diff --git a/hwe/compare/fixtures/monthly_pre_update.json b/hwe/compare/fixtures/monthly_pre_update.json new file mode 100644 index 00000000..26d97f8f --- /dev/null +++ b/hwe/compare/fixtures/monthly_pre_update.json @@ -0,0 +1,49 @@ +{ + "action": "PreUpdateMonthly", + "environment": { + "year": 200, + "month": 12, + "startyear": 190 + }, + "setup": { + "syncEnvironment": true, + "resetGenerals": true, + "deleteOtherGenerals": true, + "keepGeneralIds": [1, 2], + "general": [ + {"id": 1, "values": {"makelimit": 2}}, + {"id": 2, "values": {"makelimit": 0}} + ], + "generalAccessLog": [ + {"generalId": 1, "refreshScoreTotal": 101}, + {"generalId": 2, "refreshScoreTotal": 1} + ], + "nation": [ + { + "id": 1, + "values": { + "rate": 35, + "rate_tmp": 10, + "strategic_cmd_limit": 2, + "surlimit": 1, + "spy": "{\"1\":1,\"2\":2}" + } + } + ], + "city": [ + {"id": 1, "values": {"state": 31, "term": 1, "conflict": {"1": 10}}}, + {"id": 2, "values": {"state": 32, "term": 2, "conflict": {"1": 20}}}, + {"id": 3, "values": {"state": 33, "term": 0, "conflict": {"1": 30}}}, + {"id": 4, "values": {"state": 34, "term": 3, "conflict": {"1": 40}}}, + {"id": 5, "values": {"state": 41, "term": 1, "conflict": {"1": 50}}}, + {"id": 6, "values": {"state": 42, "term": 2, "conflict": {"1": 60}}}, + {"id": 7, "values": {"state": 43, "term": 3, "conflict": {"1": 70}}} + ] + }, + "observe": { + "generalIds": [1, 2], + "nationIds": [1], + "cityIds": [1, 2, 3, 4, 5, 6, 7], + "accessGeneralIds": [1, 2] + } +} diff --git a/hwe/compare/monthly_event_trace.php b/hwe/compare/monthly_event_trace.php index 46346b5f..f76b55e0 100644 --- a/hwe/compare/monthly_event_trace.php +++ b/hwe/compare/monthly_event_trace.php @@ -34,6 +34,7 @@ function comparisonMonthlyPatch(string $table, int $id, array $values): void 'allowed' => [ 'name', 'color', 'capital', 'gennum', 'gold', 'rice', 'tech', 'power', 'level', 'type', 'rate_tmp', 'scout', 'aux', + 'rate', 'strategic_cmd_limit', 'surlimit', 'spy', ], ], 'general' => [ @@ -45,7 +46,7 @@ function comparisonMonthlyPatch(string $table, int $id, array $values): void 'leadership', 'strength', 'intel', 'experience', 'dedication', 'dex1', 'dex2', 'dex3', 'dex4', 'dex5', 'personal', 'special', 'specage', 'special2', 'specage2', 'betray', 'age', - 'bornyear', 'deadyear', 'turntime', + 'bornyear', 'deadyear', 'turntime', 'makelimit', ], ], ]; @@ -108,6 +109,7 @@ function comparisonMonthlyDetails(array $observe, int $worldHistoryAfterId): arr 'specialWar' => 'special2', 'specAge2' => 'specage2', 'betray' => 'betray', + 'makeLimit' => 'makelimit', 'horse' => 'horse', 'weapon' => 'weapon', 'book' => 'book', @@ -129,6 +131,7 @@ function comparisonMonthlyDetails(array $observe, int $worldHistoryAfterId): arr [ 'id' => 'city', 'nationId' => 'nation', + 'state' => 'state', 'supplyState' => 'supply', 'frontState' => 'front', 'officerSet' => 'officer_set', @@ -162,9 +165,14 @@ function comparisonMonthlyDetails(array $observe, int $worldHistoryAfterId): arr 'gold' => 'gold', 'rice' => 'rice', 'rate' => 'rate_tmp', + 'baseRate' => 'rate', 'typeCode' => 'type', 'scout' => 'scout', + 'strategicCommandLimit' => 'strategic_cmd_limit', + 'surrenderLimit' => 'surlimit', + 'spy' => 'spy', ], + ['spy'], ), comparisonRowsById('nation', 'nation', comparisonIntegerList($observe['nationIds'] ?? [], 'nationIds')), ); @@ -213,6 +221,14 @@ function comparisonMonthlyDetails(array $observe, int $worldHistoryAfterId): arr $rankGeneralIds, $rankTypes, )); + $generalAccessLogs = []; + $accessGeneralIds = comparisonIntegerList($observe['accessGeneralIds'] ?? [], 'accessGeneralIds'); + if ($accessGeneralIds) { + $generalAccessLogs = iterator_to_array($db->query( + 'SELECT general_id AS generalId, refresh_score_total AS refreshScoreTotal FROM general_access_log WHERE general_id IN %li ORDER BY general_id', + $accessGeneralIds, + )); + } return [ 'generals' => $generals, 'cities' => $cities, @@ -220,6 +236,7 @@ function comparisonMonthlyDetails(array $observe, int $worldHistoryAfterId): arr 'worldHistory' => $worldHistory, 'inheritancePoints' => $inheritancePoints, 'rankData' => $rankData, + 'generalAccessLogs' => $generalAccessLogs, ]; } @@ -255,6 +272,7 @@ function comparisonMonthlyEventTraceMain(): void 'AddGlobalBetray', 'LostUniqueItem', 'MergeInheritPointRank', + 'PreUpdateMonthly', ]; if (!in_array($actionName, $supportedActions, true)) { throw new \InvalidArgumentException('unsupported monthly action'); @@ -407,6 +425,21 @@ function comparisonMonthlyEventTraceMain(): void 'value' => $row['value'], ]); } + foreach ($setup['generalAccessLog'] ?? [] as $row) { + if ( + !is_array($row) + || !is_int($row['generalId'] ?? null) + || !is_int($row['refreshScoreTotal'] ?? null) + ) { + throw new \InvalidArgumentException('invalid setup.generalAccessLog row'); + } + DB::db()->insertUpdate('general_access_log', [ + 'general_id' => $row['generalId'], + 'refresh_score_total' => $row['refreshScoreTotal'], + ], [ + 'refresh_score_total' => $row['refreshScoreTotal'], + ]); + } if (($setup['resetDiplomacy'] ?? false) === true) { DB::db()->query('DELETE FROM diplomacy'); } @@ -497,7 +530,9 @@ function comparisonMonthlyEventTraceMain(): void } $actionClass = "\\sammo\\Event\\Action\\{$actionName}"; - if ($actionName === 'ProcessSemiAnnual') { + if ($actionName === 'PreUpdateMonthly') { + $action = null; + } elseif ($actionName === 'ProcessSemiAnnual') { $resource = $request['resource'] ?? null; if (!is_string($resource)) { throw new \InvalidArgumentException('ProcessSemiAnnual requires resource'); @@ -581,7 +616,13 @@ function comparisonMonthlyEventTraceMain(): void 'fiction' => $fiction, ]; } - $action->run($actionEnvironment); + if ($actionName === 'PreUpdateMonthly') { + if (!preUpdateMonthly()) { + throw new \RuntimeException('preUpdateMonthly failed'); + } + } else { + $action->run($actionEnvironment); + } unset($action); gc_collect_cycles(); @@ -713,6 +754,11 @@ function comparisonMonthlyEventTraceMain(): void 'lastNPCTroopLeaderID', ]); } + if ($actionName === 'PreUpdateMonthly') { + $response['gameEnvironment'] = KVStorage::getStorage(DB::db(), 'game_env')->getValues([ + 'develcost', + ]); + } if (in_array($actionName, ['OpenNationBetting', 'FinishNationBetting'], true)) { $bettingStorage = KVStorage::getStorage(DB::db(), 'betting'); $response['betting'] = $bettingStorage->getAll();