140 lines
5.9 KiB
PHP
140 lines
5.9 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace sammo;
|
|
|
|
if (PHP_SAPI !== 'cli' || getenv('REF_DETERMINISTIC_INSTALL_ENABLED') !== '1') {
|
|
http_response_code(404);
|
|
exit(1);
|
|
}
|
|
|
|
chdir(dirname(__DIR__));
|
|
require_once 'lib.php';
|
|
require_once 'func.php';
|
|
|
|
/** @return mixed */
|
|
function monthlySnapshotJson(mixed $value): mixed
|
|
{
|
|
if (!is_string($value) || $value === '') {
|
|
return $value;
|
|
}
|
|
try {
|
|
return json_decode($value, true, flags: JSON_THROW_ON_ERROR);
|
|
} catch (\JsonException) {
|
|
return $value;
|
|
}
|
|
}
|
|
|
|
/** @return array<string, mixed> */
|
|
function monthlySnapshotPick(array $row, array $mapping, array $jsonColumns = []): array
|
|
{
|
|
$result = [];
|
|
foreach ($mapping as $target => $source) {
|
|
$value = $row[$source] ?? null;
|
|
$result[$target] = in_array($source, $jsonColumns, true)
|
|
? monthlySnapshotJson($value)
|
|
: $value;
|
|
}
|
|
return $result;
|
|
}
|
|
|
|
$db = DB::db();
|
|
$game = KVStorage::getStorage($db, 'game_env');
|
|
$game->resetCache();
|
|
$clock = GameClock::fromStorage($game);
|
|
$world = $game->getValues([
|
|
'scenario', 'year', 'month', 'turnterm', 'turntime', 'starttime',
|
|
'init_year', 'init_month', 'develcost', 'killturn', 'isunited',
|
|
]);
|
|
$world['turntime'] = $clock->formatTick(Util::toInt($world['turntime']), true);
|
|
$world['starttime'] = $clock->formatTick(Util::toInt($world['starttime']), true);
|
|
|
|
$generals = [];
|
|
foreach ($db->query('SELECT * FROM general ORDER BY no') as $row) {
|
|
$general = monthlySnapshotPick($row, [
|
|
'id' => 'no', 'name' => 'name', 'nationId' => 'nation', 'cityId' => 'city',
|
|
'troopId' => 'troop', 'leadership' => 'leadership', 'strength' => 'strength',
|
|
'intelligence' => 'intel', 'experience' => 'experience', 'experienceLevel' => 'explevel',
|
|
'dedication' => 'dedication', 'dedicationLevel' => 'dedlevel',
|
|
'leadershipExp' => 'leadership_exp', 'strengthExp' => 'strength_exp', 'intelligenceExp' => 'intel_exp',
|
|
'officerLevel' => 'officer_level', 'injury' => 'injury', 'gold' => 'gold',
|
|
'rice' => 'rice', 'crew' => 'crew', 'crewTypeId' => 'crewtype', 'train' => 'train',
|
|
'atmos' => 'atmos', 'age' => 'age', 'npcState' => 'npc', 'turnTime' => 'turntime',
|
|
'recentWarTime' => 'recent_war', 'lastTurn' => 'last_turn', 'meta' => 'aux',
|
|
'affinity' => 'affinity', 'birthYear' => 'bornyear', 'deathYear' => 'deadyear',
|
|
'personality' => 'personal', 'specialDomestic' => 'special', 'specialWar' => 'special2',
|
|
'specAge' => 'specage', 'specAge2' => 'specage2',
|
|
'dex1' => 'dex1', 'dex2' => 'dex2', 'dex3' => 'dex3', 'dex4' => 'dex4', 'dex5' => 'dex5',
|
|
'killTurn' => 'killturn',
|
|
], ['last_turn', 'aux']);
|
|
foreach (['id', 'nationId', 'cityId', 'troopId', 'leadership', 'strength', 'intelligence',
|
|
'experience', 'experienceLevel', 'dedication', 'dedicationLevel', 'leadershipExp',
|
|
'strengthExp', 'intelligenceExp', 'officerLevel', 'injury', 'gold', 'rice', 'crew',
|
|
'crewTypeId', 'train', 'atmos', 'age', 'npcState', 'dex1', 'dex2', 'dex3',
|
|
'dex4', 'dex5', 'killTurn', 'affinity', 'birthYear', 'deathYear', 'specAge', 'specAge2'] as $key) {
|
|
$general[$key] = (int)$general[$key];
|
|
}
|
|
$general['turnTime'] = $clock->formatTick(Util::toInt($general['turnTime']), true);
|
|
$general['recentWarTime'] = $general['recentWarTime'] === null
|
|
? null
|
|
: $clock->formatTick(Util::toInt($general['recentWarTime']), true);
|
|
$generals[] = $general;
|
|
}
|
|
|
|
$cities = [];
|
|
foreach ($db->query('SELECT * FROM city ORDER BY city') as $row) {
|
|
$city = monthlySnapshotPick($row, [
|
|
'id' => 'city', 'name' => 'name', 'nationId' => 'nation', 'level' => 'level',
|
|
'population' => 'pop', 'populationMax' => 'pop_max', 'agriculture' => 'agri',
|
|
'agricultureMax' => 'agri_max', 'commerce' => 'comm', 'commerceMax' => 'comm_max',
|
|
'security' => 'secu', 'securityMax' => 'secu_max', 'supplyState' => 'supply',
|
|
'frontState' => 'front', 'defence' => 'def', 'defenceMax' => 'def_max',
|
|
'wall' => 'wall', 'wallMax' => 'wall_max', 'state' => 'state', 'term' => 'term',
|
|
'trust' => 'trust', 'trade' => 'trade', 'conflict' => 'conflict',
|
|
], ['conflict']);
|
|
foreach (array_keys($city) as $key) {
|
|
if ($key !== 'name' && $key !== 'conflict' && $key !== 'trust') {
|
|
$city[$key] = (int)$city[$key];
|
|
}
|
|
}
|
|
$cities[] = $city;
|
|
}
|
|
|
|
$nations = [];
|
|
foreach ($db->query('SELECT * FROM nation ORDER BY nation') as $row) {
|
|
$nation = monthlySnapshotPick($row, [
|
|
'id' => 'nation', 'name' => 'name', 'color' => 'color', 'capitalCityId' => 'capital',
|
|
'gold' => 'gold', 'rice' => 'rice', 'tech' => 'tech', 'level' => 'level',
|
|
'typeCode' => 'type', 'generalCount' => 'gennum', 'power' => 'power',
|
|
'war' => 'war', 'diplomacyLimit' => 'surlimit', 'capitalRevision' => 'capset',
|
|
'strategicCommandLimit' => 'strategic_cmd_limit', 'rate' => 'rate',
|
|
'rateTmp' => 'rate_tmp', 'bill' => 'bill', 'meta' => 'aux',
|
|
], ['aux']);
|
|
foreach (['id', 'capitalCityId', 'gold', 'rice', 'level', 'generalCount',
|
|
'power', 'war', 'diplomacyLimit', 'capitalRevision', 'strategicCommandLimit',
|
|
'rate', 'rateTmp', 'bill'] as $key) {
|
|
$nation[$key] = (int)$nation[$key];
|
|
}
|
|
$nation['tech'] = (float)$nation['tech'];
|
|
$nations[] = $nation;
|
|
}
|
|
|
|
$diplomacy = [];
|
|
foreach ($db->query('SELECT me, you, state, term, dead FROM diplomacy ORDER BY me, you') as $row) {
|
|
$diplomacy[] = [
|
|
'fromNationId' => (int)$row['me'], 'toNationId' => (int)$row['you'],
|
|
'state' => (int)$row['state'], 'term' => (int)$row['term'], 'dead' => (int)$row['dead'],
|
|
];
|
|
}
|
|
|
|
echo json_encode([
|
|
'schemaVersion' => 1,
|
|
'engine' => 'ref',
|
|
'world' => $world,
|
|
'generals' => $generals,
|
|
'cities' => $cities,
|
|
'nations' => $nations,
|
|
'diplomacy' => $diplomacy,
|
|
], JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRESERVE_ZERO_FRACTION), PHP_EOL;
|