test: trace monthly unique and inheritance actions
This commit is contained in:
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"action": "LostUniqueItem",
|
||||||
|
"args": [0.2],
|
||||||
|
"environment": {
|
||||||
|
"year": 210,
|
||||||
|
"month": 1,
|
||||||
|
"startyear": 180
|
||||||
|
},
|
||||||
|
"setup": {
|
||||||
|
"syncEnvironment": true,
|
||||||
|
"resetGenerals": true,
|
||||||
|
"deleteOtherGenerals": true,
|
||||||
|
"keepGeneralIds": [1, 2],
|
||||||
|
"general": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"values": {
|
||||||
|
"name": "갑",
|
||||||
|
"npc": 0,
|
||||||
|
"horse": "che_명마_12_옥란백용구",
|
||||||
|
"weapon": "che_무기_15_의천검",
|
||||||
|
"book": "che_서적_01_효경전",
|
||||||
|
"item": "che_저지_삼황내문"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"values": {
|
||||||
|
"name": "을",
|
||||||
|
"npc": 1,
|
||||||
|
"horse": "che_명마_12_사륜거",
|
||||||
|
"weapon": "che_무기_01_단도",
|
||||||
|
"book": "None",
|
||||||
|
"item": "che_부적_태현청생부"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"observe": {
|
||||||
|
"generalIds": [1, 2]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
{
|
||||||
|
"action": "MergeInheritPointRank",
|
||||||
|
"environment": {
|
||||||
|
"year": 210,
|
||||||
|
"month": 1,
|
||||||
|
"startyear": 180
|
||||||
|
},
|
||||||
|
"setup": {
|
||||||
|
"resetGenerals": true,
|
||||||
|
"deleteOtherGenerals": true,
|
||||||
|
"keepGeneralIds": [1],
|
||||||
|
"clearInheritanceOwnerIds": [100],
|
||||||
|
"gameEnvironment": {
|
||||||
|
"isunited": 0
|
||||||
|
},
|
||||||
|
"general": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"values": {
|
||||||
|
"name": "갑",
|
||||||
|
"nation": 1,
|
||||||
|
"owner": 100,
|
||||||
|
"npc": 0,
|
||||||
|
"belong": 3,
|
||||||
|
"dex1": 1000,
|
||||||
|
"dex2": 0,
|
||||||
|
"dex3": 0,
|
||||||
|
"dex4": 0,
|
||||||
|
"dex5": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"inheritancePoints": [
|
||||||
|
{"ownerId": 100, "key": "previous", "value": 999},
|
||||||
|
{"ownerId": 100, "key": "lived_month", "value": 2},
|
||||||
|
{"ownerId": 100, "key": "max_domestic_critical", "value": 4},
|
||||||
|
{"ownerId": 100, "key": "active_action", "value": 15},
|
||||||
|
{"ownerId": 100, "key": "unifier", "value": 6},
|
||||||
|
{"ownerId": 100, "key": "tournament", "value": 7}
|
||||||
|
],
|
||||||
|
"rankData": [
|
||||||
|
{"generalId": 1, "type": "warnum", "value": 2},
|
||||||
|
{"generalId": 1, "type": "firenum", "value": 1},
|
||||||
|
{"generalId": 1, "type": "betwin", "value": 2},
|
||||||
|
{"generalId": 1, "type": "betgold", "value": 4000},
|
||||||
|
{"generalId": 1, "type": "betwingold", "value": 2000},
|
||||||
|
{"generalId": 1, "type": "inherit_earned_dyn", "value": 999},
|
||||||
|
{"generalId": 1, "type": "inherit_earned_act", "value": 11},
|
||||||
|
{"generalId": 1, "type": "inherit_earned", "value": 999},
|
||||||
|
{"generalId": 1, "type": "inherit_spent_dyn", "value": 9},
|
||||||
|
{"generalId": 1, "type": "inherit_spent", "value": 999}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"observe": {
|
||||||
|
"generalIds": [1],
|
||||||
|
"ownerIds": [100],
|
||||||
|
"inheritanceKeys": [
|
||||||
|
"previous",
|
||||||
|
"lived_month",
|
||||||
|
"max_domestic_critical",
|
||||||
|
"active_action",
|
||||||
|
"unifier",
|
||||||
|
"tournament"
|
||||||
|
],
|
||||||
|
"rankGeneralIds": [1],
|
||||||
|
"rankTypes": [
|
||||||
|
"inherit_earned",
|
||||||
|
"inherit_earned_act",
|
||||||
|
"inherit_earned_dyn",
|
||||||
|
"inherit_spent",
|
||||||
|
"inherit_spent_dyn"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -108,6 +108,10 @@ function comparisonMonthlyDetails(array $observe, int $worldHistoryAfterId): arr
|
|||||||
'specialWar' => 'special2',
|
'specialWar' => 'special2',
|
||||||
'specAge2' => 'specage2',
|
'specAge2' => 'specage2',
|
||||||
'betray' => 'betray',
|
'betray' => 'betray',
|
||||||
|
'horse' => 'horse',
|
||||||
|
'weapon' => 'weapon',
|
||||||
|
'book' => 'book',
|
||||||
|
'item' => 'item',
|
||||||
'dex1' => 'dex1',
|
'dex1' => 'dex1',
|
||||||
'dex2' => 'dex2',
|
'dex2' => 'dex2',
|
||||||
'dex3' => 'dex3',
|
'dex3' => 'dex3',
|
||||||
@@ -180,24 +184,42 @@ function comparisonMonthlyDetails(array $observe, int $worldHistoryAfterId): arr
|
|||||||
$worldHistoryAfterId,
|
$worldHistoryAfterId,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
$inheritanceKeys = $observe['inheritanceKeys'] ?? ['unifier'];
|
||||||
|
if (!is_array($inheritanceKeys) || array_filter($inheritanceKeys, static fn($key): bool => !is_string($key))) {
|
||||||
|
throw new \InvalidArgumentException('inheritanceKeys must be an array of strings');
|
||||||
|
}
|
||||||
$inheritancePoints = [];
|
$inheritancePoints = [];
|
||||||
foreach (comparisonIntegerList($observe['ownerIds'] ?? [], 'ownerIds') as $ownerId) {
|
foreach (comparisonIntegerList($observe['ownerIds'] ?? [], 'ownerIds') as $ownerId) {
|
||||||
$value = $db->queryFirstField(
|
$entry = ['ownerId' => $ownerId];
|
||||||
'SELECT value FROM storage WHERE namespace = %s AND `key` = %s',
|
foreach ($inheritanceKeys as $key) {
|
||||||
"inheritance_{$ownerId}",
|
$value = $db->queryFirstField(
|
||||||
'unifier',
|
'SELECT value FROM storage WHERE namespace = %s AND `key` = %s',
|
||||||
);
|
"inheritance_{$ownerId}",
|
||||||
$inheritancePoints[] = [
|
$key,
|
||||||
'ownerId' => $ownerId,
|
);
|
||||||
'unifier' => $value === null ? 0 : (comparisonJsonValue($value)[0] ?? 0),
|
$entry[$key] = $value === null ? 0 : (comparisonJsonValue($value)[0] ?? 0);
|
||||||
];
|
}
|
||||||
|
$inheritancePoints[] = $entry;
|
||||||
}
|
}
|
||||||
|
$rankGeneralIds = comparisonIntegerList($observe['rankGeneralIds'] ?? [], 'rankGeneralIds');
|
||||||
|
$rankTypes = $observe['rankTypes'] ?? [];
|
||||||
|
if (!is_array($rankTypes) || array_filter($rankTypes, static fn($type): bool => !is_string($type))) {
|
||||||
|
throw new \InvalidArgumentException('rankTypes must be an array of strings');
|
||||||
|
}
|
||||||
|
$rankData = (!$rankGeneralIds || !$rankTypes)
|
||||||
|
? []
|
||||||
|
: iterator_to_array($db->query(
|
||||||
|
'SELECT general_id AS generalId, nation_id AS nationId, `type`, `value` FROM rank_data WHERE general_id IN %li AND `type` IN %ls ORDER BY general_id, `type`',
|
||||||
|
$rankGeneralIds,
|
||||||
|
$rankTypes,
|
||||||
|
));
|
||||||
return [
|
return [
|
||||||
'generals' => $generals,
|
'generals' => $generals,
|
||||||
'cities' => $cities,
|
'cities' => $cities,
|
||||||
'nations' => $nations,
|
'nations' => $nations,
|
||||||
'worldHistory' => $worldHistory,
|
'worldHistory' => $worldHistory,
|
||||||
'inheritancePoints' => $inheritancePoints,
|
'inheritancePoints' => $inheritancePoints,
|
||||||
|
'rankData' => $rankData,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,6 +253,8 @@ function comparisonMonthlyEventTraceMain(): void
|
|||||||
'UnblockScoutAction',
|
'UnblockScoutAction',
|
||||||
'AssignGeneralSpeciality',
|
'AssignGeneralSpeciality',
|
||||||
'AddGlobalBetray',
|
'AddGlobalBetray',
|
||||||
|
'LostUniqueItem',
|
||||||
|
'MergeInheritPointRank',
|
||||||
];
|
];
|
||||||
if (!in_array($actionName, $supportedActions, true)) {
|
if (!in_array($actionName, $supportedActions, true)) {
|
||||||
throw new \InvalidArgumentException('unsupported monthly action');
|
throw new \InvalidArgumentException('unsupported monthly action');
|
||||||
@@ -346,6 +370,43 @@ function comparisonMonthlyEventTraceMain(): void
|
|||||||
}
|
}
|
||||||
KVStorage::getStorage(DB::db(), "inheritance_{$ownerId}")->setValue('previous', [$value, null]);
|
KVStorage::getStorage(DB::db(), "inheritance_{$ownerId}")->setValue('previous', [$value, null]);
|
||||||
}
|
}
|
||||||
|
foreach ($setup['inheritancePoints'] ?? [] as $row) {
|
||||||
|
if (
|
||||||
|
!is_array($row)
|
||||||
|
|| !is_int($row['ownerId'] ?? null)
|
||||||
|
|| !is_string($row['key'] ?? null)
|
||||||
|
|| !is_numeric($row['value'] ?? null)
|
||||||
|
) {
|
||||||
|
throw new \InvalidArgumentException('invalid setup.inheritancePoints row');
|
||||||
|
}
|
||||||
|
KVStorage::getStorage(DB::db(), "inheritance_{$row['ownerId']}")->setValue(
|
||||||
|
$row['key'],
|
||||||
|
[$row['value'], null],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
foreach ($setup['rankData'] ?? [] as $row) {
|
||||||
|
if (
|
||||||
|
!is_array($row)
|
||||||
|
|| !is_int($row['generalId'] ?? null)
|
||||||
|
|| !is_string($row['type'] ?? null)
|
||||||
|
|| !is_int($row['value'] ?? null)
|
||||||
|
) {
|
||||||
|
throw new \InvalidArgumentException('invalid setup.rankData row');
|
||||||
|
}
|
||||||
|
$nationId = (int)(DB::db()->queryFirstField(
|
||||||
|
'SELECT nation FROM general WHERE no = %i',
|
||||||
|
$row['generalId'],
|
||||||
|
) ?? 0);
|
||||||
|
DB::db()->insertUpdate('rank_data', [
|
||||||
|
'general_id' => $row['generalId'],
|
||||||
|
'nation_id' => $nationId,
|
||||||
|
'type' => $row['type'],
|
||||||
|
'value' => $row['value'],
|
||||||
|
], [
|
||||||
|
'nation_id' => $nationId,
|
||||||
|
'value' => $row['value'],
|
||||||
|
]);
|
||||||
|
}
|
||||||
if (($setup['resetDiplomacy'] ?? false) === true) {
|
if (($setup['resetDiplomacy'] ?? false) === true) {
|
||||||
DB::db()->query('DELETE FROM diplomacy');
|
DB::db()->query('DELETE FROM diplomacy');
|
||||||
}
|
}
|
||||||
@@ -442,7 +503,7 @@ function comparisonMonthlyEventTraceMain(): void
|
|||||||
throw new \InvalidArgumentException('ProcessSemiAnnual requires resource');
|
throw new \InvalidArgumentException('ProcessSemiAnnual requires resource');
|
||||||
}
|
}
|
||||||
$action = new $actionClass($resource);
|
$action = new $actionClass($resource);
|
||||||
} elseif (in_array($actionName, ['CreateManyNPC', 'RegNPC', 'RegNeutralNPC', 'RaiseInvader', 'AutoDeleteInvader', 'ChangeCity', 'OpenNationBetting', 'FinishNationBetting', 'BlockScoutAction', 'UnblockScoutAction', 'AddGlobalBetray'], true)) {
|
} elseif (in_array($actionName, ['CreateManyNPC', 'RegNPC', 'RegNeutralNPC', 'RaiseInvader', 'AutoDeleteInvader', 'ChangeCity', 'OpenNationBetting', 'FinishNationBetting', 'BlockScoutAction', 'UnblockScoutAction', 'AddGlobalBetray', 'LostUniqueItem'], true)) {
|
||||||
$args = $request['args'] ?? [];
|
$args = $request['args'] ?? [];
|
||||||
if (!is_array($args)) {
|
if (!is_array($args)) {
|
||||||
throw new \InvalidArgumentException("{$actionName} args must be an array");
|
throw new \InvalidArgumentException("{$actionName} args must be an array");
|
||||||
@@ -468,6 +529,9 @@ function comparisonMonthlyEventTraceMain(): void
|
|||||||
if ($actionName === 'AddGlobalBetray' && count($args) > 2) {
|
if ($actionName === 'AddGlobalBetray' && count($args) > 2) {
|
||||||
throw new \InvalidArgumentException('AddGlobalBetray args must have at most two entries');
|
throw new \InvalidArgumentException('AddGlobalBetray args must have at most two entries');
|
||||||
}
|
}
|
||||||
|
if ($actionName === 'LostUniqueItem' && count($args) > 1) {
|
||||||
|
throw new \InvalidArgumentException('LostUniqueItem args must have at most one entry');
|
||||||
|
}
|
||||||
$action = new $actionClass(...$args);
|
$action = new $actionClass(...$args);
|
||||||
} else {
|
} else {
|
||||||
$action = new $actionClass();
|
$action = new $actionClass();
|
||||||
|
|||||||
Reference in New Issue
Block a user