Changelog¶
Release history. The same content is mirrored as plain text in ChangeLog at the repository root (used by the release workflow); this file is the maintained Markdown copy for readers and tools.
Version 0.3.23, 2026-04-30¶
Shipping label is 0.3.23; this section lists accumulated changes on that line.
Changes and bugfixes¶
- Frontend/admin modernization closure: phases 1-7 are complete for the compatibility scope; remaining items are explicitly future/non-goals (framework reskin, route-specific visual redesign, in-app CSP header enforcement, and unproven selector deletion).
- CSS token closure: shipped themes now expose
cellmenu*variables alongside existing shell/title/list/menu tokens, and dynamic parser FTP-password panels use shared CSS classes/tokens instead of inline JSstyle.cssText. - Embedded parser confirmation UI coverage: a mocked-
EventSourcePlaywright smoke test emitsconfirm_action, verifies the visible Yes/No panel, and confirms Yes starts a new EventSource with the nonce-backedconfirmUrlwithout executing destructive actions. - Admin message hardening: login, upgrade, parser, servers, users, players, string editor, and FTP builder error messages are escaped before template output where applicable and use the established alert/live-region pattern.
- Admin FTP builder robustness: invalid server ids now render a normal escaped alert instead of relying on a broken row check; id loading uses a bound query while preserving field names and popup behavior.
- Responsive layout containment: narrow public/admin viewports now stack the 400px header logo and selector controls; long public/admin menus, public pagers, dense admin list tables, representative public content/list tables, and player/round detail shells scroll inside their own strips instead of forcing page-level horizontal overflow. Admin summary/config/filter panels and public search/error panels now fit the mobile body chrome.
- Admin server editor usability: add/edit server form fields now have stable labels/IDs plus HTML5 hints that mirror existing server-side rules (
requiredname/IP/port/log path and numeric port bounds) while preserving all field names and POST behavior. - Admin user editor usability: add/edit user form fields now have stable labels/IDs, username autocomplete/required hint, and password autocomplete hints; password fields stay optional in the shared edit form so existing password-change behavior is unchanged.
- Admin string editor usability: filter and string ID inputs now use standard text inputs; add/edit string form keeps stable labels/IDs and adds the required/autocomplete-off hint for the string ID while preserving language/text field names.
- Admin server save validation: relative game-log paths such as
gamelogs/cod4_normal.logare validated relative to the UltraStats app root, matching parser behavior; uncreatable paths now report the existing validation error instead of throwing a PHP 8fclose(false)fatal. - Admin server editor messaging: server validation errors are escaped before template output and the error box now uses alert live-region semantics like the other hardened admin forms.
- Parser confirmation coverage: Playwright now asserts classic parser destructive confirmations and embedded parser SSE confirmation payloads expose nonce-backed Yes URLs for delete server, delete stats, and reset last log line, with no legacy
verify=yeslinks. - Admin parser errors: parser wrapper validation messages are escaped before template output, and the missing-server path now reports the requested ID instead of referencing an undefined variable.
- JavaScript IE cleanup: removed active MSIE/Trident-era branches from
common.js(window.event/cancelBubblefallbacks, string-basedsetTimeout, and the Trident-only menu tooltip path). The oldHoverPopupMenuHelpglobal remains as a no-op shim while modern menu usability relies on CSS flyouts/native titles. - Admin index CSP cleanup: medal group toggles and medal autosave/recalculate logic now run from shared
common.jsusing existing checkbox classes plus#medal-autorecalc-statusdata attributes;admin/index.htmlno longer embeds inline scripts. - Embedded parser CSP cleanup: the admin
parser.htmlEventSource UI now runs from sharedcommon.jsinstead of an inline<script>block, preserving SSE event names, cancel flow, resume/run-totals chaining, and dynamic confirm/FTP panels. - Classic parser CSP cleanup: parser-core HTML now loads shared
common.js; parser autoscroll and resume/run-total auto-reload behavior usedata-parser-autoscroll/data-reload-*markers instead of inline<script>blocks. - FTP builder CSP cleanup: popup centering/focus and saved auto-close now use
common.jshandlers withdata-popup-center-*/data-ftpbuilder-close-delaymarkers;servers-ftpbuilder.htmlno longer embeds inline scripts. - Template CSP cleanup: remaining active template event-handler attributes were removed from shared popup panels, public weapon/damage stat bars, and admin server action tooltips; delegated
.us-popup-help/.us-popup-panelhandlers incommon.jspreserve hover popups whilergreports noonclick/onkeyup/ mouse-hover attributes in templates. - Player detail CSP cleanup: hit-location body-map and killed-by legend hovers in
players-detail.htmlnow use delegatedcommon.jshandlers withdata-*attributes; the repeated inline mouse handlers and page-localHoverPlayerImagescript were removed while preserving popup/legend behavior. - Public menu CSP cleanup: shared top-menu toggle, timeout-extension, and popup-help behavior moved from inline event attributes in
include_menu.htmlto delegatedcommon.jshandlers backed bydata-*attributes; smoke asserts the menu has no inline JavaScript handlers and still toggles. - Admin navigation polish: confirmation/error back links in users, players, string editor, upgrade, and parser confirm views now use real fallback URLs plus delegated
.us-history-backbehavior instead ofhref="javascript:history.back();". - Homepage top players: the Played Time column now stays on one line by scoping a no-wrap/min-width rule to the main top-player table, preventing day/time values from wrapping in narrow dark-theme layouts.
- Phase 6 (admin UX pilot): destructive parser operations in the browser (
delete,deletestats,resetlastloglineonparser-core.php/parser-sse.php) require a single-useparser_confirm_nonceissued with the confirmation UI; plainverify=yesbookmark links no longer execute those actions. Keeps GET + EventSource flows working; CLI/cronparser-shell.phpunchanged. - Admin users: confirmed deletes use POST +
ultrastats_csrf(UltraStats_AdminCsrf*infunctions_common.php) and PRG viaresult.php; CSRF rotates on login.admin_securecheck.htmlposts tousers.phpwithout relying on query-stringverify=yes. - Embedded parser UI: confirm banner uses
defaults.cssus-parser-confirm-*helpers and--us-parser-confirm-*tokens (Phase 6.2 / 4.2 slice). - Languages:
LN_WARNINGRESETLASTLOGLINE(en/de). - Docs/tests:
docs/admin-destructive-actions-inventory.md,docs/admin-phase6-manual-confirm-checklist.md; roadmap +template-variable-trust.mdrows; Playwright CSRF rejection case +history.back()selector fix. - Admin players / string editor: delete confirmation uses POST +
ultrastats_csrf(admin_confirm_player_delete/admin_confirm_string_delete);verify=yesno longer runs those deletes.SECURITY.mdand inventory updated; Playwright covers confirm forms + CSRF rejection for both routes. - Phase 1.5:
e2e/tests/admin-visual-baseline.spec.ts— admin index screenshot byte-size guard; optional golden compare whenULTRASTATS_ADMIN_VISUAL_BASELINE=1. - Admin error strips (Phase 6.2):
admin/players.html,admin/users.html,admin/stringeditor.htmluseErrorMsg+ live region semantics; matching PHP assignsUltraStats_h(ERROR_MSG)whenISERROR. - CSS:
defaults.css—--us-parser-debug-grid-bg,--us-priority-emergency-*;.us-admin-player-filter-baron admin players list filter row. - Admin slim + FTP builder:
admin_slim_header.htmlloadscommon.jswithdefer; saved FTP builder popup usesus-admin-ftpbuilder-close+UltraStatsAdminCloseFtpBuilderPopupinstead of inlineonclick. - Admin UX polish (Phase 6.3/6.4 slice): optional browser confirms on GET-first destructive entry links via
.us-confirm-nav(users,players,stringeditor, parser destructive links inparser/serversscreens); server-side confirm/nonce flow remains authoritative. - Admin servers edit inline JS reduction: FTP builder launcher uses delegated popup metadata (
.us-open-popup+data-popup-*) inservers.htmlwithcommon.jslistener (replaces inlineNewWindow(...)call). - Phase 3.3 completion pass: removed remaining active template inline
style="..."attributes by reusing utility classes indefaults.css; parser classic debug shell body color moved to.us-parser-body; player-name color output no longer uses<font>(now<span>infunctions_common.php). - Phase 4.2 completion (all shipped themes): tokenized remaining hardcoded color literals in
defaults.cssandthemes/default/main.css,themes/dark/main.css,themes/codww/main.cssunder:rootvariables. - Phase 4.3 completion (inner layout only): parser embed toolbar/status/cancel now use reusable classes (
.us-parser-embed-toolbar,.us-parser-stream-status,.us-parser-cancel-btn,.us-hidden); additional utility classes (.us-form-select-*,.us-fixed-w-*,.us-pad-*, etc.) replace inline layout styling without outer chrome changes. - Phase 4.4 completion (aggressive): shared outer shell chrome is now classed in public/admin wrappers (
.us-chrome-top,.us-chrome-body,.us-chrome-footer) viainclude_header.html,include_footer.html,admin_header.html,admin_footer.html.defaults.cssadds responsive shell sizing/radius/shadow (--us-chrome-*), with per-theme tuning in shipped theme files. - Baseline gate for 4.4: smoke assertions now check
.us-chrome-*presence on representative public/admin pages; visual baseline spec adds a public index outer-chrome screenshot guard (strict screenshot compare remains gated byULTRASTATS_ADMIN_VISUAL_BASELINE=1). - Screenshot matrix (public + admin): added
e2e/tests/full-route-visual.spec.tsto capture full-page artifacts for broad public/admin list+detail routes (includinginfo-maps.php?id=mp_strike&serverid=2) with byte-size guards and optional strict compare behindULTRASTATS_ADMIN_VISUAL_BASELINE=1. - Artifact-driven CSS fixes:
info-maps.htmlnow usesus-map-detail-layout/us-map-detail-colresponsive classes;defaults.cssstacks map detail columns on narrow widths and sets.us-chrome-top/.us-chrome-body/.us-chrome-footertooverflow: visibleto avoid chrome clipping regressions. - Mobile/narrow viewport sweep (1280/1024/900): captured a full public/admin screenshot + shell-metrics matrix and triaged shared-shell breakages first; top/menu/pager/body/footer alignment remained stable across sampled routes.
- Narrow overflow containment:
defaults.cssnow applies a <=1100px shell rule where.us-chrome-bodybecomes a bounded block container with horizontal overflow handling, so dense legacy tables (notablyindex.phpandplayers.php) scroll inside body chrome instead of forcing page-level horizontal overflow. - Verification: reran the same 1280/1024/900 matrix post-fix and executed focused smoke checks (
core public routes render without server errors,critical admin screens still load with legacy routes) to confirm compatibility on touched paths. - Phase 1 closure (
1.1–1.5): baseline program is now complete: deeper core public/admin smoke assertions for shell and contract surfaces, mandatory HTML validation suite viae2e/tests/html-validation.spec.ts, completed trust-inventory closure matrix indocs/template-variable-trust.md, and strict visual snapshot assertions enabled by default (noULTRASTATS_ADMIN_VISUAL_BASELINEgate in baseline specs). - Strict snapshot baseline set: first committed baseline snapshots generated with
--update-snapshotsfor win32/chromium undere2e/tests/admin-visual-baseline.spec.ts-snapshotsande2e/tests/full-route-visual.spec.ts-snapshots. - userchange.php: fixed the redirect after using the language, style, or time-filter dropdowns when the site is installed under a URL subfolder (the
Locationtarget is now a single script name under that folder, so the browser no longer resolves a doubled path like/app/app/players.phpand returns 404). Same-host detection for the referer now compares the host part correctly whenHTTP_HOSTincludes a port. - Admin database upgrade:
database_installedversionis updated only when every SQL statement succeeds. If anything fails, the version stays unchanged and the upgrade page explains that you must fix errors and run upgrade again (avoids a half-applied schema with a “fully upgraded” version). - CI / tests: GitHub Actions PHP CI workflow (
php -lon allsrc/**/*.php, PHPUnit for DB string helpers and the bundled CoD4 gamelog fixture); optional dev install via Composer (composer.json,vendor/gitignored). - Security (admin result): result.php now sends a sanitized meta refresh URL (
UltraStats_SanitizeRedirectTarget), HTML-escapes the flashmsgand the redirect target embedded in the translated “redirecting…” line, and caps the refresh delay. UltraStats_SanitizeRedirectTarget also rejects javascript: / data: style targets, quotes, backslashes, angle brackets, and control characters so the same helper stays safe inLocation, meta refresh, andhrefcontexts. - Admin UI: fixed
javascript:history.back()on the admin players list template and the parser helper back link (brokenhistory.backwithout parentheses). - Security (error pages):
DieWithErrorMsgandDieWithFriendlyErrorMsgnow HTML-escape error detail text before rendering (line breaks preserved), preventing script/markup execution in error detail output. - Security (legacy popup JS):
src/js/common.jsnow writes popup title/content viatextContentinstead ofinnerHTMLinHoverPopupandHoverPopupMenuHelpto reduce DOM injection risk. - Tests: PHPUnit tests cover redirect sanitization plus error-text HTML escaping; Playwright coverage for result.php (safe redirect, blocked external/javascript targets, escaped message, no meta refresh when
rediris omitted). - HTML shell (modernisation): Shared templates now use an HTML5 document type (
<!DOCTYPE html>), explicit UTF-8 charset, and a viewport meta tag for basic mobile scaling — include_header, admin_header, install, admin_slim_header, rounds-chatlog, plus the parser HTML wrapper fromCreateHTMLHeader()in functions_parser-helpers.php. - Tests: Playwright checks HTML5 doctype and charset meta on representative public routes.
- Fatal / friendly error pages:
DieWithErrorMsgandDieWithFriendlyErrorMsgnow output a minimal HTML5 shell (<!DOCTYPE html>, charset, viewport) viaUltraStats_RenderStandaloneErrorDocumentHtml()in functions_common.php; escaped detail text behavior is unchanged. - Legacy IE PNG workarounds removed: install, index medal tiles, and medals no longer use AlphaImageLoader filters or
CheckAlphaPNGImageinline scripts; unusedCheckAlphaPNGImagewas removed from common.js. - Tests: PHPUnit covers the standalone error document helper.
- Presentational / safety (Phase 3.3): Parser user-check and FTP password failure title in functions_parser-helpers.php use
us-error-textandhtmlspecialcharsfor dynamic text. Admin servers-ftpbuilder.php FTP verify messages replace<font color="red">withus-error-textand escape IP, port, path, username, and log filename in error output. - Last played rounds layout: On players-detail, info-maps, info-gametypes, and serverstats, the date/time and Details link are stacked in one column; gametype and map each have their own column where applicable. Shared
us-lastrounds-*rules in defaults.css fix cramped/overlapping cells. - Team colour markup: index.html and rounds.html use
<span class="…">(existing.WinnerTeam/.LoserTeam/.DrawTeamtheme rules) instead of<font>for flags and scores; invalid leftover</font>tags in the DM winner cell are removed; rounds.html map thumbnail cell entity fixed ( ). - Player detail hit-area hovers: players-detail.php builds damage
<span class="us-damage-pct">with validated#RRGGBBinline colours (helpersUltraStats_PlayerDetailCssHexColor,UltraStats_PlayerDetailHoverDamagePctHtml) instead of<font color>;us-damage-pct-zeroin defaults.css for 0%. - Documentation: docs/template-variable-trust.md —
{VAR}trust levels,<!-- INCLUDE -->/{ERROR_DETAILS}/{ERROR_MSG}(Phase 1.4 / 7.2). - JavaScript (Phase 5.2): include_header (server / language / style) and include_pager (year / month when time filter is on) use
us-autosubmit-select; common.js listens forchangeand callsform.submit()(no inlineOnChangehandlers). - Public header (accessibility): include_header — each of the three top
<select>controls has a stableid(us-header-serverid,us-header-langcode,us-header-stylename) and the adjacent bold caption uses<label for="…">so assistive tech can associate label and control (URLs andGETfields unchanged). - Install wizard step 2 (markup): install.html permission indicator column uses
us-install-perm-cellplusus-install-perm-ok/us-install-perm-failfrom defaults.css instead ofbgcoloron the cell (#007700 / #770000 unchanged). - Public top menu (layout): include_menu.html uses
us-top-menu; defaults.css usestable-layout: auto,td.topmenu1/td.topmenu1beginwithwidth: auto,white-space: nowrap, andmin-width: max-content(public nav only — admin_menu.html has nous-top-menu). This avoids both clipping from legacy narrowtd widthattributes and overlap when labels are long; a very wide row scrolls horizontally. - Weapon / damage-type lists (markup): weapons.html and damagetypes.html list rows — close the player-count bar
<td>after the inner bar table (was missing</td>; could confuse table column assignment next to the weapons external info cell). - Header / pager / admin selects: include_header, include_pager, admin/index.html, admin/stringeditor.html — uppercase
STYLEon<select>normalized tostyle(same widths). - Anchors (markup style): public and admin
.htmltemplates;LN_INSTALL_ERRORINSTALLEDin lang/en/main.php / lang/de/main.php; parser confirmation markup in functions_parser-helpers.php — legacy<A HREF>/</A>normalized to<a href>/</a>(same URLs). - Bold / breaks (markup style): templates —
<B>/</B>→<b>/</b>;<BR>→<br>on index.html and admin/result.html. Installer strings in main.php (en/de):<b>config.php</b>, configure.sh / contrib emphasis tags lowercased. - Parser messages: functions_parser.php — printed resume / time-limit lines use consistent lowercase
<b>…</a>…</b>. - Italic / attributes: several templates —
<I>/</I>→<i>/</i>on pager rows;width="100%"class=→width="100%" class=where the space was missing beforeclass(HTML5 attribute separation). - Event attributes: templates — legacy
OnMouseOver/OnMouseMove/OnMouseOut/OnClick→onmouseover/onmousemove/onmouseout/onclick(same handlers and behaviour). - Body / parser wrapper: include_header, admin_header, admin_slim_header, install, rounds-chatlog —
topmargin/leftmargin/marginwidth/marginheighton<body>. functions_parser-helpers.php embedded parser HTML:<script>,onload, same body margin attributes (replacing uppercaseSCRIPT/OnLoad/TOPMARGIN). - Stylesheet links:
type="text/css"dropped from<link rel="stylesheet">in shared headers, install, chatlog iframe, parser HTML head, and functions_common.php standalone error document (default MIME type unchanged). - Script tags: include_header, admin_header, install —
<script src="…common.js">withouttype="text/javascript"; admin/index.html inline scripts use<script>only. - FTP builder: servers-ftpbuilder.html —
language="javascript"removed from<script>blocks (obsolete in HTML5). - DOM lookups: servers-ftpbuilder.html —
document.all.preview→document.getElementById('preview'); players-detail.html (commented legacy axis markup) —document.all('playerlegend_killedby')→document.getElementById('playerlegend_killedby'). - Player / rounds layout: players-detail.html — added the missing space between
colspan="2"andclass="line1"on the total playtime row (wascolspan="2"class=…, invalid HTML5). rounds.html had the same typo on the round details header cell. Browsers were mis-parsing the table so main stat cells appeared empty and the ratio row looked broken. - JavaScript (Phase 5.1 / 5.3): common.js — legacy MSIE/Opera sniffing at load removed;
movePopupWindowusesUltraStatsPointerPageY/UltraStatsPointerClientX;disableEventPropagationusesstopPropagation; guards whenpopupdetailsis missing;window.UltraStatsUImirrors globals. - Player detail hit-location hovers (markup): players-detail.php — damage and 0% hover fragments use single-quoted HTML attributes so the string is safe inside template hover data attributes. (Earlier
class="…"double quotes cut the attribute short and showed raw handler text on the page.) - Player detail hit-zone layout: players-detail.html —
us-hitloc-*classes on the two half-width panels and inner chart/stats row; nested CoD4 spritetable(us-hitloc-figure) keepsborder-spacing: 0, zerotdpadding, andimg { display: block }so body-part tiles align; outertable.us-hitloc-innerusestable-layout: autoand the chart cellwidth: 220px(content-box) so the 220px-wide sprite grid is not squeezed. The stats sub-table (us-hitloc-stats-table) still usestable-layout: fixed+ column classes (us-hitloc-col-*) so zone names and kill counts stay readable.
Changes (maintainability / SQL)¶
- CSS (Phase 4.1 / maintainability): defaults.css —
:rootdefines--us-color-error,--us-color-bar-*, and related tokens;.ErrorMsgand theus-*utility classes above consumevar(...)so hex values live in one place (appearance unchanged by default). - CSS (Phase 4.1a / all shipped themes): themes/default/main.css (
--us-default-*), themes/dark/main.css (--us-dark-*), themes/codww/main.css (--us-codww-*) — top menu / flyoutvar()wiring (.topmenu1–.topmenu3, links); appearance unchanged. - Templates (Phase 3.5): public
ERROR_DETAILS/LN_ERROR_DETAILSbanners are inline HTML under<!-- IF -->in weapons.html, damagetypes.html, players-detail.html, info-maps.html, info-gametypes.html, medals.html, serverstats.html, index.html (error_noserver), players.html / rounds.html, find-players.html / find-chat.html, rounds-detail.html. include_header.html inlineserror_installfilereminder; admin_header.html inlinesisupdateavailable; servers.html / servers-ftpbuilder.html inlineERROR_MSG/ FTP-warning blocks.$contentassignments from PHP unchanged. - German strings: lang/de/main.php —
LN_GLOBAL_STATSuses the correct UTF-8 spelling präsentiert (fixes a corrupted replacement character in the shipped file). - Documentation (Phase 7.2): docs/template-variable-trust.md —
{ERROR_DETAILS}/{ERROR_MSG}trust guidance; no separate error-banner fragment files (markup inline per template). - CSS (Phase 4.2): defaults.css holds shared
TDfont/size,imgborder reset, and legacy<font>styling; thememain.cssfiles only setTDtext colour. rounds-chatlog.html andUltraStats_RenderStandaloneErrorDocumentHtml()in functions_common.php loaddefaults.cssbefore theme CSS. - CSS (Phase 4.2b): defaults.css — section
.title/.titleSecondlayout (font, height, alignment, horizontal tile repeat) and list-cellfont-sizefor.line0–.line2/.tableBackground. Shipped themes retain palette,a.titlerules, hovers, andimages/bg_3.png/bg_4.png. - PHP (Phase 7.2a): functions_common.php —
UltraStats_h()for HTML text/attribute escaping; used by result.php (admin flash + redirect line),UltraStats_EscapeErrorTextForHtml,UltraStats_RenderStandaloneErrorDocumentHtml, and the PHP 7.4+ gate message. Tests:RedirectSanitizeTest::testUltraStats_h_escapesForHtml. template-variable-trust.md updated. - JavaScript (Phase 5.1): common.js — section comments (pointer helpers,
NewWindow, toggle display, popups, autosubmit<select>,UltraStatsUI); legacyNewWindow/HoverPopupMenuHelp/ Phase 5.2 IIFE comment text cleaned to ASCII (same behaviour). - Tests: Playwright asserts a visible
td.titleon/players.phpand/rounds.phpwhen the list is enabled;test.skipif the title row is missing (stats off or empty install). - Documentation: template-variable-trust.md — Key routes (Phase 1.4): weapons, damagetypes, serverstats, medals, about; Escaping cookbook (Phase 7.2).
- Tests: Playwright asserts
td.titleon/weapons.php,/damagetypes.php,/serverstats.php,/medals.phpwhen enabled (test.skipif missing);/about.phprequirestd.titleunconditionally. - Obsolete
<center>: replaced by<div class="us-center">and.us-centerin defaults.css across public/admin templates and matching PHP-printed fragments (parser / install hint). - Parser shell: server list
SELECTusesDB_QueryBound(no placeholders). - info-maps.php / info-gametypes.php: map name and gametype name from
?id=use bound parameters for detail and “last rounds” queries.
Version 0.3.21, 2026-04-28¶
Changes and bugfixes¶
- Homepage medals: fixed row rendering and spacing in homepage medal sections (pro/anti/custom) so cards are centered consistently and no longer forced into brittle 6-item wraps.
- Homepage template: corrected malformed HTML in src/templates/index.html (stray closing tags/entities and link closure) that could destabilize table layout.
- Theme CSS (codww): replaced legacy
cursor:handusage and corrected an invalid font declaration in src/themes/codww/main.css for better browser compatibility without changing overall style.
Version 0.3.20, 2026-04-27¶
New features¶
- CI: GitHub Actions publishes a release tarball (
git archive) onv*tag pushes; release body combines ChangeLog excerpts with generated notes (.github/scripts/build_release_body.py); README.md and AGENTS.md document Releases. - Admin parser: Server-Sent Events live log (
parser-sse, sharedparser-core-operationswithparser-core); cooperative cancel (parser-cancel.php, tmp flag); batched monospace log UI; structured FTP/password prompts; dark-themed embed with viewport-clamped log panel (defaults.css,parser.html). - Admin parser (embedded SSE completion): on successful stream end, sticky green DONE banner with optional elapsed time and link back to the server list (
LN_PARSER_DONE,LN_PARSER_RETURN_SERVERLISTen/de); not shown on cancel, chained run-totals, or FTP/password-confirmation flows. - Log parser: large-parse performance (parse-scoped lookup caches, set-based
CreateTopAliasesper server and for global Run total stats, batchedmysqli_multi_queryfor queuedUPDATEs,INSERT … ON DUPLICATE KEY UPDATEfor player/time stats). - Log parser:
JT(join team); advanced round-action linesFT,FR,FC,RC,RD,BP,BD(CTF / KOTH / bomb events); CoD:WaW compactW/Lwin/loss lines whengen_gameversionis WaW. - Medals (CoD / UO / CoD2): pro medals for shotgun, MG, Thompson (display), and Panzerschreck (weapon kill rankings).
- Documentation: maintainer deployment (docs/maintainer-deployment.md), CSP staging (docs/csp-staging.md), prepared-statement inventory (docs/prepared-statements-surface.md); Docker rebuild helpers and gamelog resolution notes in AGENTS.md.
Changes and bugfixes¶
- PHP 8 / MySQLi:
DB_QueryandDB_Execcatchmysqli_sql_exceptionso failures returnfalseinstead of fatals;DB_GetRowCounthardened;DB_GetRowCountBoundfor filtered list counts. - Security / SQL:
password_hash/password_verifywith MD5 fallback; bound parameters and safer patterns across admin lists (players, strings, servers),GetPlayerHtmlNameFromID, install paths,FillPlayerWithAlias/FillPlayerWithTime,FindAndFillWithTime(dynamicIN),FindAndFillTopAliases,CreateBannedPlayerFilter(int-cast GUIDs), rounds gametype filter +LIMIT, index/top-players thresholds,GetAndSetGlobalInfoandGetAndSetMaxKillRationinteger casting;UltraStats_SqlLikeContainsPatternforLIKE;WriteConfigValueescapes name/value and handles emptySELECTresults. - Install:
UltraStats_ValidateTablePrefixbefore prefixed DDL;gen_gameversionanddatabase_installedversionviaDB_ExecBoundafter schema batch; upgrade runner accepts single-statementdb_update_*.txtfiles (statement count check uses< 1); web installer chooses InnoDB (default) or MyISAM for new tables (TYPE=MyISAMin schema rewritten toENGINE=…);config.sample.phpincludes informationalDBStorageEngine;UltraStats_NormalizeStorageEngine/UltraStats_ApplyStorageEngineToSchemaSqlinfunctions_db.php. - Docker:
seed-database.phphonorsULTRASTATS_DB_STORAGE_ENGINE(default InnoDB). - Parser / aliases: correct empty result handling after
DB_GetAllRows()(!emptyvsisset) in parser, consolidation, and admin server lookup;UltraStats_Utf8StringForDatabase+ utf8mb4-safe aliasINSERT/WHERE(fixes MySQL 1366 on non-ASCII log names); avoid indexing missingSERVERrows in admin parser. - Database internal versions 8–14 (template +
db_update_*.txt): v8 schema/config alignment with hardened mysqli paths; v9 widenstats_aliases.AliasChecksumtoINTunsigned; v10stats_aliasesindex; v11 indexes onstats_player_killsandstats_rounds; v12 CoD:WaWstats_mapsREPLACEseeds (db_update_v12.txt+db_template.txt); v13 indexidx_aliases_playerid_alias(PLAYERID,Alias) for globalCreateTopAliases; v14 fill empty EN CoD/UO/CoD2 map blurbs instats_language_strings(matchesdb_template_codww2only.txt;UPDATEonly whereTEXTis still''). - Docker:
seed-database.phpCoD4-oriented import, latin1 SQL loads, sample servers and dev admin user;UltraStats_ResolveGamelogLocationfor relative gamelog paths from app root;server_total_ratioconsolidation when no players exist. - rounds-detail.php: fixed PHP 8 fatal when a round has no round-action rows (empty
gameactionsstill passedisset()but never populated$content['gameactions']). - rounds-detail.php: initialize
$AllPlayersand skip medal/awards when there are no players; hardenGetRoundPlayerDetailswhen the kills query returns no mysqli result. - damagetypes.php: default
mostskills_maxkills/killedby_maxkillsto0when grouped kill queries return no rows (fixes PHP 8array offset on nullwarnings). - Schema seed: remove duplicate
stats_mapsINSERTformp_subwayfromdb_template_cod4only.txt(row already in base template / WaW seeds) so install /seed-database.phpdoes not fail with duplicate keyMAPNAME_UNIQUE.
Version 0.3.14, 2026-04-26¶
New features¶
- Documented project for PHP 7.4+ / MySQL 8, Docker dev stack, and security in README.md, AGENTS.md, SECURITY.md, and
.agent/skills. - Replaced
ext/mysqlwith mysqli; prepared statements for high-risk web/admin SQL (find-chat,find-players, user admin, parser server lookup).
Changes and bugfixes¶
- Hardened redirects and sessions; chat/player search and admin user flows use bound parameters; schema adjustments for MySQL 8 (e.g. utf8mb4 index limits).
- Bundled static docs in
src/doc/en/converted to Markdown; Content-Security-Policy guidance added for operators. - Assorted front-end and empty-result SQL fixes for PHP 8 / MySQL 8 (e.g.
IN ()guards).
Version 0.3.13 (beta), 2008-11-30¶
New features¶
- Added icons for game versions to the top left on the menubar.
- Added
SQL_BIG_SELECTSworkaround for certain databases. - Number of top players on the main page is configurable now.
- Added search page for searching in the chat logs.
- Added workaround for changed
ACTIONlogging format of Pam4 in CoD4. However, Pam4 still breaks the log format in a way that some features (e.g. chat logging) will not work with PAM4.
Changes and bugfixes¶
- Fixed PHP4 compatibility issues in the log parser.
- Fixed donate button.
- Added database upgrade V7, including important changes in the database. Also adds missing weapons, maps, and other content automatically, including on existing installations.
- Fixed SD gametype default for CoD:WW; empty gametypes are displayed with gametype id on the main page now.
- Fixed "WTF OMFG" error when player time was 0 seconds (e.g. client disconnected immediately).
- Fixed strange increment error in
install.php.
Version 0.3.12 (beta), 2008-11-18¶
New features¶
- Added new general frotnend options, to inject html code at certain places, prepend a string in the title tag and customize the UltraStats Logo url.
- Added help text for FTP Create button.
- Added display of the current configured game.
- Added check if gamelogfile is actually writeable.
- Added quick and dirty support for download gamelogfiles over http. Just a fully qualified http url instead of ftp, the stats parser automatically detect.
Changes and bugfixes¶
- Fixed Sniper Medal for Codww
- Removed some minor issues with missing templates variables.
- Fixed serious security issue of reading the serverid parameter.
- Fixed problem with session initialization on Microsoft IIS Webservers.
- Fixed a problem in the default db templates, causing some mysql 4 version to fail durign installation.
- Added support to display new weapon ids proberly and correct.
- Fixed minor notice bug when reading script timeout from db settings.
- Fixed PB Guid detection string
- Fixed Knife medal for CodWW and fixed minor bug in the medals page template.
- Fix detection of command line mode, which also fixes php session management.
- Added fix for "SQL_BIG_SELECT" errors in logparser.
Version 0.3.11 (beta), 2008-10-05¶
Changes and bugfixes¶
- Fixed race condition, when a new logfile is used the LastLogLine was only reseted internal. We are reseting the playedseconds as well now.
- Fixed typing issues and removed notices issues
- Changed display name of Marine Soldier to American Soldier
- Removed TM from frontpage logo
- Fixed RoundEnd Detection in Parser, which caused following errors.
Version 0.3.10 (beta), 2008-10-04¶
New features¶
- Added missing .357 Magnum Pistol including images and description.
Changes and bugfixes¶
- Calculation of time (roundbegin) has been hardened and corrected against large logfiles which contain server restarts. Added two new fields into Server Table needed for this and future enhancments.
- Removed some obselete weapons from template database
- All fopen calls changed to use @fopen, this avoids php warnings
Version 0.3.9 (beta), 2008-10-03¶
Changes and bugfixes¶
- Replaced all weapon images with new rendered weapn images from the final game. Added lots of missing images as well.
- Fixed all references to Call of Duty: World ar War.
- Fixed minor spelling issues in default database template
- Removed old obselete documentation.
- Session Startup is done in every site now!
Version 0.3.8 (beta), 2008-10-01¶
New features¶
- Added few missing language strings for certain existing and new weapons.
- Added README document
- Added images for certain existing and new weapons
Changes and bugfixes¶
- Lots of fixes in the weapon table, replaced some of the existing weapon images with better ones.
- Added new attachment images
- Removed ANTI Medals from code for now.
- Fixed minor installer issues and enhanced critical error messages.
- Changed few minor things in the docs and about page
Version 0.3.7 (devel), 2008-09-30¶
New features¶
- Added some german translation
- Added warning if FTP Extensions are disabled!
- Enhanced database query performance in player admin
- Show found player number in player admin
- Prepared time filter for consolidation table
Changes and bugfixes¶
- Fixed GUID issues bug in player admin causing failed edits of some players
- Fixed minor issues if new gametypes were added, no displayname was used
- Fixed lots of minor display issues and minor template issues
- Cleaned up gametypes in default database template
- Removed useless default charset from tabel defs
Version 0.3.6 (devel), 2008-09-29¶
New features¶
- Added missing map picture for airfield
Changes and bugfixes¶
- Fixed minor sql issues in medal statements
- Fixed sort order of available stats years and months
- fixed misspelled svt40 images
- Set default bar images for players without kills
- Added result workaround for TDM gametype in Cod:WW
- Added missing weapons into default sql statement set
- Changed artillery text
- Unknown alias is now displayed with -Topalias Unknown-
Version 0.3.5 (devel), 2008-09-28¶
New features¶
- Added new default theme called "codww" which is like the current www.callofduty.com style.
- Implemented Update Check feature which is performed when the user logs into the admin center. If an update is available, the user will be reminded on each admin page.
- Added option to set php script execution timeout, if possible. This will help people who have to parse the logfile using the webserver.
- Links within text description are parsed and modified, so that always open in a new window.
- Implemented time filter into medal code. All sql statements had to be modified for this to work.
Changes and bugfixes¶
- Fixed some sql statement issues
- Added additional pager template, forgot to add in last version
- Fixed typo of table name when deleting a player in admin/players.php
Version 0.3.4 (devel), 2008-09-24¶
New features¶
- Implemented Time Filtering which can be selected now on the left side below the menu. The time filtering can go down to year and month level. Available years and month will automatically be generated by the statsdata.
- Also cleaned up the template coding, replaced the default error display, and added more useful error description in certain places.
- Added submenu option into pager include. Added available gametypes menu into round list.
- Damagetype and Weapon lists are now stored in helper tables, the data is consolidated in the Total/Final Calculations but can also be done seperated in the Serverlist Menu. This improves performance for stats display on larger databases.
- Also added some more popup help texts in certain areas.
- Fixed a few minor isses in the css and templates.
Version 0.3.3 (devel), 2008-09-21¶
New features¶
- Added 4 new Player Models for Cod:WW, and rewrote the hitdetection model view in the player details. Details are now shown in a popup when you hover the body parts. It is also possible to configure which model you want to use in the player details: marine, german, japanese and russian.
- Added german translation
- Added support to enable GZIP compression. This can be used to reduce outgoing html traffic.
Changes and bugfixes¶
- LogParser: Added workaround to add players into a running round which did not join before. This workaround is only applied in the KILL log line for now.
- Fixed few minor display and visiblity issues in the stats
- Changed some debug levels in the parser. Default debug level is restricted to more useful output now.
- Fixed readability issue in dark style
- Added menu workaround for Internet Explorer, so it works there as well.
- Fixed default picture in serverlist view
- LogParser: Rewrote round begin and round end detection to work with new Cod:WW Gametypes.
- LogParser: Fixed a bug in the custom time start detection method using the gamestartup variable workaround.
- LogParser: Fixed a roundstart time calculation bug which caused played rounds to appear in the future.
Version 0.3.2 (devel), 2008-09-18¶
New features¶
- Initial Changelog entry for the third UltraStats release
- Added support for Cod:WW (Call of Duty: World at War)
- Added map images for Cod:WW
- Added weapon images for Cod:WW
- Added string editor in Admin Center
- Implemented new css based menu into UltraStats
- Enhanced and cleaned up the basic "default" and "dark"
- Added support to LIST weapons and damagetypes on ONE site
- Added favicon.ico
Changes and bugfixes¶
- Added new Installations instructions document called "INSTALL"
- Added GPLv3 document "COPYING"
- Removed unused files, fixed pager in stringeditor and minor other visual tweaks
- Removed unsupported languages and themes for now. Going to add them back in a later step
- Enhanced AdminMenu, fixed a few style sheet bugs
- Fixed minor issue with includes and server deletion
- ini_set commands won't create an error now
- Removed Windows linefeeds from include files
- Enhanced the UltraStats installer, better error handling now!
- Fixed issue of showing PBGUid Field when no PBGuid was available
- Fixed wrong sized thmbnails for custom maps
- Fixed bug in INSERT statement of server admin
- Fixed a bug of players which were not displayed on the detail page. Only happened if there GUID was empty.
- Fixed leaking DB handle in GetSingleDBEntryOnly
- Removed useless files like multiple Thumbs.db occurences
- Removed old cvs crap (using git now ;) )!