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:
parent
4703a24dfe
commit
0b012f07d8
1 changed files with 76 additions and 2 deletions
|
|
@ -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,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue