Add discreet anticheat mechanism for the games
Build and deploy / deploy (push) Failing after 32s

This commit is contained in:
2026-08-24 12:07:10 +02:00
parent 35704e50fc
commit b7f3f8b0fa
6 changed files with 230 additions and 53 deletions
+35 -18
View File
@@ -271,23 +271,22 @@ function drawSpeedLines(ctx: CanvasRenderingContext2D, centerX: number, centerY:
ctx.restore();
}
export type IcarusRunTelemetry = {
v: 1;
duration_ms: number;
actions: number;
};
export function IcarusGame({
onStart,
onFinish,
}: {
onStart: () => void;
onFinish: (score: number) => void;
onFinish: (score: number, run: IcarusRunTelemetry) => void;
}) {
const canvasRef = useRef<HTMLCanvasElement | null>(null);
const containerRef = useRef<HTMLDivElement | null>(null);
const [status, setStatus] = useState<Status>("idle");
const [score, setScore] = useState(0);
const onStartRef = useRef(onStart);
useEffect(() => {
onStartRef.current = onStart;
}, [onStart]);
const onFinishRef = useRef(onFinish);
useEffect(() => {
onFinishRef.current = onFinish;
@@ -306,6 +305,8 @@ export function IcarusGame({
const boostDashAtRef = useRef<number | null>(null);
const shatterEffectsRef = useRef<ShatterEffect[]>([]);
const nextEntityIdRef = useRef(0);
const runStartedAtRef = useRef<number | null>(null);
const actionCountRef = useRef(0);
const resetGame = useCallback(() => {
icarusRef.current = createInitialIcarus();
@@ -320,19 +321,28 @@ export function IcarusGame({
boostColumnsRemainingRef.current = 0;
boostDashAtRef.current = null;
shatterEffectsRef.current = [];
runStartedAtRef.current = null;
actionCountRef.current = 0;
setStatus("idle");
setScore(0);
}, []);
const requestFlap = useCallback(() => {
flapRequestedRef.current = true;
if (statusRef.current === "dead") {
resetGame();
return;
}
if (statusRef.current === "idle") {
runStartedAtRef.current = Date.now();
actionCountRef.current = 1;
statusRef.current = "flying";
setStatus("flying");
onStartRef.current();
} else if (statusRef.current === "dead") {
resetGame();
} else {
actionCountRef.current += 1;
}
flapRequestedRef.current = true;
}, [resetGame]);
// Sur ordinateur (pas de tap tactile) : la barre d'espace fait la même
@@ -383,6 +393,17 @@ export function IcarusGame({
let lastFrame: number | null = null;
let accumulator = 0;
function finishRun() {
statusRef.current = "dead";
setStatus("dead");
const startedAt = runStartedAtRef.current;
onFinishRef.current(scoreRef.current, {
v: 1,
duration_ms: startedAt === null ? 0 : Math.max(0, Date.now() - startedAt),
actions: actionCountRef.current,
});
}
function frame(now: number) {
if (lastFrame === null) lastFrame = now;
const frameDt = Math.min(now - lastFrame, MAX_FRAME_DT_MS);
@@ -505,17 +526,13 @@ export function IcarusGame({
columnsRef.current = columnsRef.current.filter((c) => !broken.includes(c));
setScore(scoreRef.current);
} else {
statusRef.current = "dead";
setStatus("dead");
onFinishRef.current(scoreRef.current);
finishRun();
break;
}
}
if (boostColumnsRemainingRef.current === 0 && hasHitGround(icarusRef.current)) {
statusRef.current = "dead";
setStatus("dead");
onFinishRef.current(scoreRef.current);
finishRun();
break;
}