diff --git a/BOT/locales/cs.json b/BOT/locales/cs.json index 4b342cb..9531fbc 100644 --- a/BOT/locales/cs.json +++ b/BOT/locales/cs.json @@ -866,15 +866,15 @@ "title_wildcard": "Týdenní zpráva BR — {br} BR", "title_squadron": "Týdenní zpráva BR — [{tag}] {long} • {br} BR", "window_label": "Období: {start} → {end}", - "wildcard_desc_first": "Top {count} letek podle ELO • Pozice {low}–{high}", - "wildcard_desc_second": "Top {count} letek podle ELO • Pozice {low}–{high}", + "wildcard_desc_first": "Top {count} letek podle Score • Pozice {low}–{high}", + "wildcard_desc_second": "Top {count} letek podle Score • Pozice {low}–{high}", "squadron_stats_line": "- {games} bitev • K/D {kdr} • Vítězství {wr}%", "top_players_inline_header": "🥇 Nejlepší hráči:", "player_line_short": " {rank}. {nick} ⭐ {score} ({games}b)", - "top_players_header": "**Top {count} hráčů podle ELO:**", + "top_players_header": "**Top {count} hráčů podle Score:**", "player_line_full": "{rank}. **{nick}** ⭐ {score} • {games} bitev • K/D {kdr}", - "squadron_header_line": "ELO letky: {score} • {games} bitev • Vítězství {wr}% • K/D {kdr}", - "squadron_header_no_aggregate": "ELO letky: tento týden nedostatek týmové aktivity.", + "squadron_header_line": "Score letky: {score} • {games} bitev • Vítězství {wr}% • K/D {kdr}", + "squadron_header_no_aggregate": "Score letky: tento týden nedostatek týmové aktivity.", "no_data": "Žádné zápasy pro [{tag}] v této rotaci BR." } } diff --git a/BOT/locales/de.json b/BOT/locales/de.json index fdf57f2..ea84ed0 100644 --- a/BOT/locales/de.json +++ b/BOT/locales/de.json @@ -866,15 +866,15 @@ "title_wildcard": "Wöchentlicher BR-Bericht — {br} BR", "title_squadron": "Wöchentlicher BR-Bericht — [{tag}] {long} • {br} BR", "window_label": "Zeitraum: {start} → {end}", - "wildcard_desc_first": "Top {count} Geschwader nach ELO • Plätze {low}–{high}", - "wildcard_desc_second": "Top {count} Geschwader nach ELO • Plätze {low}–{high}", + "wildcard_desc_first": "Top {count} Geschwader nach Score • Plätze {low}–{high}", + "wildcard_desc_second": "Top {count} Geschwader nach Score • Plätze {low}–{high}", "squadron_stats_line": "- {games} Spiele • K/D {kdr} • Siegrate {wr}%", "top_players_inline_header": "🥇 Top-Spieler:", "player_line_short": " {rank}. {nick} ⭐ {score} ({games}S)", - "top_players_header": "**Top {count} Spieler nach ELO:**", + "top_players_header": "**Top {count} Spieler nach Score:**", "player_line_full": "{rank}. **{nick}** ⭐ {score} • {games} Spiele • K/D {kdr}", - "squadron_header_line": "Geschwader-ELO: {score} • {games} Spiele • Siegrate {wr}% • K/D {kdr}", - "squadron_header_no_aggregate": "Geschwader-ELO: nicht genügend Teamspiele in dieser Woche.", + "squadron_header_line": "Geschwader-Score: {score} • {games} Spiele • Siegrate {wr}% • K/D {kdr}", + "squadron_header_no_aggregate": "Geschwader-Score: nicht genügend Teamspiele in dieser Woche.", "no_data": "Keine Spiele für [{tag}] in dieser BR-Rotation aufgezeichnet." } } diff --git a/BOT/locales/en.json b/BOT/locales/en.json index f419e0c..d6d6c14 100644 --- a/BOT/locales/en.json +++ b/BOT/locales/en.json @@ -868,15 +868,15 @@ "title_wildcard": "Weekly BR Report — {br} BR", "title_squadron": "Weekly BR Report — [{tag}] {long} • {br} BR", "window_label": "Window: {start} → {end}", - "wildcard_desc_first": "Top {count} squadrons by ELO • Ranks {low}–{high}", - "wildcard_desc_second": "Top {count} squadrons by ELO • Ranks {low}–{high}", + "wildcard_desc_first": "Top {count} squadrons by Score • Ranks {low}–{high}", + "wildcard_desc_second": "Top {count} squadrons by Score • Ranks {low}–{high}", "squadron_stats_line": "- {games} games • K/D {kdr} • WR {wr}%", "top_players_inline_header": "🥇 Top players:", "player_line_short": " {rank}. {nick} ⭐ {score} ({games}g)", - "top_players_header": "**Top {count} players by ELO:**", + "top_players_header": "**Top {count} players by Score:**", "player_line_full": "{rank}. **{nick}** ⭐ {score} • {games} games • K/D {kdr}", - "squadron_header_line": "Squadron ELO: {score} • {games} games • WR {wr}% • K/D {kdr}", - "squadron_header_no_aggregate": "Squadron ELO: not enough team activity to score this week.", + "squadron_header_line": "Squadron Score: {score} • {games} games • WR {wr}% • K/D {kdr}", + "squadron_header_no_aggregate": "Squadron Score: not enough team activity to score this week.", "no_data": "No matches recorded for [{tag}] this BR rotation." } } diff --git a/BOT/locales/es.json b/BOT/locales/es.json index 100fe53..dabb45c 100644 --- a/BOT/locales/es.json +++ b/BOT/locales/es.json @@ -866,15 +866,15 @@ "title_wildcard": "Informe BR Semanal — {br} BR", "title_squadron": "Informe BR Semanal — [{tag}] {long} • {br} BR", "window_label": "Periodo: {start} → {end}", - "wildcard_desc_first": "Top {count} escuadrones por ELO • Puestos {low}–{high}", - "wildcard_desc_second": "Top {count} escuadrones por ELO • Puestos {low}–{high}", + "wildcard_desc_first": "Top {count} escuadrones por Score • Puestos {low}–{high}", + "wildcard_desc_second": "Top {count} escuadrones por Score • Puestos {low}–{high}", "squadron_stats_line": "- {games} partidas • K/D {kdr} • Victorias {wr}%", "top_players_inline_header": "🥇 Mejores jugadores:", "player_line_short": " {rank}. {nick} ⭐ {score} ({games}p)", - "top_players_header": "**Top {count} jugadores por ELO:**", + "top_players_header": "**Top {count} jugadores por Score:**", "player_line_full": "{rank}. **{nick}** ⭐ {score} • {games} partidas • K/D {kdr}", - "squadron_header_line": "ELO de escuadrón: {score} • {games} partidas • Victorias {wr}% • K/D {kdr}", - "squadron_header_no_aggregate": "ELO de escuadrón: poca actividad de equipo esta semana.", + "squadron_header_line": "Score de escuadrón: {score} • {games} partidas • Victorias {wr}% • K/D {kdr}", + "squadron_header_no_aggregate": "Score de escuadrón: poca actividad de equipo esta semana.", "no_data": "No hay partidas registradas de [{tag}] en esta rotación de BR." } } diff --git a/BOT/locales/fr.json b/BOT/locales/fr.json index 923fda4..5454b93 100644 --- a/BOT/locales/fr.json +++ b/BOT/locales/fr.json @@ -866,15 +866,15 @@ "title_wildcard": "Rapport BR hebdomadaire — {br} BR", "title_squadron": "Rapport BR hebdomadaire — [{tag}] {long} • {br} BR", "window_label": "Période : {start} → {end}", - "wildcard_desc_first": "Top {count} escadrons par ELO • Rangs {low}–{high}", - "wildcard_desc_second": "Top {count} escadrons par ELO • Rangs {low}–{high}", + "wildcard_desc_first": "Top {count} escadrons par Score • Rangs {low}–{high}", + "wildcard_desc_second": "Top {count} escadrons par Score • Rangs {low}–{high}", "squadron_stats_line": "- {games} parties • K/D {kdr} • Victoires {wr}%", "top_players_inline_header": "🥇 Meilleurs joueurs :", "player_line_short": " {rank}. {nick} ⭐ {score} ({games}p)", - "top_players_header": "**Top {count} joueurs par ELO :**", + "top_players_header": "**Top {count} joueurs par Score :**", "player_line_full": "{rank}. **{nick}** ⭐ {score} • {games} parties • K/D {kdr}", - "squadron_header_line": "ELO escadron : {score} • {games} parties • Victoires {wr}% • K/D {kdr}", - "squadron_header_no_aggregate": "ELO escadron : pas assez d'activité d'équipe cette semaine.", + "squadron_header_line": "Score escadron : {score} • {games} parties • Victoires {wr}% • K/D {kdr}", + "squadron_header_no_aggregate": "Score escadron : pas assez d'activité d'équipe cette semaine.", "no_data": "Aucun match enregistré pour [{tag}] cette rotation BR." } } diff --git a/BOT/locales/it.json b/BOT/locales/it.json index 27b5b3f..bd876c3 100644 --- a/BOT/locales/it.json +++ b/BOT/locales/it.json @@ -866,15 +866,15 @@ "title_wildcard": "Report BR Settimanale — {br} BR", "title_squadron": "Report BR Settimanale — [{tag}] {long} • {br} BR", "window_label": "Periodo: {start} → {end}", - "wildcard_desc_first": "Top {count} squadroni per ELO • Posizioni {low}–{high}", - "wildcard_desc_second": "Top {count} squadroni per ELO • Posizioni {low}–{high}", + "wildcard_desc_first": "Top {count} squadroni per Score • Posizioni {low}–{high}", + "wildcard_desc_second": "Top {count} squadroni per Score • Posizioni {low}–{high}", "squadron_stats_line": "- {games} partite • K/D {kdr} • Vittorie {wr}%", "top_players_inline_header": "🥇 Migliori giocatori:", "player_line_short": " {rank}. {nick} ⭐ {score} ({games}p)", - "top_players_header": "**Top {count} giocatori per ELO:**", + "top_players_header": "**Top {count} giocatori per Score:**", "player_line_full": "{rank}. **{nick}** ⭐ {score} • {games} partite • K/D {kdr}", - "squadron_header_line": "ELO squadrone: {score} • {games} partite • Vittorie {wr}% • K/D {kdr}", - "squadron_header_no_aggregate": "ELO squadrone: troppa poca attività di squadra questa settimana.", + "squadron_header_line": "Score squadrone: {score} • {games} partite • Vittorie {wr}% • K/D {kdr}", + "squadron_header_no_aggregate": "Score squadrone: troppa poca attività di squadra questa settimana.", "no_data": "Nessuna partita registrata per [{tag}] in questa rotazione BR." } } diff --git a/BOT/locales/pl.json b/BOT/locales/pl.json index 8593c07..8bc8c2a 100644 --- a/BOT/locales/pl.json +++ b/BOT/locales/pl.json @@ -866,15 +866,15 @@ "title_wildcard": "Tygodniowy raport BR — {br} BR", "title_squadron": "Tygodniowy raport BR — [{tag}] {long} • {br} BR", "window_label": "Okres: {start} → {end}", - "wildcard_desc_first": "Top {count} szwadronów wg ELO • Miejsca {low}–{high}", - "wildcard_desc_second": "Top {count} szwadronów wg ELO • Miejsca {low}–{high}", + "wildcard_desc_first": "Top {count} szwadronów wg Score • Miejsca {low}–{high}", + "wildcard_desc_second": "Top {count} szwadronów wg Score • Miejsca {low}–{high}", "squadron_stats_line": "- {games} bitew • K/D {kdr} • Zwycięstw {wr}%", "top_players_inline_header": "🥇 Najlepsi gracze:", "player_line_short": " {rank}. {nick} ⭐ {score} ({games}b)", - "top_players_header": "**Top {count} graczy wg ELO:**", + "top_players_header": "**Top {count} graczy wg Score:**", "player_line_full": "{rank}. **{nick}** ⭐ {score} • {games} bitew • K/D {kdr}", - "squadron_header_line": "ELO szwadronu: {score} • {games} bitew • Zwycięstw {wr}% • K/D {kdr}", - "squadron_header_no_aggregate": "ELO szwadronu: zbyt mała aktywność drużyny w tym tygodniu.", + "squadron_header_line": "Score szwadronu: {score} • {games} bitew • Zwycięstw {wr}% • K/D {kdr}", + "squadron_header_no_aggregate": "Score szwadronu: zbyt mała aktywność drużyny w tym tygodniu.", "no_data": "Brak meczów dla [{tag}] w tej rotacji BR." } } diff --git a/BOT/locales/pt.json b/BOT/locales/pt.json index ed80924..01b7eb5 100644 --- a/BOT/locales/pt.json +++ b/BOT/locales/pt.json @@ -866,15 +866,15 @@ "title_wildcard": "Relatório BR Semanal — {br} BR", "title_squadron": "Relatório BR Semanal — [{tag}] {long} • {br} BR", "window_label": "Período: {start} → {end}", - "wildcard_desc_first": "Top {count} esquadrões por ELO • Posições {low}–{high}", - "wildcard_desc_second": "Top {count} esquadrões por ELO • Posições {low}–{high}", + "wildcard_desc_first": "Top {count} esquadrões por Score • Posições {low}–{high}", + "wildcard_desc_second": "Top {count} esquadrões por Score • Posições {low}–{high}", "squadron_stats_line": "- {games} partidas • K/D {kdr} • Vitórias {wr}%", "top_players_inline_header": "🥇 Melhores jogadores:", "player_line_short": " {rank}. {nick} ⭐ {score} ({games}p)", - "top_players_header": "**Top {count} jogadores por ELO:**", + "top_players_header": "**Top {count} jogadores por Score:**", "player_line_full": "{rank}. **{nick}** ⭐ {score} • {games} partidas • K/D {kdr}", - "squadron_header_line": "ELO do esquadrão: {score} • {games} partidas • Vitórias {wr}% • K/D {kdr}", - "squadron_header_no_aggregate": "ELO do esquadrão: pouca atividade da equipe esta semana.", + "squadron_header_line": "Score do esquadrão: {score} • {games} partidas • Vitórias {wr}% • K/D {kdr}", + "squadron_header_no_aggregate": "Score do esquadrão: pouca atividade da equipe esta semana.", "no_data": "Nenhuma partida registrada para [{tag}] nesta rotação de BR." } } diff --git a/BOT/locales/ru.json b/BOT/locales/ru.json index 6ab4d2e..ed61294 100644 --- a/BOT/locales/ru.json +++ b/BOT/locales/ru.json @@ -866,15 +866,15 @@ "title_wildcard": "Еженедельный отчёт BR — {br} BR", "title_squadron": "Еженедельный отчёт BR — [{tag}] {long} • {br} BR", "window_label": "Период: {start} → {end}", - "wildcard_desc_first": "Топ-{count} полков по ELO • Места {low}–{high}", - "wildcard_desc_second": "Топ-{count} полков по ELO • Места {low}–{high}", + "wildcard_desc_first": "Топ-{count} полков по Score • Места {low}–{high}", + "wildcard_desc_second": "Топ-{count} полков по Score • Места {low}–{high}", "squadron_stats_line": "- {games} боёв • K/D {kdr} • Побед {wr}%", "top_players_inline_header": "🥇 Лучшие игроки:", "player_line_short": " {rank}. {nick} ⭐ {score} ({games}б)", - "top_players_header": "**Топ-{count} игроков по ELO:**", + "top_players_header": "**Топ-{count} игроков по Score:**", "player_line_full": "{rank}. **{nick}** ⭐ {score} • {games} боёв • K/D {kdr}", - "squadron_header_line": "ELO полка: {score} • {games} боёв • Побед {wr}% • K/D {kdr}", - "squadron_header_no_aggregate": "ELO полка: недостаточно активности команды на этой неделе.", + "squadron_header_line": "Score полка: {score} • {games} боёв • Побед {wr}% • K/D {kdr}", + "squadron_header_no_aggregate": "Score полка: недостаточно активности команды на этой неделе.", "no_data": "Нет матчей для [{tag}] в этой ротации BR." } } diff --git a/BOT/locales/uk.json b/BOT/locales/uk.json index ac6c725..76a0791 100644 --- a/BOT/locales/uk.json +++ b/BOT/locales/uk.json @@ -866,15 +866,15 @@ "title_wildcard": "Тижневий звіт BR — {br} BR", "title_squadron": "Тижневий звіт BR — [{tag}] {long} • {br} BR", "window_label": "Період: {start} → {end}", - "wildcard_desc_first": "Топ-{count} полків за ELO • Місця {low}–{high}", - "wildcard_desc_second": "Топ-{count} полків за ELO • Місця {low}–{high}", + "wildcard_desc_first": "Топ-{count} полків за Score • Місця {low}–{high}", + "wildcard_desc_second": "Топ-{count} полків за Score • Місця {low}–{high}", "squadron_stats_line": "- {games} боїв • K/D {kdr} • Перемог {wr}%", "top_players_inline_header": "🥇 Найкращі гравці:", "player_line_short": " {rank}. {nick} ⭐ {score} ({games}б)", - "top_players_header": "**Топ-{count} гравців за ELO:**", + "top_players_header": "**Топ-{count} гравців за Score:**", "player_line_full": "{rank}. **{nick}** ⭐ {score} • {games} боїв • K/D {kdr}", - "squadron_header_line": "ELO полку: {score} • {games} боїв • Перемог {wr}% • K/D {kdr}", - "squadron_header_no_aggregate": "ELO полку: недостатньо активності команди цього тижня.", + "squadron_header_line": "Score полку: {score} • {games} боїв • Перемог {wr}% • K/D {kdr}", + "squadron_header_no_aggregate": "Score полку: недостатньо активності команди цього тижня.", "no_data": "Немає матчів для [{tag}] у цій ротації BR." } } diff --git a/BOT/locales/zh-CN.json b/BOT/locales/zh-CN.json index 1b46834..e2f4514 100644 --- a/BOT/locales/zh-CN.json +++ b/BOT/locales/zh-CN.json @@ -868,15 +868,15 @@ "title_wildcard": "周BR报告 — {br} BR", "title_squadron": "周BR报告 — [{tag}] {long} • {br} BR", "window_label": "时段:{start} → {end}", - "wildcard_desc_first": "按ELO排序前 {count} 中队 • 排名 {low}–{high}", - "wildcard_desc_second": "按ELO排序前 {count} 中队 • 排名 {low}–{high}", + "wildcard_desc_first": "按Score排序前 {count} 中队 • 排名 {low}–{high}", + "wildcard_desc_second": "按Score排序前 {count} 中队 • 排名 {low}–{high}", "squadron_stats_line": "- {games} 场 • K/D {kdr} • 胜率 {wr}%", "top_players_inline_header": "🥇 顶尖玩家:", "player_line_short": " {rank}. {nick} ⭐ {score} ({games}场)", - "top_players_header": "**按ELO排序前 {count} 名玩家:**", + "top_players_header": "**按Score排序前 {count} 名玩家:**", "player_line_full": "{rank}. **{nick}** ⭐ {score} • {games} 场 • K/D {kdr}", - "squadron_header_line": "中队 ELO:{score} • {games} 场 • 胜率 {wr}% • K/D {kdr}", - "squadron_header_no_aggregate": "中队 ELO:本周团队活动不足,无法评分。", + "squadron_header_line": "中队 Score:{score} • {games} 场 • 胜率 {wr}% • K/D {kdr}", + "squadron_header_no_aggregate": "中队 Score:本周团队活动不足,无法评分。", "no_data": "本次BR轮换中 [{tag}] 没有比赛记录。" } } diff --git a/BOT/task_executors.py b/BOT/task_executors.py index bc146dc..8644791 100644 --- a/BOT/task_executors.py +++ b/BOT/task_executors.py @@ -1765,7 +1765,7 @@ def _build_wildcard_embeds( end=f"", ) - # The "highest ELO person for the entire week" -- single trophy on the + # The highest-scoring person for the entire week -- single trophy on the # top-scoring player across all squadrons in the payload. top_uid: Optional[str] = None top_score = -1.0 @@ -1955,9 +1955,9 @@ async def execute_weekly_br_report_task(window: Dict[str, Any]) -> None: logging.info("(WBR) Skip — marker says window %s already fired", start_ts) return - # 1. Hit the heavy ELO pipeline ONCE per fire. The maps are reused below for + # 1. Hit the heavy scoring pipeline ONCE per fire. The maps are reused below for # both the wildcard payload and every per-squadron variant, so 30 guilds - # subscribing don't trigger 30 full ELO recomputes. + # subscribing don't trigger 30 full score recomputes. sq_map = await _wbr_squadron_scores(start_ts, end_ts) pl_map = await _wbr_player_scores(start_ts, end_ts) wildcard_payload = top_n_squadrons_with_top_k_players_from_maps( diff --git a/BOT/weekly_br_elo.py b/BOT/weekly_br_elo.py index 3b965bc..ac2a90c 100644 --- a/BOT/weekly_br_elo.py +++ b/BOT/weekly_br_elo.py @@ -1,7 +1,7 @@ """ weekly_br_elo.py -Window-scoped player & squadron ELO scoring. Python port of the +Window-scoped player & squadron scoring. Python port of the computePerformanceScore + ratingCtes pipeline from server.js, used by the Weekly BR Report executor. diff --git a/server.js b/server.js index 3cd62da..fa01d14 100644 --- a/server.js +++ b/server.js @@ -808,7 +808,7 @@ function queryPlayerRatingStats(uid, dateFilters) { GROUP BY entity_key `; return dbGet(query, [uid, ...sessionDate.params, ...playerDate.params, uid]).catch(err => { - log.error('Failed to query player ELO stats', err, { uid }); + log.error('Failed to query player performance stats', err, { uid }); return null; }); } @@ -850,7 +850,7 @@ function queryPlayerRatingStatsForUids(uids, dateFilters) { return map; }) .catch(err => { - log.error('Failed to query roster player ELO stats', err, { count: ids.length }); + log.error('Failed to query roster player performance stats', err, { count: ids.length }); return new Map(); }); } @@ -904,7 +904,7 @@ function querySquadronRatingStats(variants, dateFilters, clanId = null) { clan_id: clanId }; }).catch(err => { - log.error('Failed to query squadron ELO stats', err, { variants: names }); + log.error('Failed to query squadron performance stats', err, { variants: names }); return null; }); } @@ -932,14 +932,14 @@ function loadPerformanceBenchmarksCached(dateFilters, callback) { (() => { const benchmarkQuery = playerBenchmarkQuery(dateFilters); return dbAllHeavy(benchmarkQuery.query, benchmarkQuery.params).catch(err => { - log.error('Failed to load player ELO benchmarks', err); + log.error('Failed to load player performance benchmarks', err); return []; }); })(), (() => { const benchmarkQuery = squadronBenchmarkQuery(dateFilters); return dbAllHeavy(benchmarkQuery.query, benchmarkQuery.params).catch(err => { - log.error('Failed to load squadron ELO benchmarks', err); + log.error('Failed to load squadron performance benchmarks', err); return []; }); })() @@ -957,7 +957,7 @@ function loadPerformanceBenchmarksCached(dateFilters, callback) { return data; }).catch(err => { performanceBenchmarkInFlight.delete(key); - log.error('Failed to load ELO benchmarks', err); + log.error('Failed to load performance benchmarks', err); }); performanceBenchmarkInFlight.set(key, promise); diff --git a/web/views/docs.ejs b/web/views/docs.ejs index c494224..6e7034b 100644 --- a/web/views/docs.ejs +++ b/web/views/docs.ejs @@ -276,7 +276,7 @@

