merge: trace monthly invader lifecycle
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"action": "AutoDeleteInvader",
|
||||
"compactOutput": true,
|
||||
"args": [1],
|
||||
"setup": {
|
||||
"resetGenerals": true,
|
||||
"deleteOtherGenerals": true,
|
||||
"keepGeneralIds": [1],
|
||||
"resetNations": true,
|
||||
"deleteOtherNations": true,
|
||||
"keepNationIds": [1],
|
||||
"resetDiplomacy": true,
|
||||
"nation": [
|
||||
{
|
||||
"id": 1,
|
||||
"values": {
|
||||
"name": "ⓞ남만족",
|
||||
"capital": 69,
|
||||
"gennum": 1,
|
||||
"tech": 100,
|
||||
"level": 2,
|
||||
"type": "che_병가"
|
||||
}
|
||||
}
|
||||
],
|
||||
"general": [
|
||||
{
|
||||
"id": 1,
|
||||
"values": {
|
||||
"name": "ⓞ남만대왕",
|
||||
"nation": 1,
|
||||
"city": 69,
|
||||
"officer_level": 12,
|
||||
"npc": 9
|
||||
}
|
||||
}
|
||||
],
|
||||
"event": [
|
||||
{
|
||||
"id": 990001,
|
||||
"action": [["AutoDeleteInvader", 1]]
|
||||
}
|
||||
]
|
||||
},
|
||||
"environment": {
|
||||
"year": 200,
|
||||
"month": 1,
|
||||
"startyear": 190,
|
||||
"currentEventID": 990001
|
||||
},
|
||||
"observe": {
|
||||
"generalIds": [1]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"action": "InvaderEnding",
|
||||
"compactOutput": true,
|
||||
"setup": {
|
||||
"resetNations": true,
|
||||
"deleteOtherNations": true,
|
||||
"keepNationIds": [1],
|
||||
"setAllCitiesNation": 1,
|
||||
"nation": [
|
||||
{
|
||||
"id": 1,
|
||||
"values": {
|
||||
"name": "기준국",
|
||||
"capital": 1,
|
||||
"gennum": 1,
|
||||
"tech": 100,
|
||||
"level": 2,
|
||||
"type": "che_유가"
|
||||
}
|
||||
}
|
||||
],
|
||||
"gameEnvironment": {
|
||||
"isunited": 1,
|
||||
"refreshLimit": 3
|
||||
},
|
||||
"event": [
|
||||
{
|
||||
"id": 990002,
|
||||
"action": [["InvaderEnding"]]
|
||||
}
|
||||
]
|
||||
},
|
||||
"environment": {
|
||||
"year": 200,
|
||||
"month": 1,
|
||||
"startyear": 190,
|
||||
"currentEventID": 990002
|
||||
},
|
||||
"observe": {}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
{
|
||||
"action": "RaiseInvader",
|
||||
"compactOutput": true,
|
||||
"args": [10, 150, 100, 20],
|
||||
"setup": {
|
||||
"resetCities": true,
|
||||
"resetGenerals": true,
|
||||
"deleteOtherGenerals": true,
|
||||
"keepGeneralIds": [1],
|
||||
"resetNations": true,
|
||||
"deleteOtherNations": true,
|
||||
"keepNationIds": [1],
|
||||
"city": [
|
||||
{
|
||||
"id": 1,
|
||||
"values": {
|
||||
"level": 3,
|
||||
"nation": 1,
|
||||
"pop": 1000,
|
||||
"pop_max": 10000,
|
||||
"agri": 2000,
|
||||
"agri_max": 20000,
|
||||
"comm": 3000,
|
||||
"comm_max": 30000,
|
||||
"secu": 4000,
|
||||
"secu_max": 40000,
|
||||
"def": 5000,
|
||||
"def_max": 50000,
|
||||
"wall": 6000,
|
||||
"wall_max": 60000
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 48,
|
||||
"values": {
|
||||
"level": 4,
|
||||
"nation": 0,
|
||||
"pop": 1000,
|
||||
"pop_max": 10000,
|
||||
"agri": 2000,
|
||||
"agri_max": 20000,
|
||||
"comm": 3000,
|
||||
"comm_max": 30000,
|
||||
"secu": 4000,
|
||||
"secu_max": 40000,
|
||||
"def": 5000,
|
||||
"def_max": 50000,
|
||||
"wall": 6000,
|
||||
"wall_max": 60000
|
||||
}
|
||||
}
|
||||
],
|
||||
"nation": [
|
||||
{
|
||||
"id": 1,
|
||||
"values": {
|
||||
"name": "기준국",
|
||||
"capital": 1,
|
||||
"gennum": 1,
|
||||
"tech": 100,
|
||||
"level": 2,
|
||||
"type": "che_유가"
|
||||
}
|
||||
}
|
||||
],
|
||||
"general": [
|
||||
{
|
||||
"id": 1,
|
||||
"values": {
|
||||
"name": "군주",
|
||||
"nation": 1,
|
||||
"city": 1,
|
||||
"officer_level": 12,
|
||||
"npc": 0,
|
||||
"leadership": 50,
|
||||
"strength": 50,
|
||||
"intel": 50,
|
||||
"experience": 1000,
|
||||
"dedication": 1000,
|
||||
"dex1": 10,
|
||||
"dex2": 20,
|
||||
"dex3": 30,
|
||||
"dex4": 40,
|
||||
"dex5": 50,
|
||||
"turntime": "0200-01-01 00:05:00"
|
||||
}
|
||||
}
|
||||
],
|
||||
"syncEnvironment": true
|
||||
},
|
||||
"environment": {
|
||||
"year": 200,
|
||||
"month": 1,
|
||||
"startyear": 190,
|
||||
"turnterm": 10,
|
||||
"turntime": "0200-01-01 00:00:00",
|
||||
"show_img_level": 3,
|
||||
"fiction": [0]
|
||||
},
|
||||
"observe": {
|
||||
"generalIds": [1],
|
||||
"cityIds": [1, 48],
|
||||
"nationIds": [1]
|
||||
}
|
||||
}
|
||||
@@ -42,6 +42,9 @@ function comparisonMonthlyPatch(string $table, int $id, array $values): void
|
||||
'name', 'nation', 'city', 'officer_level', 'officer_city',
|
||||
'crew', 'train', 'atmos', 'owner', 'npc', 'killturn', 'belong',
|
||||
'gold', 'rice', 'horse', 'weapon', 'book', 'item', 'aux',
|
||||
'leadership', 'strength', 'intel', 'experience', 'dedication',
|
||||
'dex1', 'dex2', 'dex3', 'dex4', 'dex5', 'personal', 'special',
|
||||
'special2', 'bornyear', 'deadyear', 'turntime',
|
||||
],
|
||||
],
|
||||
];
|
||||
@@ -192,6 +195,9 @@ function comparisonMonthlyEventTraceMain(): void
|
||||
'RegNPC',
|
||||
'RegNeutralNPC',
|
||||
'RaiseNPCNation',
|
||||
'RaiseInvader',
|
||||
'AutoDeleteInvader',
|
||||
'InvaderEnding',
|
||||
];
|
||||
if (!in_array($actionName, $supportedActions, true)) {
|
||||
throw new \InvalidArgumentException('unsupported monthly action');
|
||||
@@ -230,12 +236,34 @@ function comparisonMonthlyEventTraceMain(): void
|
||||
comparisonMonthlyPatch('general', $row['id'], $row['values']);
|
||||
}
|
||||
}
|
||||
if (($setup['deleteOtherGenerals'] ?? false) === true) {
|
||||
$keepGeneralIds = comparisonIntegerList($setup['keepGeneralIds'] ?? [], 'keepGeneralIds');
|
||||
if (!$keepGeneralIds) {
|
||||
throw new \InvalidArgumentException('deleteOtherGenerals requires keepGeneralIds');
|
||||
}
|
||||
DB::db()->query('DELETE FROM general_turn WHERE general_id NOT IN %li', $keepGeneralIds);
|
||||
DB::db()->query('DELETE FROM rank_data WHERE general_id NOT IN %li', $keepGeneralIds);
|
||||
DB::db()->query('DELETE FROM general WHERE no NOT IN %li', $keepGeneralIds);
|
||||
}
|
||||
if (($setup['resetNations'] ?? false) === true) {
|
||||
DB::db()->query('UPDATE nation SET level = 0, gennum = 0, tech = 0');
|
||||
foreach ($setup['nation'] ?? [] as $row) {
|
||||
comparisonMonthlyPatch('nation', $row['id'], $row['values']);
|
||||
}
|
||||
}
|
||||
if (($setup['deleteOtherNations'] ?? false) === true) {
|
||||
$keepNationIds = comparisonIntegerList($setup['keepNationIds'] ?? [], 'keepNationIds');
|
||||
if (!$keepNationIds) {
|
||||
throw new \InvalidArgumentException('deleteOtherNations requires keepNationIds');
|
||||
}
|
||||
DB::db()->query(
|
||||
'DELETE FROM diplomacy WHERE me NOT IN %li OR you NOT IN %li',
|
||||
$keepNationIds,
|
||||
$keepNationIds,
|
||||
);
|
||||
DB::db()->query('DELETE FROM nation_turn WHERE nation_id NOT IN %li', $keepNationIds);
|
||||
DB::db()->query('DELETE FROM nation WHERE nation NOT IN %li', $keepNationIds);
|
||||
}
|
||||
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\\_%');
|
||||
@@ -246,12 +274,64 @@ function comparisonMonthlyEventTraceMain(): void
|
||||
foreach (comparisonIntegerList($setup['clearInheritanceOwnerIds'] ?? [], 'clearInheritanceOwnerIds') as $ownerId) {
|
||||
DB::db()->delete('storage', 'namespace = %s', "inheritance_{$ownerId}");
|
||||
}
|
||||
if (($setup['resetDiplomacy'] ?? false) === true) {
|
||||
DB::db()->query('DELETE FROM diplomacy');
|
||||
}
|
||||
foreach ($setup['diplomacy'] ?? [] as $row) {
|
||||
if (
|
||||
!is_array($row)
|
||||
|| !is_int($row['fromNationId'] ?? null)
|
||||
|| !is_int($row['toNationId'] ?? null)
|
||||
|| !is_int($row['state'] ?? null)
|
||||
|| !is_int($row['term'] ?? null)
|
||||
) {
|
||||
throw new \InvalidArgumentException('invalid setup.diplomacy row');
|
||||
}
|
||||
$diplomacyPatch = [
|
||||
'me' => $row['fromNationId'],
|
||||
'you' => $row['toNationId'],
|
||||
'state' => $row['state'],
|
||||
'term' => $row['term'],
|
||||
];
|
||||
DB::db()->insertUpdate('diplomacy', $diplomacyPatch, $diplomacyPatch);
|
||||
}
|
||||
foreach ($setup['event'] ?? [] as $row) {
|
||||
if (!is_array($row) || !is_int($row['id'] ?? null) || !is_array($row['action'] ?? null)) {
|
||||
throw new \InvalidArgumentException('invalid setup.event row');
|
||||
}
|
||||
$eventPatch = [
|
||||
'id' => $row['id'],
|
||||
'target' => $row['target'] ?? 'month',
|
||||
'priority' => $row['priority'] ?? 1000,
|
||||
'condition' => Json::encode($row['condition'] ?? true),
|
||||
'action' => Json::encode($row['action']),
|
||||
];
|
||||
DB::db()->insertUpdate('event', $eventPatch, $eventPatch);
|
||||
}
|
||||
$gameEnvironmentPatch = $setup['gameEnvironment'] ?? [];
|
||||
if (!is_array($gameEnvironmentPatch)) {
|
||||
throw new \InvalidArgumentException('setup.gameEnvironment must be an object');
|
||||
}
|
||||
$gameStorage = KVStorage::getStorage(DB::db(), 'game_env');
|
||||
foreach (['isunited', 'refreshLimit', 'block_change_scout'] as $key) {
|
||||
if (array_key_exists($key, $gameEnvironmentPatch)) {
|
||||
$gameStorage->setValue($key, $gameEnvironmentPatch[$key]);
|
||||
}
|
||||
}
|
||||
if (($setup['setAllCitiesNation'] ?? null) !== null) {
|
||||
if (!is_int($setup['setAllCitiesNation'])) {
|
||||
throw new \InvalidArgumentException('setup.setAllCitiesNation must be an integer');
|
||||
}
|
||||
DB::db()->update('city', ['nation' => $setup['setAllCitiesNation']], true);
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
$generalIdBeforeAction =
|
||||
(int)($db->queryFirstField('SELECT COALESCE(MAX(no), 0) FROM general') ?? 0);
|
||||
$nationIdBeforeAction =
|
||||
(int)($db->queryFirstField('SELECT COALESCE(MAX(nation), 0) FROM nation') ?? 0);
|
||||
$eventIdBeforeAction =
|
||||
(int)($db->queryFirstField('SELECT COALESCE(MAX(id), 0) FROM event') ?? 0);
|
||||
$snapshotRequest = ['observe' => $request['observe'] ?? []];
|
||||
$snapshotRequest['observe']['logAfterId'] =
|
||||
(int)($db->queryFirstField('SELECT COALESCE(MAX(id), 0) FROM general_record') ?? 0);
|
||||
@@ -290,7 +370,7 @@ function comparisonMonthlyEventTraceMain(): void
|
||||
throw new \InvalidArgumentException('ProcessSemiAnnual requires resource');
|
||||
}
|
||||
$action = new $actionClass($resource);
|
||||
} elseif (in_array($actionName, ['CreateManyNPC', 'RegNPC', 'RegNeutralNPC'], true)) {
|
||||
} elseif (in_array($actionName, ['CreateManyNPC', 'RegNPC', 'RegNeutralNPC', 'RaiseInvader', 'AutoDeleteInvader'], true)) {
|
||||
$args = $request['args'] ?? [];
|
||||
if (!is_array($args)) {
|
||||
throw new \InvalidArgumentException("{$actionName} args must be an array");
|
||||
@@ -298,6 +378,9 @@ function comparisonMonthlyEventTraceMain(): void
|
||||
if ($actionName === 'CreateManyNPC' && count($args) > 2) {
|
||||
throw new \InvalidArgumentException('CreateManyNPC args must have at most two entries');
|
||||
}
|
||||
if ($actionName === 'RaiseInvader' && count($args) > 4) {
|
||||
throw new \InvalidArgumentException('RaiseInvader args must have at most four entries');
|
||||
}
|
||||
$action = new $actionClass(...$args);
|
||||
} else {
|
||||
$action = new $actionClass();
|
||||
@@ -307,6 +390,12 @@ function comparisonMonthlyEventTraceMain(): void
|
||||
'month' => $month,
|
||||
'startyear' => $startYear,
|
||||
];
|
||||
if (isset($environment['currentEventID'])) {
|
||||
if (!is_int($environment['currentEventID'])) {
|
||||
throw new \InvalidArgumentException('currentEventID must be an integer');
|
||||
}
|
||||
$actionEnvironment['currentEventID'] = $environment['currentEventID'];
|
||||
}
|
||||
if ($actionName === 'UpdateNationLevel') {
|
||||
$killturn = $environment['killturn'] ?? null;
|
||||
$turnterm = $environment['turnterm'] ?? null;
|
||||
@@ -316,7 +405,7 @@ function comparisonMonthlyEventTraceMain(): void
|
||||
$actionEnvironment['killturn'] = $killturn;
|
||||
$actionEnvironment['turnterm'] = $turnterm;
|
||||
}
|
||||
if (in_array($actionName, ['CreateManyNPC', 'RegNPC', 'RegNeutralNPC', 'RaiseNPCNation'], true)) {
|
||||
if (in_array($actionName, ['CreateManyNPC', 'RegNPC', 'RegNeutralNPC', 'RaiseNPCNation', 'RaiseInvader'], true)) {
|
||||
$turnterm = $environment['turnterm'] ?? null;
|
||||
$turntime = $environment['turntime'] ?? null;
|
||||
$showImgLevel = $environment['show_img_level'] ?? 3;
|
||||
@@ -348,7 +437,7 @@ function comparisonMonthlyEventTraceMain(): void
|
||||
$after = comparisonTurnStateSnapshot($snapshotRequest);
|
||||
$afterDetails = comparisonMonthlyDetails($snapshotRequest['observe'], $worldHistoryAfterId);
|
||||
$createdGenerals = [];
|
||||
if (in_array($actionName, ['CreateManyNPC', 'RegNPC', 'RegNeutralNPC', 'RaiseNPCNation'], true)) {
|
||||
if (in_array($actionName, ['CreateManyNPC', 'RegNPC', 'RegNeutralNPC', 'RaiseNPCNation', 'RaiseInvader'], true)) {
|
||||
foreach ($db->query('SELECT * FROM general WHERE no > %i ORDER BY no', $generalIdBeforeAction) as $row) {
|
||||
$generalId = (int)$row['no'];
|
||||
$turnRows = $db->query(
|
||||
@@ -388,6 +477,11 @@ function comparisonMonthlyEventTraceMain(): void
|
||||
'bornYear' => 'bornyear',
|
||||
'deadYear' => 'deadyear',
|
||||
'picture' => 'picture',
|
||||
'dex1' => 'dex1',
|
||||
'dex2' => 'dex2',
|
||||
'dex3' => 'dex3',
|
||||
'dex4' => 'dex4',
|
||||
'dex5' => 'dex5',
|
||||
],
|
||||
) + [
|
||||
'turnCount' => count($turnRows),
|
||||
@@ -404,7 +498,7 @@ function comparisonMonthlyEventTraceMain(): void
|
||||
}
|
||||
}
|
||||
$createdNations = [];
|
||||
if ($actionName === 'RaiseNPCNation') {
|
||||
if (in_array($actionName, ['RaiseNPCNation', 'RaiseInvader'], true)) {
|
||||
foreach ($db->query('SELECT * FROM nation WHERE nation > %i ORDER BY nation', $nationIdBeforeAction) as $row) {
|
||||
$nationId = (int)$row['nation'];
|
||||
$createdNations[] = comparisonPickRow(
|
||||
@@ -454,10 +548,82 @@ function comparisonMonthlyEventTraceMain(): void
|
||||
if (in_array($actionName, ['CreateManyNPC', 'RegNPC', 'RegNeutralNPC'], true)) {
|
||||
$response['createdGenerals'] = $createdGenerals;
|
||||
}
|
||||
if ($actionName === 'RaiseNPCNation') {
|
||||
if (in_array($actionName, ['RaiseNPCNation', 'RaiseInvader'], true)) {
|
||||
$response['createdGenerals'] = $createdGenerals;
|
||||
$response['createdNations'] = $createdNations;
|
||||
}
|
||||
if ($actionName === 'RaiseInvader') {
|
||||
$response['createdEvents'] = array_map(
|
||||
static fn(array $row): array => comparisonPickRow(
|
||||
$row,
|
||||
[
|
||||
'id' => 'id',
|
||||
'targetCode' => 'target',
|
||||
'priority' => 'priority',
|
||||
'condition' => 'condition',
|
||||
'action' => 'action',
|
||||
],
|
||||
['condition', 'action'],
|
||||
),
|
||||
iterator_to_array(
|
||||
$db->query(
|
||||
'SELECT id, target, priority, `condition`, action FROM event WHERE id > %i ORDER BY id',
|
||||
$eventIdBeforeAction,
|
||||
),
|
||||
),
|
||||
);
|
||||
$response['createdDiplomacy'] = iterator_to_array(
|
||||
$db->query(
|
||||
'SELECT me AS fromNationId, you AS toNationId, state, term FROM diplomacy WHERE me > %i OR you > %i ORDER BY me, you',
|
||||
$nationIdBeforeAction,
|
||||
$nationIdBeforeAction,
|
||||
),
|
||||
);
|
||||
$gameStorage = KVStorage::getStorage(DB::db(), 'game_env');
|
||||
$response['gameEnvironment'] = $gameStorage->getValues([
|
||||
'isunited',
|
||||
'turnterm',
|
||||
'block_change_scout',
|
||||
'refreshLimit',
|
||||
]);
|
||||
}
|
||||
if (in_array($actionName, ['AutoDeleteInvader', 'InvaderEnding'], true)) {
|
||||
$gameStorage = KVStorage::getStorage(DB::db(), 'game_env');
|
||||
$response['gameEnvironment'] = $gameStorage->getValues([
|
||||
'isunited',
|
||||
'turnterm',
|
||||
'block_change_scout',
|
||||
'refreshLimit',
|
||||
]);
|
||||
}
|
||||
if (($request['compactOutput'] ?? false) === true) {
|
||||
$observedGeneralTurns = [];
|
||||
foreach (comparisonIntegerList($request['observe']['generalIds'] ?? [], 'generalIds') as $generalId) {
|
||||
$observedGeneralTurns[(string)$generalId] = iterator_to_array(
|
||||
$db->query(
|
||||
'SELECT turn_idx AS turnIndex, action, arg FROM general_turn WHERE general_id = %i ORDER BY turn_idx',
|
||||
$generalId,
|
||||
),
|
||||
);
|
||||
}
|
||||
$response = [
|
||||
'schemaVersion' => 1,
|
||||
'engine' => 'ref',
|
||||
'action' => $actionName,
|
||||
'afterDetails' => $afterDetails,
|
||||
'createdGeneralCount' => count($createdGenerals),
|
||||
'firstCreatedGenerals' => array_slice($createdGenerals, 0, 3),
|
||||
'createdNations' => $response['createdNations'] ?? [],
|
||||
'createdEvents' => $response['createdEvents'] ?? [],
|
||||
'createdDiplomacy' => $response['createdDiplomacy'] ?? [],
|
||||
'gameEnvironment' => $response['gameEnvironment'] ?? [],
|
||||
'observedGeneralTurns' => $observedGeneralTurns,
|
||||
'remainingEventIds' => array_map(
|
||||
'intval',
|
||||
$db->queryFirstColumn('SELECT id FROM event ORDER BY id'),
|
||||
),
|
||||
];
|
||||
}
|
||||
echo json_encode(
|
||||
$response,
|
||||
JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRESERVE_ZERO_FRACTION,
|
||||
|
||||
Reference in New Issue
Block a user