compare: trace nation betting user lifecycle
This commit is contained in:
@@ -0,0 +1,75 @@
|
|||||||
|
{
|
||||||
|
"action": "NationBettingLifecycle",
|
||||||
|
"args": [1, 100],
|
||||||
|
"bettorGeneralIds": [1, 2],
|
||||||
|
"bettorOwnerIds": [1, 2],
|
||||||
|
"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,
|
||||||
|
"deleteOtherCities": true,
|
||||||
|
"keepCityIds": [1, 2],
|
||||||
|
"city": [
|
||||||
|
{ "id": 1, "values": { "name": "허창", "nation": 1, "level": 3 } },
|
||||||
|
{ "id": 2, "values": { "name": "성도", "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 } }
|
||||||
|
],
|
||||||
|
"inheritancePrevious": {
|
||||||
|
"1": 1000,
|
||||||
|
"2": 1000
|
||||||
|
},
|
||||||
|
"rankData": [
|
||||||
|
{ "generalId": 1, "type": "inherit_spent_dyn", "value": 0 },
|
||||||
|
{ "generalId": 1, "type": "inherit_earned_act", "value": 0 },
|
||||||
|
{ "generalId": 2, "type": "inherit_spent_dyn", "value": 0 },
|
||||||
|
{ "generalId": 2, "type": "inherit_earned_act", "value": 0 }
|
||||||
|
],
|
||||||
|
"syncEnvironment": true
|
||||||
|
},
|
||||||
|
"environment": {
|
||||||
|
"year": 200,
|
||||||
|
"month": 1,
|
||||||
|
"startyear": 190
|
||||||
|
},
|
||||||
|
"observe": {}
|
||||||
|
}
|
||||||
@@ -591,6 +591,155 @@ function comparisonNpcNationLifecycleTrace(
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exercise nation betting from monthly open through real user bets and settlement.
|
||||||
|
*
|
||||||
|
* @param array<string, mixed> $request
|
||||||
|
* @param array<string, mixed> $environment
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
function comparisonNationBettingLifecycleTrace(
|
||||||
|
array $request,
|
||||||
|
array $environment,
|
||||||
|
int $eventIdBeforeAction,
|
||||||
|
int $worldHistoryIdBeforeAction,
|
||||||
|
): array {
|
||||||
|
$db = DB::db();
|
||||||
|
$args = $request['args'] ?? [];
|
||||||
|
if (!is_array($args) || count($args) > 2) {
|
||||||
|
throw new \InvalidArgumentException('NationBettingLifecycle args must have at most two entries');
|
||||||
|
}
|
||||||
|
$bettorGeneralIds = comparisonIntegerList(
|
||||||
|
$request['bettorGeneralIds'] ?? [],
|
||||||
|
'bettorGeneralIds',
|
||||||
|
);
|
||||||
|
$bettorOwnerIds = comparisonIntegerList(
|
||||||
|
$request['bettorOwnerIds'] ?? [],
|
||||||
|
'bettorOwnerIds',
|
||||||
|
);
|
||||||
|
if (count($bettorGeneralIds) !== 2 || count($bettorOwnerIds) !== 2) {
|
||||||
|
throw new \InvalidArgumentException(
|
||||||
|
'NationBettingLifecycle requires exactly two bettorGeneralIds and bettorOwnerIds',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$year = $environment['year'];
|
||||||
|
$month = $environment['month'];
|
||||||
|
$startYear = $environment['startyear'];
|
||||||
|
(new \sammo\Event\Action\OpenNationBetting(...$args))->run([
|
||||||
|
'year' => $year,
|
||||||
|
'month' => $month,
|
||||||
|
'startyear' => $startYear,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$gameStorage = KVStorage::getStorage($db, 'game_env');
|
||||||
|
$gameStorage->resetCache();
|
||||||
|
$bettingId = (int)$gameStorage->last_betting_id;
|
||||||
|
$betting = new Betting($bettingId);
|
||||||
|
$bettingInfo = $betting->getInfo();
|
||||||
|
$candidateNationIds = array_map(
|
||||||
|
static fn(\sammo\DTO\SelectItem $candidate): int => (int)($candidate->aux['nation'] ?? 0),
|
||||||
|
$bettingInfo->candidates,
|
||||||
|
);
|
||||||
|
if (count($candidateNationIds) !== 2) {
|
||||||
|
throw new \RuntimeException('NationBettingLifecycle requires exactly two candidates');
|
||||||
|
}
|
||||||
|
|
||||||
|
$finishEventCount = (int)$db->queryFirstField(
|
||||||
|
'SELECT count(*) FROM event WHERE id > %i AND action LIKE %s',
|
||||||
|
$eventIdBeforeAction,
|
||||||
|
"%FinishNationBetting%{$bettingId}%",
|
||||||
|
);
|
||||||
|
$afterOpen = [
|
||||||
|
'bettingId' => $bettingId,
|
||||||
|
'candidateNationIds' => $candidateNationIds,
|
||||||
|
'systemBonus' => (int)($db->queryFirstField(
|
||||||
|
'SELECT amount FROM ng_betting WHERE betting_id = %i AND general_id = 0',
|
||||||
|
$bettingId,
|
||||||
|
) ?? 0),
|
||||||
|
'finishEventCount' => $finishEventCount,
|
||||||
|
'historyLogs' => array_values($db->queryFirstColumn(
|
||||||
|
'SELECT text FROM world_history WHERE id > %i AND nation_id = 0 ORDER BY id',
|
||||||
|
$worldHistoryIdBeforeAction,
|
||||||
|
)),
|
||||||
|
];
|
||||||
|
|
||||||
|
$betting->bet($bettorGeneralIds[0], $bettorOwnerIds[0], [1], 100);
|
||||||
|
$betting->bet($bettorGeneralIds[1], $bettorOwnerIds[1], [0], 100);
|
||||||
|
$afterBets = [
|
||||||
|
'bets' => array_map(
|
||||||
|
static fn(array $row): array => [
|
||||||
|
'generalId' => (int)$row['general_id'],
|
||||||
|
'ownerId' => $row['user_id'] === null ? null : (int)$row['user_id'],
|
||||||
|
'selectionKey' => $row['betting_type'],
|
||||||
|
'amount' => (int)$row['amount'],
|
||||||
|
],
|
||||||
|
iterator_to_array($db->query(
|
||||||
|
'SELECT general_id, user_id, betting_type, amount FROM ng_betting WHERE betting_id = %i ORDER BY general_id',
|
||||||
|
$bettingId,
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
'inheritancePrevious' => array_map(
|
||||||
|
static function (int $ownerId): int {
|
||||||
|
$value = KVStorage::getStorage(DB::db(), "inheritance_{$ownerId}")->getValue('previous');
|
||||||
|
return is_array($value) ? (int)($value[0] ?? 0) : 0;
|
||||||
|
},
|
||||||
|
$bettorOwnerIds,
|
||||||
|
),
|
||||||
|
'spentRank' => array_map(
|
||||||
|
static fn(int $generalId): int => (int)(DB::db()->queryFirstField(
|
||||||
|
'SELECT value FROM rank_data WHERE general_id = %i AND type = %s',
|
||||||
|
$generalId,
|
||||||
|
\sammo\Enums\RankColumn::inherit_point_spent_dynamic->value,
|
||||||
|
) ?? 0),
|
||||||
|
$bettorGeneralIds,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
$db->update('nation', ['level' => 0], 'nation = %i', $candidateNationIds[1]);
|
||||||
|
$finishResult = (new \sammo\Event\Action\FinishNationBetting($bettingId))->run([
|
||||||
|
'year' => $year,
|
||||||
|
'month' => $month + 1,
|
||||||
|
'startyear' => $startYear,
|
||||||
|
]);
|
||||||
|
$settledInfo = (new Betting($bettingId))->getInfo();
|
||||||
|
$afterFinish = [
|
||||||
|
'result' => $finishResult[1] ?? null,
|
||||||
|
'finished' => $settledInfo->finished,
|
||||||
|
'winner' => $settledInfo->winner,
|
||||||
|
'inheritancePrevious' => array_map(
|
||||||
|
static function (int $ownerId): int {
|
||||||
|
$value = KVStorage::getStorage(DB::db(), "inheritance_{$ownerId}")->getValue('previous');
|
||||||
|
return is_array($value) ? (int)($value[0] ?? 0) : 0;
|
||||||
|
},
|
||||||
|
$bettorOwnerIds,
|
||||||
|
),
|
||||||
|
'earnedRank' => array_map(
|
||||||
|
static fn(int $generalId): int => (int)(DB::db()->queryFirstField(
|
||||||
|
'SELECT value FROM rank_data WHERE general_id = %i AND type = %s',
|
||||||
|
$generalId,
|
||||||
|
\sammo\Enums\RankColumn::inherit_point_earned_by_action->value,
|
||||||
|
) ?? 0),
|
||||||
|
$bettorGeneralIds,
|
||||||
|
),
|
||||||
|
'historyLogs' => array_values($db->queryFirstColumn(
|
||||||
|
'SELECT text FROM world_history WHERE id > %i AND nation_id = 0 ORDER BY id',
|
||||||
|
$worldHistoryIdBeforeAction,
|
||||||
|
)),
|
||||||
|
];
|
||||||
|
|
||||||
|
return [
|
||||||
|
'schemaVersion' => 1,
|
||||||
|
'engine' => 'ref',
|
||||||
|
'action' => 'NationBettingLifecycle',
|
||||||
|
'phases' => [
|
||||||
|
'afterOpen' => $afterOpen,
|
||||||
|
'afterBets' => $afterBets,
|
||||||
|
'afterFinish' => $afterFinish,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
function comparisonMonthlyEventTraceMain(): void
|
function comparisonMonthlyEventTraceMain(): void
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
@@ -618,6 +767,7 @@ function comparisonMonthlyEventTraceMain(): void
|
|||||||
'InvaderEnding',
|
'InvaderEnding',
|
||||||
'ChangeCity',
|
'ChangeCity',
|
||||||
'ProvideNPCTroopLeader',
|
'ProvideNPCTroopLeader',
|
||||||
|
'NationBettingLifecycle',
|
||||||
'OpenNationBetting',
|
'OpenNationBetting',
|
||||||
'FinishNationBetting',
|
'FinishNationBetting',
|
||||||
'BlockScoutAction',
|
'BlockScoutAction',
|
||||||
@@ -993,6 +1143,18 @@ function comparisonMonthlyEventTraceMain(): void
|
|||||||
), PHP_EOL;
|
), PHP_EOL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if ($actionName === 'NationBettingLifecycle') {
|
||||||
|
echo json_encode(
|
||||||
|
comparisonNationBettingLifecycleTrace(
|
||||||
|
$request,
|
||||||
|
$environment,
|
||||||
|
$eventIdBeforeAction,
|
||||||
|
$worldHistoryAfterId,
|
||||||
|
),
|
||||||
|
JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRESERVE_ZERO_FRACTION,
|
||||||
|
), PHP_EOL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$actionClass = "\\sammo\\Event\\Action\\{$actionName}";
|
$actionClass = "\\sammo\\Event\\Action\\{$actionName}";
|
||||||
if (in_array($actionName, ['PreUpdateMonthly', 'PostUpdateMonthly', 'MonthlyBoundary'], true)) {
|
if (in_array($actionName, ['PreUpdateMonthly', 'PostUpdateMonthly', 'MonthlyBoundary'], true)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user