Weekly BR Report: Fires at the end of each BR rotation (~10 min after the BR window closes). - With a squadron name, posts the top 15 players by ELO for that squadron. + With a squadron name, posts the top 15 players for that squadron. With an empty squadron field (or *), posts the top 20 squadrons of the week with their top 5 players each. Free for all servers.

diff --git a/web/views/game-detail.ejs b/web/views/game-detail.ejs index 0466265..fd7e4a9 100644 --- a/web/views/game-detail.ejs +++ b/web/views/game-detail.ejs @@ -101,8 +101,9 @@ font-weight: 700; margin-bottom: 1rem; } - .sq-winner { color: #90EE90; text-shadow: 0 0 10px rgba(144, 238, 144, 0.3); font-family: 'skyquakesymbols', 'Inter', sans-serif; } - .sq-loser { color: rgba(255, 255, 255, 0.7); font-family: 'skyquakesymbols', 'Inter', sans-serif; } + .sq-winner { color: #90EE90; text-shadow: 0 0 10px rgba(144, 238, 144, 0.3); font-family: 'skyquakesymbols', 'Inter', sans-serif; text-decoration: none; } + .sq-loser { color: rgb(255, 100, 100); text-shadow: 0 0 10px rgba(255, 100, 100, 0.25); font-family: 'skyquakesymbols', 'Inter', sans-serif; text-decoration: none; } + .sq-winner:hover, .sq-loser:hover { text-decoration: underline; text-underline-offset: 0.15em; } .sq-vs { color: rgba(255, 255, 255, 0.4); font-size: 1rem; font-weight: 400; } .match-meta { display: flex; @@ -643,9 +644,9 @@
- + VS - +
@@ -832,6 +833,12 @@ return `/MAPS/${fileName}.jpg`; } + function squadronHref(team, fallbackName) { + if (team?.clan_id != null && team.clan_id !== '') return `/squadrons/${encodeURIComponent(String(team.clan_id))}`; + const name = fallbackName || team?.squadron || team?.squadron_tagged || ''; + return name ? `/squadrons/${encodeURIComponent(name)}` : '/squadrons'; + } + function renderTeamTable(players, isWinner) { const sorted = [...players].sort((a, b) => (b.score || 0) - (a.score || 0)); return sorted.map(player => { @@ -942,8 +949,12 @@ const TYPE_LABELS = { sqb: __t('live.squadronBattle'), rb: __t('live.randomBattle') }; document.getElementById('matchTypeBadge').textContent = TYPE_LABELS[match.game_type] || match.game_type || 'Match'; document.getElementById('matchMapName').textContent = cleanMapName; - document.getElementById('sqWinner').textContent = match.winning_tag || match.winning_squadron || 'Unknown'; - document.getElementById('sqLoser').textContent = match.losing_tag || match.losing_squadron || 'Unknown'; + const winnerEl = document.getElementById('sqWinner'); + const loserEl = document.getElementById('sqLoser'); + winnerEl.textContent = match.winning_tag || match.winning_squadron || 'Unknown'; + winnerEl.href = squadronHref(match.winning_team, match.winning_squadron); + loserEl.textContent = match.losing_tag || match.losing_squadron || 'Unknown'; + loserEl.href = squadronHref(match.losing_team, match.losing_squadron); // Meta const endTime = match.endtime_iso ? new Date(match.endtime_iso).toISOString().replace('T', ' ').substring(0, 16) + ' UTC' : 'Unknown'; @@ -997,8 +1008,9 @@ // Add duration/mode to meta const metaEl = document.getElementById('matchMeta'); if (replay.duration) { - const mins = Math.floor(replay.duration / 60); - const secs = replay.duration % 60; + const durationSeconds = Math.max(0, Math.round(Number(replay.duration) || 0)); + const mins = Math.floor(durationSeconds / 60); + const secs = durationSeconds % 60; metaEl.innerHTML += `${mins}m ${secs}s`; } if (replay.mode) { diff --git a/web/views/player.ejs b/web/views/player.ejs index 0268782..29a1a59 100644 --- a/web/views/player.ejs +++ b/web/views/player.ejs @@ -161,57 +161,6 @@ margin-top: 0.2rem; } - .stat-card-performance .stat-label { - margin-top: 0; - margin-bottom: 0.35rem; - } - - .stat-performance-wrap { - width: 100%; - margin-top: 0.35rem; - } - - .stat-performance-wrap .sq-performance-bar { - width: 100%; - } - - .sq-performance-bar { - width: 100%; - display: flex; - align-items: center; - gap: 0.55rem; - } - - .sq-performance-bar-track { - position: relative; - flex: 1; - height: 12px; - border-radius: 999px; - overflow: hidden; - background: rgba(255, 255, 255, 0.08); - border: 1px solid rgba(144, 238, 144, 0.16); - box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.35); - } - - .sq-performance-bar-fill { - height: 100%; - border-radius: inherit; - background: linear-gradient(90deg, rgba(245, 245, 220, 0.96), rgba(144, 238, 144, 0.96)); - box-shadow: 0 0 14px rgba(144, 238, 144, 0.25); - transition: width 0.35s ease; - } - - .sq-performance-bar-value { - min-width: 2.75rem; - text-align: right; - font-variant-numeric: tabular-nums; - font-size: 0.9rem; - font-weight: 700; - color: #F5F5DC; - letter-spacing: 0.02em; - } - - .vehicles-section { background: rgba(30, 30, 30, 0.6); border-radius: 1rem; @@ -954,18 +903,6 @@
No stats yet for this player
<% } %> - <% - const performanceLabel = 'ELO'; - const buildPerformanceBarHtml = (score) => ` -
-
-
-
- ${Number(score || 0).toFixed(2)} -
- `; - const initialPerformance = Math.max(0, Math.min(5, Number(playerData.performance || 0))); - %>
<%= totals.totalBattles %> @@ -991,11 +928,6 @@ <%= totals.totalBattles > 0 ? (totals.totalKills / totals.totalBattles).toFixed(2) : '0.00' %>
<%= t('common.kps') %>
-
-
ELO
-
<%- buildPerformanceBarHtml(initialPerformance) %>
-
-
<%= totals.totalAirKills %>
<%= t('common.airKills') %>
@@ -2215,7 +2147,6 @@ const _playerUID = document.getElementById('playerChartSection').dataset.uid; const initialVehicles = <%- JSON.stringify((playerData.vehicles || []).filter(v => v.vehicle !== 'DISCONNECTED')) %>; - const initialPerformanceRating = <%- JSON.stringify(initialPerformance) %>; const noStatsYet = <%- JSON.stringify(Boolean(playerData.no_stats_yet)) %>; let cumulativeRequestId = 0; @@ -2228,7 +2159,7 @@ // Cache hit for all-time data if (!startDate && !endDate && initialVehicles) { renderVehicleTable(initialVehicles.map(v => ({...v}))); - updateSummaryStats(initialVehicles, initialPerformanceRating); + updateSummaryStats(initialVehicles); return; } @@ -2249,7 +2180,7 @@ if (thisRequest !== cumulativeRequestId) return; if (loadingEl) loadingEl.style.display = 'none'; renderVehicleTable(data.vehicles || []); - updateSummaryStats(data.vehicles || [], data.performance); + updateSummaryStats(data.vehicles || []); } catch (err) { if (thisRequest !== cumulativeRequestId) return; console.error('[Cumulative Filter] Error fetching vehicle data:', err); @@ -2312,19 +2243,7 @@ if (isMobileView) populateMobileCards(); } - function buildPerformanceBarHtml(score) { - const rating = Math.max(0, Math.min(5, Number(score) || 0)); - return ` -
-
-
-
- ${rating.toFixed(2)} -
- `; - } - - function updateSummaryStats(vehicles, performanceScore) { + function updateSummaryStats(vehicles) { vehicles = vehicles.filter(v => v.vehicle !== 'DISCONNECTED'); let totalBattles = 0, totalWins = 0, totalGK = 0, totalAK = 0; let totalAssists = 0, totalCaptures = 0, totalDeaths = 0; @@ -2353,8 +2272,6 @@ document.getElementById('stat-assists').textContent = totalAssists; document.getElementById('stat-deaths').textContent = totalDeaths; document.getElementById('stat-captures').textContent = totalCaptures; - const performanceWrap = document.getElementById('stat-performance'); - if (performanceWrap) performanceWrap.innerHTML = buildPerformanceBarHtml(performanceScore ?? initialPerformanceRating); } function applyCumulativeFilters() { diff --git a/web/views/squadron-profile.ejs b/web/views/squadron-profile.ejs index 1382735..995f964 100644 --- a/web/views/squadron-profile.ejs +++ b/web/views/squadron-profile.ejs @@ -166,24 +166,6 @@ margin-top: 0.2rem; } - .stat-card-performance .stat-label { - margin-top: 0; - margin-bottom: 0.35rem; - } - - .stat-card-performance { - min-height: 78px; - } - - .stat-performance-wrap { - width: 100%; - margin-top: 0.35rem; - } - - .stat-performance-wrap .sq-performance-bar { - width: 100%; - } - .members-section { background: rgba(30, 30, 30, 0.6); border-radius: 1rem; @@ -646,51 +628,6 @@ color: rgba(255, 255, 255, 0.8); } - /* Cumulative performance bar */ - .sq-mini-graph { - width: 160px; - min-height: 40px; - margin: 0 auto; - display: flex; - align-items: center; - } - - .sq-performance-bar { - width: 100%; - display: flex; - align-items: center; - gap: 0.55rem; - } - - .sq-performance-bar-track { - position: relative; - flex: 1; - height: 12px; - border-radius: 999px; - overflow: hidden; - background: rgba(255, 255, 255, 0.08); - border: 1px solid rgba(144, 238, 144, 0.16); - box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.35); - } - - .sq-performance-bar-fill { - height: 100%; - border-radius: inherit; - background: linear-gradient(90deg, rgba(245, 245, 220, 0.96), rgba(144, 238, 144, 0.96)); - box-shadow: 0 0 14px rgba(144, 238, 144, 0.25); - transition: width 0.35s ease; - } - - .sq-performance-bar-value { - min-width: 2.75rem; - text-align: right; - font-variant-numeric: tabular-nums; - font-size: 0.9rem; - font-weight: 700; - color: #F5F5DC; - letter-spacing: 0.02em; - } - /* Games section */ .sq-games-section { background: rgba(30, 30, 30, 0.6); @@ -940,8 +877,6 @@ const summaryKps = typeof squadronData.squadron_summary.kps === 'number' ? squadronData.squadron_summary.kps.toFixed(2) : (Number(squadronData.squadron_summary.kps || 0)).toFixed(2); - const summaryPerformance = Math.max(0, Math.min(5, Number(squadronData.squadron_summary.performance || 0))); - const summaryPerformanceWidth = summaryPerformance * 20; %>
<% if (squadronData.squadron_summary.points && squadronData.squadron_summary.points.has_points_data) { %> @@ -978,18 +913,6 @@ <%= summaryKps %>
KPS
-
-
ELO
-
-
-
-
-
- <%= summaryPerformance.toFixed(2) %> -
-
-
-
<%= squadronData.squadron_summary.ground_kills %>
<%= t('common.groundKills') %>
@@ -1135,12 +1058,9 @@ <%= t('common.player') %> - - ELO - - - <%= t('common.points') %> - + + <%= t('common.points') %> + <%= t('common.battles') %> @@ -1177,24 +1097,10 @@ - <% - const buildEfficiencyBar = (score) => { - const rating = Math.max(0, Math.min(5, Number(score) || 0)); - return ` -
-
-
-
- ${rating.toFixed(2)} -
- `; - }; - %> - <% squadronData.players.forEach(player => { const score = Math.max(0, Math.min(5, Number(player.performance || 0))); %> - - <%= player.nick %> -
<%- buildEfficiencyBar(score) %>
- <%= player.sqb_points || 0 %> + <% squadronData.players.forEach(player => { %> + + <%= player.nick %> + <%= player.sqb_points || 0 %> <%= player.total_battles %> <%= player.wins %> <%= player.win_rate.toFixed(1) %>% @@ -2443,11 +2349,6 @@ setText('sq-stat-assists', s.assists); setText('sq-stat-deaths', s.deaths); setText('sq-stat-captures', s.captures); - const performanceWrap = getElement('sq-stat-performance'); - if (performanceWrap) { - const score = Math.max(0, Math.min(5, Number(s.performance || 0))); - performanceWrap.innerHTML = buildEfficiencyBarHtml(score); - } } function escapeHtml(str) { @@ -3107,27 +3008,14 @@ renderPerformanceView(); }; - function buildEfficiencyBarHtml(score) { - const rating = Math.max(0, Math.min(5, Number(score) || 0)); - return ` -
-
-
-
- ${rating.toFixed(2)} -
- `; - } - - function renderMembersTable(players) { + function renderMembersTable(players) { const tbody = getElement('sq-members-table-body'); if (!tbody) return; - if (!players.length) { - tbody.innerHTML = ''; - document.querySelectorAll('.sq-mini-graph').forEach(wrap => { wrap.innerHTML = ''; }); - return; - } + if (!players.length) { + tbody.innerHTML = ''; + return; + } tbody.innerHTML = players.map(p => { const nickRaw = p.nick || ''; @@ -3136,13 +3024,11 @@ const winRate = (typeof p.win_rate === 'number' ? p.win_rate.toFixed(1) : (p.win_rate || 0)) + '%'; const kdr = typeof p.kdr === 'number' ? p.kdr.toFixed(2) : (p.kdr || 0); const kps = typeof p.kps === 'number' ? p.kps.toFixed(2) : (Number(p.kps) || 0).toFixed(2); - const performanceValue = Math.max(0, Math.min(5, Number(p.performance || 0))); - return '' + - '' + nickEsc + - '' + - '
' + buildEfficiencyBarHtml(performanceValue) + '
' + - '' + (p.sqb_points || 0) + '' + + return '' + + '' + nickEsc + + '' + + '' + (p.sqb_points || 0) + '' + '' + (p.total_battles || 0) + '' + '' + (p.wins || 0) + '' + '' + winRate + '' + @@ -3157,12 +3043,12 @@ ''; }).join(''); - // Reset sort state so the next call lands on desc instead of toggling - try { currentSort = { field: '', direction: 'desc' }; } catch (e) { /* no-op */ } - if (typeof sortMembersTable === 'function') { - sortMembersTable('performance'); - } - } + // Reset sort state so the next call lands on desc instead of toggling + try { currentSort = { field: '', direction: 'desc' }; } catch (e) { /* no-op */ } + if (typeof sortMembersTable === 'function') { + sortMembersTable('sqb_points'); + } + } initSeasons(); renderMembersTable(currentSquadronPlayers);