Add per-user language selection (issue #166)

The profile already had a language selector (Templates/Profile/preference.tpl)
that saved the choice into users.lang and $_SESSION['lang'], but the saved
preference was never used to actually load the language: every page loads
include("Lang/".LANG.".php") with the server-wide LANG constant, so changing
the language in the profile had no visible effect.

This wires it up:

- Introduce SERVER_LANG (the server default) and make LANG the EFFECTIVE
  display language, resolved from the player's saved preference
  ($_SESSION['lang']) with a fallback to SERVER_LANG
  (install/data/constant_format.tpl).
  SECURITY: the value is sanitized to [a-z_] and the target Lang/<x>.php
  file must exist, otherwise we fall back to the server default. This
  prevents Local File Inclusion via include("Lang/".LANG.".php").

- Seed $_SESSION['lang'] from users.lang on login (GameEngine/Session.php,
  PopulateVar), so the chosen language applies right after logging in.

- Keep the SERVER default intact when an admin saves settings: the admin
  config regenerators and the "Server Settings"/config displays now use
  SERVER_LANG (the server default) instead of the per-user LANG, so an
  admin browsing in their own language can't accidentally overwrite the
  server default (6 Admin/Mods/edit*.php + editServerSet.tpl + config.tpl).

Note: existing installs must also add SERVER_LANG + the LANG resolution to
their generated GameEngine/config.php (and the Admin/Mods/constant_format.tpl
copy) since config is generated at install time.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
TravianZ Patcher
2026-06-04 09:07:57 +02:00
parent 11ce6e6052
commit 421915f774
10 changed files with 38 additions and 15 deletions
+16 -2
View File
@@ -43,8 +43,22 @@ define("START_DATE", "%SSTARTDATE%");
define("START_TIME", "%SSTARTTIME%");
// ***** Language
// Choose your server language.
define("LANG","%LANG%");
// SERVER_LANG is the DEFAULT language of the server (chosen at install / in
// the admin "Server Settings"). LANG is the EFFECTIVE display language.
//
// Per-user language (issue #166): if the logged-in player picked a language
// in their profile preferences (stored in users.lang and mirrored into
// $_SESSION['lang']), LANG becomes that language; otherwise LANG falls back
// to SERVER_LANG.
//
// SECURITY: LANG is used in include("Lang/".LANG.".php"), so the value is
// strictly sanitized to [a-z_] (no path traversal) and the target file MUST
// exist, otherwise we fall back to the server default. This prevents Local
// File Inclusion via a crafted session value.
define("SERVER_LANG", "%LANG%");
if (session_status() !== PHP_SESSION_ACTIVE) { @session_start(); }
$__user_lang = isset($_SESSION['lang']) ? preg_replace('/[^a-z_]/', '', strtolower((string) $_SESSION['lang'])) : '';
define("LANG", ($__user_lang !== '' && is_file(__DIR__ . "/Lang/" . $__user_lang . ".php")) ? $__user_lang : SERVER_LANG);
// ***** Speed
// Choose your server speed. NOTICE: Higher speed, more likely