merge: add nation level monthly comparison fixture

This commit is contained in:
2026-07-25 17:20:17 +00:00
2 changed files with 159 additions and 8 deletions
@@ -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]
}
}
+74 -8
View File
@@ -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,