From 6b64f6f8ed81f90df31c71db72650afad43141ad Mon Sep 17 00:00:00 2001 From: hided62 Date: Sat, 25 Jul 2026 17:20:09 +0000 Subject: [PATCH] Add nation level monthly comparison fixture --- .../fixtures/monthly_update_nation_level.json | 85 +++++++++++++++++++ hwe/compare/monthly_event_trace.php | 82 ++++++++++++++++-- 2 files changed, 159 insertions(+), 8 deletions(-) create mode 100644 hwe/compare/fixtures/monthly_update_nation_level.json diff --git a/hwe/compare/fixtures/monthly_update_nation_level.json b/hwe/compare/fixtures/monthly_update_nation_level.json new file mode 100644 index 00000000..b8a679c5 --- /dev/null +++ b/hwe/compare/fixtures/monthly_update_nation_level.json @@ -0,0 +1,85 @@ +{ + "action": "UpdateNationLevel", + "environment": { + "year": 193, + "month": 2, + "startyear": 190, + "killturn": 1000, + "turnterm": 10 + }, + "setup": { + "resetCities": true, + "resetGenerals": true, + "resetUniqueOccupancy": true, + "syncEnvironment": true, + "clearNationTurnIds": [1], + "clearInheritanceOwnerIds": [990061], + "nation": [ + { + "id": 1, + "values": { + "name": "작위검증국", + "color": "#777777", + "capital": 1, + "gold": 10000, + "rice": 20000, + "level": 0, + "type": "che_중립", + "aux": {} + } + } + ], + "city": [ + { + "id": 1, + "values": { + "nation": 1, + "level": 4 + } + }, + { + "id": 2, + "values": { + "nation": 1, + "level": 4 + } + } + ], + "general": [ + { + "id": 1, + "values": { + "name": "조조", + "nation": 1, + "city": 1, + "officer_level": 12, + "owner": 990061, + "npc": 0, + "killturn": 1000, + "belong": 10, + "horse": "None", + "weapon": "None", + "book": "None", + "item": "None", + "aux": {} + } + }, + { + "id": 2, + "values": { + "nation": 0, + "city": 2, + "officer_level": 1, + "npc": 0, + "killturn": 0 + } + } + ] + }, + "observe": { + "generalIds": [1], + "cityIds": [1, 2], + "nationIds": [1], + "ownerIds": [990061] + } +} diff --git a/hwe/compare/monthly_event_trace.php b/hwe/compare/monthly_event_trace.php index d00ba15c..1d175340 100644 --- a/hwe/compare/monthly_event_trace.php +++ b/hwe/compare/monthly_event_trace.php @@ -31,13 +31,14 @@ function comparisonMonthlyPatch(string $table, int $id, array $values): void ], 'nation' => [ 'idColumn' => 'nation', - 'allowed' => ['name', 'color', 'capital', 'gold', 'rice', 'level', 'type'], + 'allowed' => ['name', 'color', 'capital', 'gold', 'rice', 'level', 'type', 'aux'], ], 'general' => [ 'idColumn' => 'no', 'allowed' => [ 'name', 'nation', 'city', 'officer_level', 'officer_city', - 'crew', 'train', 'atmos', + 'crew', 'train', 'atmos', 'owner', 'npc', 'killturn', 'belong', + 'horse', 'weapon', 'book', 'item', 'aux', ], ], ]; @@ -50,7 +51,7 @@ function comparisonMonthlyPatch(string $table, int $id, array $values): void if (!is_string($key) || !in_array($key, $definition['allowed'], true)) { throw new \InvalidArgumentException("unsupported {$table} setup field"); } - if (in_array($key, ['conflict'], true) && is_array($value)) { + if (in_array($key, ['conflict', 'aux'], true) && is_array($value)) { $value = json_encode($value, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE); } $patch[$key] = $value; @@ -125,10 +126,23 @@ function comparisonMonthlyDetails(array $observe, int $worldHistoryAfterId): arr $worldHistoryAfterId, ), ); + $inheritancePoints = []; + foreach (comparisonIntegerList($observe['ownerIds'] ?? [], 'ownerIds') as $ownerId) { + $value = $db->queryFirstField( + 'SELECT value FROM storage WHERE namespace = %s AND `key` = %s', + "inheritance_{$ownerId}", + 'unifier', + ); + $inheritancePoints[] = [ + 'ownerId' => $ownerId, + 'unifier' => $value === null ? 0 : (comparisonJsonValue($value)[0] ?? 0), + ]; + } return [ 'generals' => $generals, 'cities' => $cities, 'worldHistory' => $worldHistory, + 'inheritancePoints' => $inheritancePoints, ]; } @@ -140,7 +154,8 @@ function comparisonMonthlyEventTraceMain(): void if (!is_array($request)) { throw new \InvalidArgumentException('request must be an object'); } - if (($request['action'] ?? null) !== 'UpdateCitySupply') { + $actionName = $request['action'] ?? null; + if (!in_array($actionName, ['UpdateCitySupply', 'UpdateNationLevel'], true)) { throw new \InvalidArgumentException('unsupported monthly action'); } $setup = $request['setup'] ?? []; @@ -159,6 +174,34 @@ function comparisonMonthlyEventTraceMain(): void comparisonMonthlyPatch($table, $row['id'], $row['values']); } } + if (($setup['resetCities'] ?? false) === true) { + DB::db()->query('UPDATE city SET nation = 0, level = 1'); + foreach ($setup['city'] ?? [] as $row) { + comparisonMonthlyPatch('city', $row['id'], $row['values']); + } + } + if (($setup['resetGenerals'] ?? false) === true) { + DB::db()->query( + 'UPDATE general SET nation = 0, officer_level = 1, npc = 2, killturn = 0, horse = %s, weapon = %s, book = %s, item = %s', + 'None', + 'None', + 'None', + 'None', + ); + foreach ($setup['general'] ?? [] as $row) { + comparisonMonthlyPatch('general', $row['id'], $row['values']); + } + } + if (($setup['resetUniqueOccupancy'] ?? false) === true) { + DB::db()->delete('ng_auction', '`type` = %s AND finished = 0', 'uniqueItem'); + DB::db()->query('DELETE FROM storage WHERE namespace LIKE %s', 'ut\\_%'); + } + foreach (comparisonIntegerList($setup['clearNationTurnIds'] ?? [], 'clearNationTurnIds') as $nationId) { + DB::db()->delete('nation_turn', 'nation_id = %i', $nationId); + } + foreach (comparisonIntegerList($setup['clearInheritanceOwnerIds'] ?? [], 'clearInheritanceOwnerIds') as $ownerId) { + DB::db()->delete('storage', 'namespace = %s', "inheritance_{$ownerId}"); + } $db = DB::db(); $snapshotRequest = ['observe' => $request['observe'] ?? []]; @@ -179,13 +222,36 @@ function comparisonMonthlyEventTraceMain(): void if (!is_int($year) || !is_int($month) || !is_int($startYear)) { throw new \InvalidArgumentException('environment year, month, and startyear must be integers'); } + if (($setup['syncEnvironment'] ?? false) === true) { + $gameStorage = KVStorage::getStorage(DB::db(), 'game_env'); + foreach ([ + 'year' => $year, + 'month' => $month, + 'startyear' => $startYear, + 'killturn' => $environment['killturn'] ?? $gameStorage->killturn, + 'turnterm' => $environment['turnterm'] ?? $gameStorage->turnterm, + ] as $key => $value) { + $gameStorage->setValue($key, $value); + } + } - $action = new Event\Action\UpdateCitySupply(); - $action->run([ + $actionClass = "\\sammo\\Event\\Action\\{$actionName}"; + $action = new $actionClass(); + $actionEnvironment = [ 'year' => $year, 'month' => $month, 'startyear' => $startYear, - ]); + ]; + if ($actionName === 'UpdateNationLevel') { + $killturn = $environment['killturn'] ?? null; + $turnterm = $environment['turnterm'] ?? null; + if (!is_int($killturn) || !is_int($turnterm) || $turnterm <= 0) { + throw new \InvalidArgumentException('UpdateNationLevel requires integer killturn and positive turnterm'); + } + $actionEnvironment['killturn'] = $killturn; + $actionEnvironment['turnterm'] = $turnterm; + } + $action->run($actionEnvironment); unset($action); gc_collect_cycles(); @@ -195,7 +261,7 @@ function comparisonMonthlyEventTraceMain(): void [ 'schemaVersion' => 1, 'engine' => 'ref', - 'action' => 'UpdateCitySupply', + 'action' => $actionName, 'before' => $before, 'beforeDetails' => $beforeDetails, 'after' => $after,