mirror of
https://github.com/Shadowss/TravianZ.git
synced 2026-08-22 11:07:13 +00:00
Fix Natars
Fix Natars
This commit is contained in:
+45
-26
@@ -277,39 +277,58 @@ class Artifacts
|
||||
global $database;
|
||||
|
||||
//Register the Natars account, the Natars' password is the same as the MH's one
|
||||
//NOTE: pre-existing anomaly, left untouched - this call passes 8 args
|
||||
//(..., self::NATARS_DESC, self::NATARS_DESC2) but register() only
|
||||
//accepts up to $desc (7 params), so NATARS_DESC2 is silently dropped
|
||||
//by PHP. Not related to the crash fixed below.
|
||||
$password = $database->getUserField(5, 'password', 0);
|
||||
$database->register(TRIBE5, $password, self::NATARS_EMAIL, self::NATARS_TRIBE, null, self::NATARS_UID, self::NATARS_DESC, self::NATARS_DESC2);
|
||||
|
||||
//Convert from coordinates to village IDs
|
||||
$possibleWids = $database->getVilWrefs(self::NATARS_CAPITAL_COORDINATES);
|
||||
|
||||
//Check if the villages aren't already taken
|
||||
$wid = $database->getFreeVillage($possibleWids);
|
||||
|
||||
//Generate the Natars' capital
|
||||
//
|
||||
// The capital starts with the World Wonder and the infrastructure defined
|
||||
// in NATARS_CAPITAL_BUILDINGS. The data is passed in the same format used
|
||||
// for World Wonder villages: [0] = column names, [1][] = values.
|
||||
$capitalBuildings = [];
|
||||
$capitalBuildings[0] = array_keys(self::NATARS_CAPITAL_BUILDINGS);
|
||||
$capitalBuildings[1][] = array_values(self::NATARS_CAPITAL_BUILDINGS);
|
||||
//Idempotency guard: this whole method isn't wrapped in a transaction,
|
||||
//so a previous run may have already built the Natars' capital (e.g.
|
||||
//the register() call above went through, then the process died/timed
|
||||
//out before finishing). Reuse the existing capital instead of trying
|
||||
//to generate a second one, which would either collide or leave a
|
||||
//stray village behind.
|
||||
$existingCapital = $database->getVrefCapital(self::NATARS_UID);
|
||||
if ($existingCapital) {
|
||||
$wid = $existingCapital['wref'];
|
||||
} else {
|
||||
//Convert from coordinates to village IDs
|
||||
$possibleWids = $database->getVilWrefs(self::NATARS_CAPITAL_COORDINATES);
|
||||
|
||||
// The capital army, using the same format as World Wonder villages:
|
||||
// [0] = column names, [1][] = values.
|
||||
$capitalUnits = [];
|
||||
$capitalUnits[0] = array_keys(self::NATARS_CAPITAL_UNITS);
|
||||
$capitalUnits[1][] = array_values(self::NATARS_CAPITAL_UNITS);
|
||||
//Check if the villages aren't already taken
|
||||
$wid = $database->getFreeVillage($possibleWids);
|
||||
|
||||
$wid = $database->generateVillages(
|
||||
[['wid' => $wid, 'mode' => 2, 'type' => 3, 'kid' => 0, 'capital' => 1, 'pop' => 1163, 'name' => null, 'natar' => 0]],
|
||||
self::NATARS_UID,
|
||||
TRIBE5,
|
||||
$capitalUnits,
|
||||
$capitalBuildings
|
||||
);
|
||||
//Generate the Natars' capital
|
||||
//
|
||||
// The capital starts with the World Wonder and the infrastructure defined
|
||||
// in NATARS_CAPITAL_BUILDINGS. The data is passed in the same format used
|
||||
// for World Wonder villages: [0] = column names, [1][] = values.
|
||||
$capitalBuildings = [];
|
||||
$capitalBuildings[0] = array_keys(self::NATARS_CAPITAL_BUILDINGS);
|
||||
$capitalBuildings[1][] = array_values(self::NATARS_CAPITAL_BUILDINGS);
|
||||
|
||||
// The capital army, using the same format as World Wonder villages:
|
||||
// [0] = column names, [1][] = values.
|
||||
$capitalUnits = [];
|
||||
$capitalUnits[0] = array_keys(self::NATARS_CAPITAL_UNITS);
|
||||
$capitalUnits[1][] = array_values(self::NATARS_CAPITAL_UNITS);
|
||||
|
||||
$wid = $database->generateVillages(
|
||||
[['wid' => $wid, 'mode' => 2, 'type' => 3, 'kid' => 0, 'capital' => 1, 'pop' => 1163, 'name' => null, 'natar' => 0]],
|
||||
self::NATARS_UID,
|
||||
TRIBE5,
|
||||
$capitalUnits,
|
||||
$capitalBuildings
|
||||
);
|
||||
}
|
||||
|
||||
//Scouts all players
|
||||
//NOTE: if this retry path is taken (capital already existed), players
|
||||
//get scouted again - harmless duplicate espionage reports, not data
|
||||
//corruption. Only reachable if a prior run died after building the
|
||||
//capital but before finishing artifact spawning below.
|
||||
$this->scoutAllPlayers($wid);
|
||||
|
||||
//Add artifacts
|
||||
|
||||
@@ -31,6 +31,27 @@ trait DatabaseUserQueries {
|
||||
$time = time();
|
||||
$access = USER;
|
||||
|
||||
// Idempotency guard for pre-assigned IDs (system accounts such as
|
||||
// Natars, uid=3, called from Artifacts::createNatars()). Regular
|
||||
// player registration always passes uid=0, so this branch never
|
||||
// runs for it. It exists because createNatars() is not wrapped in
|
||||
// a transaction: if it registers the Natars row but then dies
|
||||
// further down (village/scout/artifact generation), every retry
|
||||
// used to hit this INSERT again and throw an uncaught
|
||||
// "Duplicate entry '3' for key PRIMARY" mysqli_sql_exception,
|
||||
// fatal on every cron tick and page-load fallback. Detect the
|
||||
// existing row and hand its id back instead of re-inserting.
|
||||
if ($uid > 0) {
|
||||
$existing = $this->dblink->prepare("SELECT id FROM `".TB_PREFIX."users` WHERE id = ? LIMIT 1");
|
||||
$existing->bind_param("i", $uid);
|
||||
$existing->execute();
|
||||
$existingRow = $existing->get_result()->fetch_assoc();
|
||||
$existing->close();
|
||||
if ($existingRow) {
|
||||
return (int)$existingRow['id'];
|
||||
}
|
||||
}
|
||||
|
||||
// New accounts inherit the configured server language.
|
||||
// English remains the safe fallback if SERVER_LANG is missing or invalid.
|
||||
$serverLang = defined('SERVER_LANG')
|
||||
@@ -902,4 +923,4 @@ trait DatabaseUserQueries {
|
||||
}
|
||||
return empty($errors) ? true : $errors;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -120,7 +120,7 @@ define("START_TIME", "%SSTARTTIME%");
|
||||
// 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
|
||||
// Per-user language : 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.
|
||||
|
||||
Reference in New Issue
Block a user