'Method not allowed']); exit; } if (empty($_SESSION['access_token'])) { echo json_encode(['reauth' => true]); exit; } if (($_SESSION['token_expires'] ?? 0) <= time()) { echo json_encode(['reauth' => true]); exit; } $reportCode = preg_replace('/[^a-zA-Z0-9]/', '', $_POST['report_code'] ?? ''); $fightId = (int)($_POST['fight_id'] ?? 0); $startTime = (float)($_POST['start_time'] ?? 0); $endTime = (float)($_POST['end_time'] ?? 0); $language = strtolower(trim($_POST['language'] ?? 'en')); $language = in_array($language, ['en', 'de', 'fr', 'jp'], true) ? $language : 'en'; $translate = $language === 'en' ? 'false' : 'true'; if (!$reportCode || !$fightId || !$endTime) { http_response_code(400); echo json_encode(['error' => 'Missing params']); exit; } $token = $_SESSION['access_token']; function localized_graphql_uri(string $language): string { $host = [ 'de' => 'de.fflogs.com', 'fr' => 'fr.fflogs.com', 'jp' => 'ja.fflogs.com', ][$language] ?? 'www.fflogs.com'; return preg_replace('#https://[^/]+#', 'https://' . $host, GRAPHQL_URI); } function ab_gql(string $query): array { global $token, $language; $acceptLanguage = $language === 'jp' ? 'ja' : $language; $ch = curl_init(localized_graphql_uri($language)); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode(['query' => $query]), CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ['Content-Type: application/json', 'Authorization: Bearer ' . $token, 'Accept-Language: ' . $acceptLanguage], CURLOPT_SSL_VERIFYPEER => !DEV_MODE, ]); $body = curl_exec($ch); curl_close($ch); return json_decode($body, true) ?? []; } // Fetch ability names from masterData $mdResult = ab_gql(<< 'tank', 'healers' => 'healer', 'dps' => 'dps']; foreach ($roleMap as $group => $role) { foreach ($pdGroups[$group] ?? [] as $p) { $players[] = ['name' => $p['name'], 'role' => $role]; } } usort($players, fn($a, $b) => strcmp($a['name'], $b['name'])); // Fetch DamageTaken events from NPC sources only (paginated) $filterEsc = 'source.type = \\"NPC\\"'; $seenIds = []; $nextPage = $startTime; for ($page = 0; $page < 10; $page++) { $evResult = ab_gql(<< 7) $seenIds[$abId] = true; } $nextPage = $ev['nextPageTimestamp'] ?? null; if ($nextPage === null || $nextPage >= $endTime) break; } // Build sorted ability list $abilities = []; foreach (array_keys($seenIds) as $id) { $abilities[] = [ 'id' => $id, 'name' => $abilityNames[$id] ?? ('Ability #' . $id), ]; } usort($abilities, fn($a, $b) => strcmp($a['name'], $b['name'])); echo json_encode(['abilities' => $abilities, 'players' => $players]);