Compare commits
No commits in common. "206e09a57aed7e3bd5b84cb5d19304f5eacf4ce6" and "eecab6d76a628ff95f11c70e5a159df3c0969e89" have entirely different histories.
206e09a57a
...
eecab6d76a
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,5 +1,5 @@
|
|||||||
.claude/
|
.claude/
|
||||||
debug/
|
debug/
|
||||||
cached_logs/
|
cached_logs/
|
||||||
.env
|
|
||||||
fflogs-schema.json
|
fflogs-schema.json
|
||||||
|
config.php
|
||||||
|
|||||||
@ -393,9 +393,6 @@ foreach ($allEvents as $ev) {
|
|||||||
$tgtId = (int)($ev['targetID'] ?? 0);
|
$tgtId = (int)($ev['targetID'] ?? 0);
|
||||||
if (!$abId || !$tgtId || $abId <= 7) continue;
|
if (!$abId || !$tgtId || $abId <= 7) continue;
|
||||||
|
|
||||||
$srcId = (int)($ev['sourceID'] ?? 0);
|
|
||||||
if ($srcId > 0 && isset($players[$srcId])) continue;
|
|
||||||
|
|
||||||
$byAbility[$abId][] = [
|
$byAbility[$abId][] = [
|
||||||
'ts' => (float)($ev['timestamp'] ?? 0),
|
'ts' => (float)($ev['timestamp'] ?? 0),
|
||||||
'tgtId' => $tgtId,
|
'tgtId' => $tgtId,
|
||||||
|
|||||||
@ -2,7 +2,6 @@
|
|||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
const CACHED_LOG_DIR = __DIR__ . '/../cached_logs';
|
const CACHED_LOG_DIR = __DIR__ . '/../cached_logs';
|
||||||
const CACHED_LOG_VERSION = 'v2';
|
|
||||||
|
|
||||||
function cache_language(string $language): string {
|
function cache_language(string $language): string {
|
||||||
$language = strtolower(trim($language));
|
$language = strtolower(trim($language));
|
||||||
@ -26,7 +25,7 @@ function cached_log_path(string $kind, string $reportCode, string $language, arr
|
|||||||
$safeParts = array_map('cache_key_part', $parts);
|
$safeParts = array_map('cache_key_part', $parts);
|
||||||
$suffix = $safeParts ? '_' . implode('_', $safeParts) : '';
|
$suffix = $safeParts ? '_' . implode('_', $safeParts) : '';
|
||||||
|
|
||||||
return CACHED_LOG_DIR . '/' . CACHED_LOG_VERSION . '/' . $reportCode . '/' . $language . '/' . $kind . $suffix . '.json';
|
return CACHED_LOG_DIR . '/' . $reportCode . '/' . $language . '/' . $kind . $suffix . '.json';
|
||||||
}
|
}
|
||||||
|
|
||||||
function read_cached_log(string $kind, string $reportCode, string $language, array $parts = []): ?string {
|
function read_cached_log(string $kind, string $reportCode, string $language, array $parts = []): ?string {
|
||||||
|
|||||||
87
config.php
87
config.php
@ -1,51 +1,11 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
function load_env_file(string $path): void {
|
define('DEV_MODE', true); // set to false in production
|
||||||
if (!is_file($path)) return;
|
define('CLIENT_ID', 'a1d27cba-b7f8-48dd-aefd-4697b457cc67');
|
||||||
|
define('REDIRECT_URI', 'http://localhost:8080/auth/callback.php');
|
||||||
foreach (file($path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) ?: [] as $line) {
|
define('AUTHORIZE_URI','https://www.fflogs.com/oauth/authorize');
|
||||||
$line = trim($line);
|
define('TOKEN_URI', 'https://www.fflogs.com/oauth/token');
|
||||||
if ($line === '' || str_starts_with($line, '#')) continue;
|
define('GRAPHQL_URI', 'https://www.fflogs.com/api/v2/user');
|
||||||
|
|
||||||
[$key, $value] = array_pad(explode('=', $line, 2), 2, '');
|
|
||||||
$key = trim($key);
|
|
||||||
if ($key === '') continue;
|
|
||||||
|
|
||||||
$value = trim($value);
|
|
||||||
if (
|
|
||||||
strlen($value) >= 2
|
|
||||||
&& (($value[0] === '"' && $value[-1] === '"') || ($value[0] === "'" && $value[-1] === "'"))
|
|
||||||
) {
|
|
||||||
$value = substr($value, 1, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
$_ENV[$key] = $value;
|
|
||||||
putenv($key . '=' . $value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function env_value(string $key, ?string $default = null): string {
|
|
||||||
$value = $_ENV[$key] ?? getenv($key);
|
|
||||||
if ($value === false || $value === null || $value === '') {
|
|
||||||
if ($default !== null) return $default;
|
|
||||||
throw new RuntimeException('Missing required environment value: ' . $key);
|
|
||||||
}
|
|
||||||
return (string)$value;
|
|
||||||
}
|
|
||||||
|
|
||||||
function env_bool(string $key, bool $default = false): bool {
|
|
||||||
$value = strtolower(env_value($key, $default ? 'true' : 'false'));
|
|
||||||
return in_array($value, ['1', 'true', 'yes', 'on'], true);
|
|
||||||
}
|
|
||||||
|
|
||||||
load_env_file(__DIR__ . '/.env');
|
|
||||||
|
|
||||||
define('DEV_MODE', env_bool('DEV_MODE'));
|
|
||||||
define('CLIENT_ID', env_value('CLIENT_ID'));
|
|
||||||
define('REDIRECT_URI', env_value('REDIRECT_URI'));
|
|
||||||
define('AUTHORIZE_URI', env_value('AUTHORIZE_URI'));
|
|
||||||
define('TOKEN_URI', env_value('TOKEN_URI'));
|
|
||||||
define('GRAPHQL_URI', env_value('GRAPHQL_URI'));
|
|
||||||
|
|
||||||
function session_start_safe(): void {
|
function session_start_safe(): void {
|
||||||
if (session_status() === PHP_SESSION_NONE) {
|
if (session_status() === PHP_SESSION_NONE) {
|
||||||
@ -59,38 +19,3 @@ function session_start_safe(): void {
|
|||||||
session_start();
|
session_start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function default_return_path(): string {
|
|
||||||
$script = str_replace('\\', '/', $_SERVER['SCRIPT_NAME'] ?? '/index.php');
|
|
||||||
$base = rtrim(dirname(dirname($script)), '/');
|
|
||||||
return ($base === '' ? '' : $base) . '/index.php';
|
|
||||||
}
|
|
||||||
|
|
||||||
function safe_return_path(?string $value): string {
|
|
||||||
$value = trim((string)$value);
|
|
||||||
if ($value === '') return default_return_path();
|
|
||||||
|
|
||||||
$parts = parse_url($value);
|
|
||||||
if ($parts === false) return default_return_path();
|
|
||||||
if (isset($parts['host'])) {
|
|
||||||
$currentHost = strtolower(explode(':', $_SERVER['HTTP_HOST'] ?? '')[0]);
|
|
||||||
if (strtolower($parts['host']) !== $currentHost) return default_return_path();
|
|
||||||
} elseif (str_starts_with($value, '//')) {
|
|
||||||
return default_return_path();
|
|
||||||
}
|
|
||||||
|
|
||||||
$path = $parts['path'] ?? '';
|
|
||||||
if ($path === '') $path = default_return_path();
|
|
||||||
if ($path[0] !== '/') $path = '/' . ltrim($path, '/');
|
|
||||||
|
|
||||||
$query = isset($parts['query']) ? '?' . $parts['query'] : '';
|
|
||||||
return $path . $query;
|
|
||||||
}
|
|
||||||
|
|
||||||
function current_return_path(): string {
|
|
||||||
return safe_return_path($_SERVER['REQUEST_URI'] ?? null);
|
|
||||||
}
|
|
||||||
|
|
||||||
function auth_start_href(?string $returnPath = null): string {
|
|
||||||
return 'auth/start.php?return=' . rawurlencode($returnPath ?? current_return_path());
|
|
||||||
}
|
|
||||||
|
|||||||
@ -797,11 +797,6 @@
|
|||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.timeline-hit-line--tankbuster {
|
|
||||||
width: 2px;
|
|
||||||
background: rgba(177,112,255,.62);
|
|
||||||
}
|
|
||||||
|
|
||||||
.timeline-player-row .timeline-track {
|
.timeline-player-row .timeline-track {
|
||||||
background-color: rgba(255,255,255,0.015);
|
background-color: rgba(255,255,255,0.015);
|
||||||
}
|
}
|
||||||
@ -879,17 +874,6 @@
|
|||||||
background: rgba(224,92,92,.22);
|
background: rgba(224,92,92,.22);
|
||||||
}
|
}
|
||||||
|
|
||||||
.timeline-boss-action--tankbuster {
|
|
||||||
border-color: rgba(177,112,255,.55);
|
|
||||||
background: rgba(177,112,255,.18);
|
|
||||||
color: #dbc7ff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.timeline-boss-action--tankbuster:hover {
|
|
||||||
border-color: rgba(177,112,255,.85);
|
|
||||||
background: rgba(177,112,255,.28);
|
|
||||||
}
|
|
||||||
|
|
||||||
.timeline-mitigation {
|
.timeline-mitigation {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 6px;
|
top: 6px;
|
||||||
|
|||||||
@ -2,6 +2,11 @@
|
|||||||
require_once __DIR__ . '/config.php';
|
require_once __DIR__ . '/config.php';
|
||||||
session_start_safe();
|
session_start_safe();
|
||||||
|
|
||||||
|
function auth_start_href(): string {
|
||||||
|
$return = $_SERVER['REQUEST_URI'] ?? '/';
|
||||||
|
return 'auth/start.php?return=' . urlencode($return);
|
||||||
|
}
|
||||||
|
|
||||||
$authenticated = !empty($_SESSION['access_token'])
|
$authenticated = !empty($_SESSION['access_token'])
|
||||||
&& ($_SESSION['token_expires'] ?? 0) > time();
|
&& ($_SESSION['token_expires'] ?? 0) > time();
|
||||||
|
|
||||||
|
|||||||
@ -920,14 +920,14 @@ function renderTimelineHtml(plan) {
|
|||||||
const bossActions = layoutBossActions(mechanics, duration);
|
const bossActions = layoutBossActions(mechanics, duration);
|
||||||
const laneCount = Math.max(1, ...bossActions.map(item => item.lane + 1));
|
const laneCount = Math.max(1, ...bossActions.map(item => item.lane + 1));
|
||||||
const hitLines = mechanics.map(m => `
|
const hitLines = mechanics.map(m => `
|
||||||
<span class="timeline-hit-line${m.isHeavyTankbuster ? ' timeline-hit-line--tankbuster' : ''}" style="left:${(m.timestamp / duration) * 100}%"></span>
|
<span class="timeline-hit-line" style="left:${(m.timestamp / duration) * 100}%"></span>
|
||||||
`).join('');
|
`).join('');
|
||||||
|
|
||||||
const bossItems = bossActions.map(({ mechanic: m, left, lane }) => `
|
const bossItems = bossActions.map(({ mechanic: m, left, lane }) => `
|
||||||
<button class="timeline-boss-action${m.isHeavyTankbuster ? ' timeline-boss-action--tankbuster' : ''}"
|
<button class="timeline-boss-action"
|
||||||
style="left:${left}%;top:${8 + lane * 30}px"
|
style="left:${left}%;top:${8 + lane * 30}px"
|
||||||
data-mechanic-id="${escHtml(m.id)}"
|
data-mechanic-id="${escHtml(m.id)}"
|
||||||
title="${escHtml(fmtTimestamp(m.timestamp))} · ${escHtml(m.name)} · ${m.isHeavyTankbuster ? 'Tankbuster' : 'AoE'}">
|
title="${escHtml(fmtTimestamp(m.timestamp))} · ${escHtml(m.name)}">
|
||||||
${escHtml(m.name)}
|
${escHtml(m.name)}
|
||||||
</button>
|
</button>
|
||||||
`).join('');
|
`).join('');
|
||||||
@ -1869,7 +1869,6 @@ function aoeEventsToMechanics(aoeEvents, fightStart, phases, players, withMitiga
|
|||||||
timestamp: relTs,
|
timestamp: relTs,
|
||||||
phase: phase?.name ?? '',
|
phase: phase?.name ?? '',
|
||||||
unmitigatedDamage: avgUnmit,
|
unmitigatedDamage: avgUnmit,
|
||||||
isHeavyTankbuster: !!ev.isHeavyTankbuster,
|
|
||||||
notes: '',
|
notes: '',
|
||||||
assignments,
|
assignments,
|
||||||
};
|
};
|
||||||
@ -1992,7 +1991,6 @@ async function refreshPlanLanguage(planId) {
|
|||||||
...mechanic,
|
...mechanic,
|
||||||
name: match.abilityName ?? mechanic.name,
|
name: match.abilityName ?? mechanic.name,
|
||||||
abilityId: match.abilityId ?? mechanic.abilityId,
|
abilityId: match.abilityId ?? mechanic.abilityId,
|
||||||
isHeavyTankbuster: !!match.isHeavyTankbuster,
|
|
||||||
assignments,
|
assignments,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user