1
0
Fork 0

feat(radio): record mode-specific traffic results

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
Jason Fraley 2026-09-03 16:03:10 -04:00
parent 4703a24dfe
commit 0b012f07d8

View file

@ -15,9 +15,20 @@ interface ActionResult<T = undefined> {
export interface RadioStats { export interface RadioStats {
gamesPlayed: number; gamesPlayed: number;
totalMessages: number; totalMessages: number;
incorrectMessages: number;
bestScore: number; bestScore: number;
bestAccuracy: number; bestAccuracy: number;
bestSprintTimeMs: number; bestSprintTimeMs: number;
sprintGamesPlayed: number;
sprintTotalMessages: number;
sprintIncorrectMessages: number;
sprintBestScore: number;
sprintBestAccuracy: number;
watchGamesPlayed: number;
watchTotalMessages: number;
watchIncorrectMessages: number;
watchBestScore: number;
watchBestAccuracy: number;
radioTrafficXp: number; radioTrafficXp: number;
xpEarned: number; xpEarned: number;
} }
@ -52,8 +63,9 @@ async function authenticate() {
export async function submitRadioResult(input: { export async function submitRadioResult(input: {
score: number; score: number;
messageCount: number; messageCount: number;
correctMessages: number; correctMessages: number;
incorrectMessages: number;
accuracy: number; accuracy: number;
mode: RadioMode; mode: RadioMode;
timeMs?: number; timeMs?: number;
@ -83,6 +95,12 @@ export async function submitRadioResult(input: {
) { ) {
return { success: false, error: "Invalid result." }; return { success: false, error: "Invalid result." };
} }
if (!Number.isInteger(input.incorrectMessages) || input.incorrectMessages < 0) {
return { success: false, error: "Invalid result." };
}
if (input.mode === "sprint" && input.correctMessages === 0) {
return { success: false, error: "A Sprint needs at least one correct transmission." };
}
if (!Number.isFinite(input.accuracy) || input.accuracy < 0 || input.accuracy > 1) { if (!Number.isFinite(input.accuracy) || input.accuracy < 0 || input.accuracy > 1) {
return { success: false, error: "Invalid result." }; return { success: false, error: "Invalid result." };
} }
@ -112,9 +130,20 @@ export async function submitRadioResult(input: {
radioTraffic?: { radioTraffic?: {
gamesPlayed?: number; gamesPlayed?: number;
totalMessages?: number; totalMessages?: number;
incorrectMessages?: number;
bestScore?: number; bestScore?: number;
bestAccuracy?: number; bestAccuracy?: number;
bestSprintTimeMs?: number; bestSprintTimeMs?: number;
sprintGamesPlayed?: number;
sprintTotalMessages?: number;
sprintIncorrectMessages?: number;
sprintBestScore?: number;
sprintBestAccuracy?: number;
watchGamesPlayed?: number;
watchTotalMessages?: number;
watchIncorrectMessages?: number;
watchBestScore?: number;
watchBestAccuracy?: number;
xpEarned?: number; xpEarned?: number;
}; };
}; };
@ -123,8 +152,31 @@ export async function submitRadioResult(input: {
const runXp = Math.round(input.correctMessages * 0.1 * 10) / 10; const runXp = Math.round(input.correctMessages * 0.1 * 10) / 10;
const gamesPlayed = (current.gamesPlayed ?? 0) + 1; const gamesPlayed = (current.gamesPlayed ?? 0) + 1;
const totalMessages = (current.totalMessages ?? 0) + input.correctMessages; const totalMessages = (current.totalMessages ?? 0) + input.correctMessages;
const incorrectMessages = (current.incorrectMessages ?? 0) + input.incorrectMessages;
const bestScore = Math.max(current.bestScore ?? 0, score); const bestScore = Math.max(current.bestScore ?? 0, score);
const bestAccuracy = Math.round(Math.max(current.bestAccuracy ?? 0, input.accuracy) * 10000) / 10000; const bestAccuracy = Math.round(Math.max(current.bestAccuracy ?? 0, input.accuracy) * 10000) / 10000;
const sprintGamesPlayed = (current.sprintGamesPlayed ?? 0) + (input.mode === "sprint" ? 1 : 0);
const sprintTotalMessages =
(current.sprintTotalMessages ?? 0) + (input.mode === "sprint" ? input.correctMessages : 0);
const sprintIncorrectMessages =
(current.sprintIncorrectMessages ?? 0) + (input.mode === "sprint" ? input.incorrectMessages : 0);
const sprintBestScore =
input.mode === "sprint" ? Math.max(current.sprintBestScore ?? 0, score) : (current.sprintBestScore ?? 0);
const sprintBestAccuracy =
input.mode === "sprint"
? Math.round(Math.max(current.sprintBestAccuracy ?? 0, input.accuracy) * 10000) / 10000
: (current.sprintBestAccuracy ?? 0);
const watchGamesPlayed = (current.watchGamesPlayed ?? 0) + (input.mode === "watch" ? 1 : 0);
const watchTotalMessages =
(current.watchTotalMessages ?? 0) + (input.mode === "watch" ? input.correctMessages : 0);
const watchIncorrectMessages =
(current.watchIncorrectMessages ?? 0) + (input.mode === "watch" ? input.incorrectMessages : 0);
const watchBestScore =
input.mode === "watch" ? Math.max(current.watchBestScore ?? 0, score) : (current.watchBestScore ?? 0);
const watchBestAccuracy =
input.mode === "watch"
? Math.round(Math.max(current.watchBestAccuracy ?? 0, input.accuracy) * 10000) / 10000
: (current.watchBestAccuracy ?? 0);
const previousBestSprintTimeMs = current.bestSprintTimeMs ?? 0; const previousBestSprintTimeMs = current.bestSprintTimeMs ?? 0;
const bestSprintTimeMs = const bestSprintTimeMs =
input.mode === "sprint" && typeof sprintTime === "number" input.mode === "sprint" && typeof sprintTime === "number"
@ -145,9 +197,20 @@ export async function submitRadioResult(input: {
radioTraffic: { radioTraffic: {
gamesPlayed, gamesPlayed,
totalMessages, totalMessages,
incorrectMessages,
bestScore, bestScore,
bestAccuracy, bestAccuracy,
bestSprintTimeMs, bestSprintTimeMs,
sprintGamesPlayed,
sprintTotalMessages,
sprintIncorrectMessages,
sprintBestScore,
sprintBestAccuracy,
watchGamesPlayed,
watchTotalMessages,
watchIncorrectMessages,
watchBestScore,
watchBestAccuracy,
xpEarned: radioTrafficXp, xpEarned: radioTrafficXp,
}, },
}, },
@ -190,9 +253,20 @@ export async function submitRadioResult(input: {
data: { data: {
gamesPlayed, gamesPlayed,
totalMessages, totalMessages,
incorrectMessages,
bestScore, bestScore,
bestAccuracy, bestAccuracy,
bestSprintTimeMs, bestSprintTimeMs,
sprintGamesPlayed,
sprintTotalMessages,
sprintIncorrectMessages,
sprintBestScore,
sprintBestAccuracy,
watchGamesPlayed,
watchTotalMessages,
watchIncorrectMessages,
watchBestScore,
watchBestAccuracy,
radioTrafficXp, radioTrafficXp,
xpEarned: runXp, xpEarned: runXp,
}, },