forked from xziino/ff14-mitigator
if tank is selected track also tankbuster
on login keep url params
This commit is contained in:
parent
139ea8d3ac
commit
19bd79c056
@ -333,6 +333,7 @@ if (!empty($shieldStatusIds)) {
|
||||
// Group events by abilityId, then cluster by time proximity (≤ 1000ms from
|
||||
// the first event in the cluster) to avoid fixed-window boundary splits.
|
||||
const CLUSTER_WINDOW_MS = 1000;
|
||||
const HEAVY_TANKBUSTER_MIN_HP_RATIO = 0.33;
|
||||
|
||||
$byAbility = []; // abilityId → [{ts, tgtId, amount, hp, maxHp, buffs, name}]
|
||||
foreach ($allEvents as $ev) {
|
||||
@ -404,7 +405,26 @@ foreach ($byAbility as $abId => $events) {
|
||||
|
||||
$aoeEvents = [];
|
||||
foreach ($clusters as $group) {
|
||||
if (count($group['targets']) < 3) continue;
|
||||
$targetCount = count($group['targets']);
|
||||
$isHeavyTankbuster = false;
|
||||
if ($targetCount < 3) {
|
||||
foreach ($group['targets'] as $tgtId => $tgt) {
|
||||
$p = $players[$tgtId] ?? null;
|
||||
if (($p['role'] ?? null) !== 'tank') continue;
|
||||
|
||||
$tankMaxHp = (int)($tgt['maxHp'] ?? 0);
|
||||
$rawDamage = max(
|
||||
(int)($tgt['unmitigatedAmount'] ?? 0),
|
||||
(int)($tgt['amount'] ?? 0) + (int)($tgt['absorbed'] ?? 0) + (int)($tgt['mitigated'] ?? 0)
|
||||
);
|
||||
if ($tankMaxHp > 0 && $rawDamage >= $tankMaxHp * HEAVY_TANKBUSTER_MIN_HP_RATIO) {
|
||||
$isHeavyTankbuster = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($targetCount < 3 && !$isHeavyTankbuster) continue;
|
||||
|
||||
$targets = [];
|
||||
foreach ($group['targets'] as $tgtId => $tgt) {
|
||||
@ -448,6 +468,7 @@ foreach ($clusters as $group) {
|
||||
'abilityName' => $group['abilityName'],
|
||||
'targets' => $targets,
|
||||
'totalDamage' => array_sum(array_column($targets, 'amount')),
|
||||
'isHeavyTankbuster' => $isHeavyTankbuster,
|
||||
];
|
||||
}
|
||||
usort($aoeEvents, fn($a, $b) => $a['timestamp'] <=> $b['timestamp']);
|
||||
|
||||
@ -2,10 +2,17 @@
|
||||
require_once __DIR__ . '/../config.php';
|
||||
session_start_safe();
|
||||
|
||||
function redirect_with_error(string $returnPath, string $error): void {
|
||||
$separator = str_contains($returnPath, '?') ? '&' : '?';
|
||||
header('Location: ' . $returnPath . $separator . 'error=' . rawurlencode($error));
|
||||
exit;
|
||||
}
|
||||
|
||||
$returnPath = safe_return_path($_SESSION['oauth_return'] ?? null);
|
||||
|
||||
// user denied access
|
||||
if (isset($_GET['error'])) {
|
||||
header('Location: ../index.php?error=' . urlencode($_GET['error']));
|
||||
exit;
|
||||
redirect_with_error($returnPath, $_GET['error']);
|
||||
}
|
||||
|
||||
// CSRF check
|
||||
@ -21,12 +28,11 @@ if (
|
||||
}
|
||||
|
||||
if (empty($_GET['code'])) {
|
||||
header('Location: ../index.php?error=missing_code');
|
||||
exit;
|
||||
redirect_with_error($returnPath, 'missing_code');
|
||||
}
|
||||
|
||||
$verifier = $_SESSION['pkce_verifier'];
|
||||
unset($_SESSION['pkce_verifier'], $_SESSION['oauth_state']);
|
||||
unset($_SESSION['pkce_verifier'], $_SESSION['oauth_state'], $_SESSION['oauth_return']);
|
||||
|
||||
$post = http_build_query([
|
||||
'grant_type' => 'authorization_code',
|
||||
@ -56,12 +62,11 @@ if ($curlError || $status !== 200 || empty($data['access_token'])) {
|
||||
'http_status' => $status,
|
||||
'response_body' => $body,
|
||||
];
|
||||
header('Location: ../index.php?error=token_failed');
|
||||
exit;
|
||||
redirect_with_error($returnPath, 'token_failed');
|
||||
}
|
||||
|
||||
$_SESSION['access_token'] = $data['access_token'];
|
||||
$_SESSION['token_expires'] = time() + ($data['expires_in'] ?? 3600);
|
||||
|
||||
header('Location: ../index.php');
|
||||
header('Location: ' . $returnPath);
|
||||
exit;
|
||||
|
||||
@ -8,6 +8,7 @@ $state = bin2hex(random_bytes(16));
|
||||
|
||||
$_SESSION['pkce_verifier'] = $verifier;
|
||||
$_SESSION['oauth_state'] = $state;
|
||||
$_SESSION['oauth_return'] = safe_return_path($_GET['return'] ?? ($_SERVER['HTTP_REFERER'] ?? null));
|
||||
|
||||
$params = http_build_query([
|
||||
'response_type' => 'code',
|
||||
|
||||
@ -341,7 +341,7 @@
|
||||
body: new URLSearchParams({ report_code: code, language: window.App.language }),
|
||||
});
|
||||
const json = await res.json();
|
||||
if (json.reauth) { window.location.href = 'auth/start.php'; return; }
|
||||
if (json.reauth) { window.location.href = window.App?.authStartUrl?.() ?? 'auth/start.php'; return; }
|
||||
|
||||
const fights = json?.data?.reportData?.report?.fights ?? [];
|
||||
extFights = fights;
|
||||
@ -459,6 +459,7 @@
|
||||
!hiddenPlayers.has(t.id) &&
|
||||
(!playerFilter || t.name.toLowerCase().includes(playerFilter))
|
||||
);
|
||||
if (ev.isHeavyTankbuster && !visibleTargets.some(t => t.role === 'tank')) return '';
|
||||
if (!visibleTargets.length) return '';
|
||||
|
||||
// Collect boss debuffs (Reprisal/Feint/Addle) once at event level
|
||||
@ -675,7 +676,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
if (json.reauth) { window.location.href = 'auth/start.php'; return; }
|
||||
if (json.reauth) { window.location.href = window.App?.authStartUrl?.() ?? 'auth/start.php'; return; }
|
||||
if (json.error) { setEmpty('Fehler: ' + json.error); return; }
|
||||
|
||||
lastFightId = fightId;
|
||||
|
||||
@ -60,6 +60,11 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
}
|
||||
window.App.setUrlState = setUrlState;
|
||||
|
||||
function authStartUrl() {
|
||||
return 'auth/start.php?return=' + encodeURIComponent(window.location.pathname + window.location.search);
|
||||
}
|
||||
window.App.authStartUrl = authStartUrl;
|
||||
|
||||
function fflogsReportUrl(reportCode, fightId = 0) {
|
||||
const code = String(reportCode || '').trim();
|
||||
if (!code) return '#';
|
||||
@ -237,7 +242,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
body: new URLSearchParams(params),
|
||||
});
|
||||
const json = await res.json();
|
||||
if (json.reauth) { window.location.href = 'auth/start.php'; return; }
|
||||
if (json.reauth) { window.location.href = authStartUrl(); return; }
|
||||
output.textContent = JSON.stringify(json, null, 2);
|
||||
} catch (err) {
|
||||
output.textContent = '// Fehler: ' + err.message;
|
||||
@ -287,7 +292,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
|
||||
if (json.reauth) {
|
||||
output.textContent = '// session expired — redirecting...';
|
||||
setTimeout(() => { window.location.href = 'auth/start.php'; }, 1500);
|
||||
setTimeout(() => { window.location.href = authStartUrl(); }, 1500);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
|
||||
<a href="auth/start.php" class="btn btn-gold btn-login">
|
||||
<a href="<?= htmlspecialchars(auth_start_href(), ENT_QUOTES) ?>" class="btn btn-gold btn-login">
|
||||
<?= $tokenExpired ? 'Reconnect to FFLogs' : 'Connect to FFLogs' ?>
|
||||
</a>
|
||||
|
||||
|
||||
@ -23,7 +23,7 @@
|
||||
</select>
|
||||
</div>
|
||||
<button class="btn btn-gold" type="submit" style="align-self:flex-end">Fetch</button>
|
||||
<a class="btn" href="auth/start.php" style="align-self:flex-end;text-decoration:none">Reconnect</a>
|
||||
<a class="btn" href="<?= htmlspecialchars(auth_start_href(), ENT_QUOTES) ?>" style="align-self:flex-end;text-decoration:none">Reconnect</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user