fix input limits, use redis SCAN, move interval to hooks
This commit is contained in:
parent
6e93a2905b
commit
a352314d42
4 changed files with 40 additions and 16 deletions
|
|
@ -7,6 +7,7 @@ import { redirect, type Handle } from '@sveltejs/kit';
|
||||||
import { db } from '$lib/server/db';
|
import { db } from '$lib/server/db';
|
||||||
import { user } from '$lib/server/db/schema';
|
import { user } from '$lib/server/db/schema';
|
||||||
import { eq } from 'drizzle-orm';
|
import { eq } from 'drizzle-orm';
|
||||||
|
import { minesCleanupInactiveGames, minesAutoCashout } from '$lib/server/games/mines';
|
||||||
|
|
||||||
async function initializeScheduler() {
|
async function initializeScheduler() {
|
||||||
if (building) return;
|
if (building) return;
|
||||||
|
|
@ -49,10 +50,16 @@ async function initializeScheduler() {
|
||||||
processAccountDeletions().catch(console.error);
|
processAccountDeletions().catch(console.error);
|
||||||
}, 5 * 60 * 1000);
|
}, 5 * 60 * 1000);
|
||||||
|
|
||||||
|
const minesCleanupInterval = setInterval(() => {
|
||||||
|
minesCleanupInactiveGames().catch(console.error);
|
||||||
|
minesAutoCashout().catch(console.error);
|
||||||
|
}, 60 * 1000);
|
||||||
|
|
||||||
// Cleanup on process exit
|
// Cleanup on process exit
|
||||||
const cleanup = async () => {
|
const cleanup = async () => {
|
||||||
clearInterval(renewInterval);
|
clearInterval(renewInterval);
|
||||||
clearInterval(schedulerInterval);
|
clearInterval(schedulerInterval);
|
||||||
|
clearInterval(minesCleanupInterval);
|
||||||
const currentValue = await redis.get(lockKey);
|
const currentValue = await redis.get(lockKey);
|
||||||
if (currentValue === lockValue) {
|
if (currentValue === lockValue) {
|
||||||
await redis.del(lockKey);
|
await redis.del(lockKey);
|
||||||
|
|
|
||||||
|
|
@ -19,10 +19,16 @@ interface MinesSession {
|
||||||
const MINES_SESSION_PREFIX = 'mines:session:';
|
const MINES_SESSION_PREFIX = 'mines:session:';
|
||||||
export const getSessionKey = (token: string) => `${MINES_SESSION_PREFIX}${token}`;
|
export const getSessionKey = (token: string) => `${MINES_SESSION_PREFIX}${token}`;
|
||||||
|
|
||||||
// Clean up old games every minute. (5 Minute system)
|
// --- Mines cleanup logic for scheduler ---
|
||||||
setInterval(async () => {
|
export async function minesCleanupInactiveGames() {
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const keys = await redis.keys(`${MINES_SESSION_PREFIX}*`);
|
const keys: string[] = [];
|
||||||
|
let cursor = '0';
|
||||||
|
do {
|
||||||
|
const scanResult = await redis.scan(cursor, { MATCH: `${MINES_SESSION_PREFIX}*` });
|
||||||
|
cursor = scanResult.cursor;
|
||||||
|
keys.push(...scanResult.keys);
|
||||||
|
} while (cursor !== '0');
|
||||||
for (const key of keys) {
|
for (const key of keys) {
|
||||||
const sessionRaw = await redis.get(key);
|
const sessionRaw = await redis.get(key);
|
||||||
if (!sessionRaw) continue;
|
if (!sessionRaw) continue;
|
||||||
|
|
@ -54,11 +60,17 @@ setInterval(async () => {
|
||||||
await redis.del(getSessionKey(game.sessionToken));
|
await redis.del(getSessionKey(game.sessionToken));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 60000);
|
}
|
||||||
|
|
||||||
setInterval(async () => {
|
export async function minesAutoCashout() {
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const keys = await redis.keys(`${MINES_SESSION_PREFIX}*`);
|
const keys: string[] = [];
|
||||||
|
let cursor = '0';
|
||||||
|
do {
|
||||||
|
const scanResult = await redis.scan(cursor, { MATCH: `${MINES_SESSION_PREFIX}*` });
|
||||||
|
cursor = scanResult.cursor;
|
||||||
|
keys.push(...scanResult.keys);
|
||||||
|
} while (cursor !== '0');
|
||||||
for (const key of keys) {
|
for (const key of keys) {
|
||||||
const sessionRaw = await redis.get(key);
|
const sessionRaw = await redis.get(key);
|
||||||
if (!sessionRaw) continue;
|
if (!sessionRaw) continue;
|
||||||
|
|
@ -97,7 +109,7 @@ setInterval(async () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 15000);
|
}
|
||||||
|
|
||||||
const getMaxPayout = (bet: number, picks: number, mines: number): number => {
|
const getMaxPayout = (bet: number, picks: number, mines: number): number => {
|
||||||
const MAX_PAYOUT = 2_000_000;
|
const MAX_PAYOUT = 2_000_000;
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,11 @@ export const POST: RequestHandler = async ({ request }) => {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { sessionToken, tileIndex } = await request.json();
|
const { sessionToken, tileIndex } = await request.json();
|
||||||
|
|
||||||
|
if (!Number.isInteger(tileIndex) || tileIndex < 0 || tileIndex > 24) {
|
||||||
|
return json({ error: 'Invalid tileIndex' }, { status: 400 });
|
||||||
|
}
|
||||||
|
|
||||||
const sessionRaw = await redis.get(getSessionKey(sessionToken));
|
const sessionRaw = await redis.get(getSessionKey(sessionToken));
|
||||||
const game = sessionRaw ? JSON.parse(sessionRaw) : null;
|
const game = sessionRaw ? JSON.parse(sessionRaw) : null;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ export const POST: RequestHandler = async ({ request }) => {
|
||||||
const { betAmount, mineCount } = await request.json();
|
const { betAmount, mineCount } = await request.json();
|
||||||
const userId = Number(session.user.id);
|
const userId = Number(session.user.id);
|
||||||
|
|
||||||
if (!betAmount || !mineCount || mineCount < 3 || mineCount > 24) {
|
if (!betAmount || betAmount <= 0 || !mineCount || mineCount < 3 || mineCount > 24) {
|
||||||
return json({ error: 'Invalid bet amount or mine count' }, { status: 400 });
|
return json({ error: 'Invalid bet amount or mine count' }, { status: 400 });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Reference in a new issue