ff14-mitigator/api/cache.php
xziino a9b3cc8666 Planer: Clarity of Corundum + separate Tankbuster-Fixes
- Clarity of Corundum (GNB Proc, 15% DR, statusId 1002684) neu in
  MITIGATION_ABILITIES, ABILITY_DR, JOB_ABILITIES, TIMELINE_PERSONAL_ABILITIES
- statusId fuer Heart of Corundum (1002683) und Great Nebula (1003838)
  nachgetragen (stabilere Erkennung via buffs-Feld)
- Icons heruntergeladen: heart-of-corundum.png, heart-of-stone.png,
  clarity-of-corundum.png (teilt HoC-Action-Icon vorlaeufig)
- Cache-Version v3 -> v4 (erzwingt Neu-Fetch nach Erkennungs-Aenderungen)

Separate Tankbuster:
- tankMaxHpFromEvent(): maxHP direkt aus dem aoe_event des getroffenen
  Tanks statt Roster-Durchschnitt (ein Tank getroffen = sein MaxHP)
- renderMechanicListHtml: m.tankMaxHp hat Vorrang vor avgTankMaxHp(plan)
- plannedAssignmentsForMechanic: persoenliche Mitigation erscheint nur
  auf der direkt zugewiesenen Mechanik (DRK-CDs nicht mehr auf GNB-TB)
- DR-Label: 'mitigiert' -> 'nach DR' (verbleibender Schaden, nicht
  reduzierter Betrag)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 15:04:21 +02:00

53 lines
2.0 KiB
PHP

<?php
declare(strict_types=1);
const CACHED_LOG_DIR = __DIR__ . '/../cached_logs';
const CACHED_LOG_VERSION = 'v4';
function cache_language(string $language): string {
$language = strtolower(trim($language));
return in_array($language, ['en', 'de', 'fr', 'jp'], true) ? $language : 'en';
}
function cache_report_code(string $reportCode): string {
return preg_replace('/[^a-zA-Z0-9]/', '', $reportCode);
}
function cache_key_part(string|int|float|null $value): string {
$value = (string)($value ?? '');
$value = preg_replace('/[^a-zA-Z0-9._-]/', '_', $value);
return trim($value, '_') ?: 'all';
}
function cached_log_path(string $kind, string $reportCode, string $language, array $parts = []): string {
$reportCode = cache_report_code($reportCode);
$language = cache_language($language);
$kind = cache_key_part($kind);
$safeParts = array_map('cache_key_part', $parts);
$suffix = $safeParts ? '_' . implode('_', $safeParts) : '';
return CACHED_LOG_DIR . '/' . CACHED_LOG_VERSION . '/' . $reportCode . '/' . $language . '/' . $kind . $suffix . '.json';
}
function read_cached_log(string $kind, string $reportCode, string $language, array $parts = []): ?string {
$path = cached_log_path($kind, $reportCode, $language, $parts);
if (!is_file($path)) return null;
$body = file_get_contents($path);
if ($body === false || trim($body) === '') return null;
return $body;
}
function write_cached_log(string $kind, string $reportCode, string $language, array $parts, string $body): void {
$decoded = json_decode($body, true);
if (!is_array($decoded) || isset($decoded['error'], $decoded['errors'], $decoded['reauth'])) return;
$path = cached_log_path($kind, $reportCode, $language, $parts);
$dir = dirname($path);
if (!is_dir($dir) && !mkdir($dir, 0775, true) && !is_dir($dir)) return;
$tmp = $path . '.' . bin2hex(random_bytes(4)) . '.tmp';
if (file_put_contents($tmp, $body, LOCK_EX) === false) return;
rename($tmp, $path);
}