diff --git a/hwe/compare/turn_state_snapshot.php b/hwe/compare/turn_state_snapshot.php index 831676e4..6562f19c 100644 --- a/hwe/compare/turn_state_snapshot.php +++ b/hwe/compare/turn_state_snapshot.php @@ -115,6 +115,36 @@ function comparisonNationCooldownSelectors(mixed $value, string $label): array return array_values($result); } +/** @return list */ +function comparisonDiplomacyPairSelectors(mixed $value, string $label): array +{ + if ($value === null) { + return []; + } + if (!is_array($value)) { + throw new \InvalidArgumentException("{$label} must be an array"); + } + $result = []; + foreach ($value as $entry) { + if (!is_array($entry)) { + throw new \InvalidArgumentException("{$label} entries must be objects"); + } + $fromNationId = $entry['fromNationId'] ?? null; + $toNationId = $entry['toNationId'] ?? null; + if (!is_int($fromNationId) || $fromNationId < 1 || !is_int($toNationId) || $toNationId < 1) { + throw new \InvalidArgumentException( + "{$label} entries require positive fromNationId and toNationId", + ); + } + $result["{$fromNationId}:{$toNationId}"] = [ + 'fromNationId' => $fromNationId, + 'toNationId' => $toNationId, + ]; + } + ksort($result, SORT_STRING); + return array_values($result); +} + /** @param array $row */ function comparisonPickRow(array $row, array $mapping, array $jsonKeys = []): array { @@ -168,6 +198,10 @@ function comparisonTurnStateSnapshot(array $request): array $observe['nationCooldowns'] ?? [], 'nationCooldowns', ); + $diplomacyPairSelectors = comparisonDiplomacyPairSelectors( + $observe['diplomacyPairs'] ?? [], + 'diplomacyPairs', + ); if (!is_int($logAfterId) || $logAfterId < 0 || !is_int($messageAfterId) || $messageAfterId < 0) { throw new \InvalidArgumentException('logAfterId and messageAfterId must be non-negative integers'); } @@ -363,26 +397,38 @@ function comparisonTurnStateSnapshot(array $request): array comparisonRowsById('nation', 'nation', $nationIds), ); - $diplomacy = []; + $diplomacyPairs = []; foreach ($nationIds as $fromNationId) { foreach ($nationIds as $toNationId) { if ($fromNationId === $toNationId) { continue; } - $row = $db->queryFirstRow( - 'SELECT me, you, state, term, dead FROM diplomacy WHERE me = %i AND you = %i', - $fromNationId, - $toNationId, - ); - if ($row !== null) { - $diplomacy[] = comparisonPickRow($row, [ - 'fromNationId' => 'me', - 'toNationId' => 'you', - 'state' => 'state', - 'term' => 'term', - 'dead' => 'dead', - ]); - } + $diplomacyPairs["{$fromNationId}:{$toNationId}"] = [ + 'fromNationId' => $fromNationId, + 'toNationId' => $toNationId, + ]; + } + } + foreach ($diplomacyPairSelectors as $pair) { + $diplomacyPairs["{$pair['fromNationId']}:{$pair['toNationId']}"] = $pair; + } + ksort($diplomacyPairs, SORT_STRING); + + $diplomacy = []; + foreach ($diplomacyPairs as $pair) { + $row = $db->queryFirstRow( + 'SELECT me, you, state, term, dead FROM diplomacy WHERE me = %i AND you = %i', + $pair['fromNationId'], + $pair['toNationId'], + ); + if ($row !== null) { + $diplomacy[] = comparisonPickRow($row, [ + 'fromNationId' => 'me', + 'toNationId' => 'you', + 'state' => 'state', + 'term' => 'term', + 'dead' => 'dead', + ]); } }