merge: trace nation betting lifecycle
This commit is contained in:
@@ -0,0 +1,69 @@
|
|||||||
|
{
|
||||||
|
"action": "FinishNationBetting",
|
||||||
|
"args": [1],
|
||||||
|
"setup": {
|
||||||
|
"clearBetting": true,
|
||||||
|
"resetNations": true,
|
||||||
|
"deleteOtherNations": true,
|
||||||
|
"keepNationIds": [1, 2],
|
||||||
|
"nation": [
|
||||||
|
{ "id": 1, "values": { "name": "위", "gennum": 1, "power": 100, "level": 2 } },
|
||||||
|
{ "id": 2, "values": { "name": "촉", "gennum": 1, "power": 300, "level": 0 } }
|
||||||
|
],
|
||||||
|
"resetGenerals": true,
|
||||||
|
"deleteOtherGenerals": true,
|
||||||
|
"keepGeneralIds": [1, 2],
|
||||||
|
"general": [
|
||||||
|
{ "id": 1, "values": { "name": "장수1", "nation": 1, "owner": 1, "npc": 0 } },
|
||||||
|
{ "id": 2, "values": { "name": "장수2", "nation": 2, "owner": 2, "npc": 0 } }
|
||||||
|
],
|
||||||
|
"bettingInfo": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"type": "bettingNation",
|
||||||
|
"name": "천통국 예상",
|
||||||
|
"finished": false,
|
||||||
|
"selectCnt": 1,
|
||||||
|
"isExclusive": null,
|
||||||
|
"reqInheritancePoint": true,
|
||||||
|
"openYearMonth": 2400,
|
||||||
|
"closeYearMonth": 2424,
|
||||||
|
"candidates": [
|
||||||
|
{
|
||||||
|
"title": "위",
|
||||||
|
"info": "국력: 100<br>장수 수: 1<br>도시 수: 1",
|
||||||
|
"isHtml": true,
|
||||||
|
"aux": { "nation": 1 }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "촉",
|
||||||
|
"info": "국력: 300<br>장수 수: 1<br>도시 수: 1",
|
||||||
|
"isHtml": true,
|
||||||
|
"aux": { "nation": 2 }
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"winner": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"bet": [
|
||||||
|
{ "betting_id": 1, "general_id": 0, "user_id": null, "betting_type": "[-1]", "amount": 100 },
|
||||||
|
{ "betting_id": 1, "general_id": 1, "user_id": 1, "betting_type": "[0]", "amount": 100 },
|
||||||
|
{ "betting_id": 1, "general_id": 2, "user_id": 2, "betting_type": "[1]", "amount": 100 }
|
||||||
|
],
|
||||||
|
"inheritancePrevious": {
|
||||||
|
"1": 900,
|
||||||
|
"2": 900
|
||||||
|
},
|
||||||
|
"syncEnvironment": true
|
||||||
|
},
|
||||||
|
"environment": {
|
||||||
|
"year": 202,
|
||||||
|
"month": 1,
|
||||||
|
"startyear": 190
|
||||||
|
},
|
||||||
|
"observe": {
|
||||||
|
"generalIds": [1, 2],
|
||||||
|
"nationIds": [1, 2],
|
||||||
|
"ownerIds": [1, 2]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
{
|
||||||
|
"action": "OpenNationBetting",
|
||||||
|
"args": [1, 500],
|
||||||
|
"setup": {
|
||||||
|
"clearBetting": true,
|
||||||
|
"resetNations": true,
|
||||||
|
"deleteOtherNations": true,
|
||||||
|
"keepNationIds": [1, 2],
|
||||||
|
"nation": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"values": {
|
||||||
|
"name": "위",
|
||||||
|
"color": "#111111",
|
||||||
|
"capital": 1,
|
||||||
|
"gennum": 1,
|
||||||
|
"gold": 1000,
|
||||||
|
"rice": 2000,
|
||||||
|
"tech": 100,
|
||||||
|
"power": 100,
|
||||||
|
"level": 2,
|
||||||
|
"type": "che_유가"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"values": {
|
||||||
|
"name": "촉",
|
||||||
|
"color": "#222222",
|
||||||
|
"capital": 2,
|
||||||
|
"gennum": 1,
|
||||||
|
"gold": 3000,
|
||||||
|
"rice": 4000,
|
||||||
|
"tech": 200,
|
||||||
|
"power": 300,
|
||||||
|
"level": 2,
|
||||||
|
"type": "che_병가"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"resetCities": true,
|
||||||
|
"city": [
|
||||||
|
{ "id": 1, "values": { "nation": 1, "level": 3 } },
|
||||||
|
{ "id": 2, "values": { "nation": 2, "level": 3 } }
|
||||||
|
],
|
||||||
|
"resetGenerals": true,
|
||||||
|
"deleteOtherGenerals": true,
|
||||||
|
"keepGeneralIds": [1, 2],
|
||||||
|
"general": [
|
||||||
|
{ "id": 1, "values": { "name": "장수1", "nation": 1, "city": 1, "owner": 1, "npc": 0 } },
|
||||||
|
{ "id": 2, "values": { "name": "장수2", "nation": 2, "city": 2, "owner": 2, "npc": 0 } }
|
||||||
|
],
|
||||||
|
"syncEnvironment": true
|
||||||
|
},
|
||||||
|
"environment": {
|
||||||
|
"year": 200,
|
||||||
|
"month": 1,
|
||||||
|
"startyear": 190
|
||||||
|
},
|
||||||
|
"observe": {
|
||||||
|
"generalIds": [1, 2],
|
||||||
|
"cityIds": [1, 2],
|
||||||
|
"nationIds": [1, 2]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -33,7 +33,7 @@ function comparisonMonthlyPatch(string $table, int $id, array $values): void
|
|||||||
'idColumn' => 'nation',
|
'idColumn' => 'nation',
|
||||||
'allowed' => [
|
'allowed' => [
|
||||||
'name', 'color', 'capital', 'gennum', 'gold', 'rice', 'tech',
|
'name', 'color', 'capital', 'gennum', 'gold', 'rice', 'tech',
|
||||||
'level', 'type', 'rate_tmp', 'aux',
|
'power', 'level', 'type', 'rate_tmp', 'aux',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'general' => [
|
'general' => [
|
||||||
@@ -207,6 +207,8 @@ function comparisonMonthlyEventTraceMain(): void
|
|||||||
'InvaderEnding',
|
'InvaderEnding',
|
||||||
'ChangeCity',
|
'ChangeCity',
|
||||||
'ProvideNPCTroopLeader',
|
'ProvideNPCTroopLeader',
|
||||||
|
'OpenNationBetting',
|
||||||
|
'FinishNationBetting',
|
||||||
];
|
];
|
||||||
if (!in_array($actionName, $supportedActions, true)) {
|
if (!in_array($actionName, $supportedActions, true)) {
|
||||||
throw new \InvalidArgumentException('unsupported monthly action');
|
throw new \InvalidArgumentException('unsupported monthly action');
|
||||||
@@ -283,6 +285,45 @@ function comparisonMonthlyEventTraceMain(): void
|
|||||||
foreach (comparisonIntegerList($setup['clearInheritanceOwnerIds'] ?? [], 'clearInheritanceOwnerIds') as $ownerId) {
|
foreach (comparisonIntegerList($setup['clearInheritanceOwnerIds'] ?? [], 'clearInheritanceOwnerIds') as $ownerId) {
|
||||||
DB::db()->delete('storage', 'namespace = %s', "inheritance_{$ownerId}");
|
DB::db()->delete('storage', 'namespace = %s', "inheritance_{$ownerId}");
|
||||||
}
|
}
|
||||||
|
if (($setup['clearBetting'] ?? false) === true) {
|
||||||
|
DB::db()->query('DELETE FROM ng_betting');
|
||||||
|
DB::db()->query('DELETE FROM storage WHERE namespace = %s', 'betting');
|
||||||
|
$gameStorage = KVStorage::getStorage(DB::db(), 'game_env');
|
||||||
|
$gameStorage->setValue('last_betting_id', 0);
|
||||||
|
}
|
||||||
|
foreach ($setup['bettingInfo'] ?? [] as $rawBettingInfo) {
|
||||||
|
if (!is_array($rawBettingInfo) || !is_int($rawBettingInfo['id'] ?? null)) {
|
||||||
|
throw new \InvalidArgumentException('invalid setup.bettingInfo row');
|
||||||
|
}
|
||||||
|
KVStorage::getStorage(DB::db(), 'betting')->setValue(
|
||||||
|
"id_{$rawBettingInfo['id']}",
|
||||||
|
$rawBettingInfo,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
foreach ($setup['bet'] ?? [] as $row) {
|
||||||
|
if (
|
||||||
|
!is_array($row)
|
||||||
|
|| !is_int($row['betting_id'] ?? null)
|
||||||
|
|| !is_int($row['general_id'] ?? null)
|
||||||
|
|| !is_string($row['betting_type'] ?? null)
|
||||||
|
|| !is_int($row['amount'] ?? null)
|
||||||
|
) {
|
||||||
|
throw new \InvalidArgumentException('invalid setup.bet row');
|
||||||
|
}
|
||||||
|
DB::db()->insert('ng_betting', [
|
||||||
|
'betting_id' => $row['betting_id'],
|
||||||
|
'general_id' => $row['general_id'],
|
||||||
|
'user_id' => $row['user_id'] ?? null,
|
||||||
|
'betting_type' => $row['betting_type'],
|
||||||
|
'amount' => $row['amount'],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
foreach ($setup['inheritancePrevious'] ?? [] as $ownerId => $value) {
|
||||||
|
if (!is_numeric($ownerId) || !is_int($value)) {
|
||||||
|
throw new \InvalidArgumentException('invalid setup.inheritancePrevious entry');
|
||||||
|
}
|
||||||
|
KVStorage::getStorage(DB::db(), "inheritance_{$ownerId}")->setValue('previous', [$value, null]);
|
||||||
|
}
|
||||||
if (($setup['resetDiplomacy'] ?? false) === true) {
|
if (($setup['resetDiplomacy'] ?? false) === true) {
|
||||||
DB::db()->query('DELETE FROM diplomacy');
|
DB::db()->query('DELETE FROM diplomacy');
|
||||||
}
|
}
|
||||||
@@ -379,7 +420,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'], true)) {
|
} elseif (in_array($actionName, ['CreateManyNPC', 'RegNPC', 'RegNeutralNPC', 'RaiseInvader', 'AutoDeleteInvader', 'ChangeCity', 'OpenNationBetting', 'FinishNationBetting'], 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");
|
||||||
@@ -393,6 +434,12 @@ function comparisonMonthlyEventTraceMain(): void
|
|||||||
if ($actionName === 'ChangeCity' && count($args) !== 2) {
|
if ($actionName === 'ChangeCity' && count($args) !== 2) {
|
||||||
throw new \InvalidArgumentException('ChangeCity args must have exactly two entries');
|
throw new \InvalidArgumentException('ChangeCity args must have exactly two entries');
|
||||||
}
|
}
|
||||||
|
if ($actionName === 'OpenNationBetting' && count($args) > 2) {
|
||||||
|
throw new \InvalidArgumentException('OpenNationBetting args must have at most two entries');
|
||||||
|
}
|
||||||
|
if ($actionName === 'FinishNationBetting' && count($args) !== 1) {
|
||||||
|
throw new \InvalidArgumentException('FinishNationBetting args must have exactly one entry');
|
||||||
|
}
|
||||||
$action = new $actionClass(...$args);
|
$action = new $actionClass(...$args);
|
||||||
} else {
|
} else {
|
||||||
$action = new $actionClass();
|
$action = new $actionClass();
|
||||||
@@ -574,6 +621,42 @@ function comparisonMonthlyEventTraceMain(): void
|
|||||||
'lastNPCTroopLeaderID',
|
'lastNPCTroopLeaderID',
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
if (in_array($actionName, ['OpenNationBetting', 'FinishNationBetting'], true)) {
|
||||||
|
$bettingStorage = KVStorage::getStorage(DB::db(), 'betting');
|
||||||
|
$response['betting'] = $bettingStorage->getAll();
|
||||||
|
$response['bets'] = iterator_to_array(
|
||||||
|
$db->query(
|
||||||
|
'SELECT betting_id AS bettingId, general_id AS generalId, user_id AS userId, betting_type AS selectionKey, amount FROM ng_betting ORDER BY id',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
$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['gameEnvironment'] = KVStorage::getStorage(DB::db(), 'game_env')->getValues([
|
||||||
|
'last_betting_id',
|
||||||
|
]);
|
||||||
|
$response['inheritancePrevious'] = [];
|
||||||
|
foreach (comparisonIntegerList($request['observe']['ownerIds'] ?? [], 'ownerIds') as $ownerId) {
|
||||||
|
$value = KVStorage::getStorage(DB::db(), "inheritance_{$ownerId}")->getValue('previous');
|
||||||
|
$response['inheritancePrevious'][(string)$ownerId] = is_array($value) ? ($value[0] ?? 0) : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
if ($actionName === 'RaiseInvader') {
|
if ($actionName === 'RaiseInvader') {
|
||||||
$response['createdEvents'] = array_map(
|
$response['createdEvents'] = array_map(
|
||||||
static fn(array $row): array => comparisonPickRow(
|
static fn(array $row): array => comparisonPickRow(
|
||||||
|
|||||||
Reference in New Issue
Block a user