make mines use redis

This commit is contained in:
Face 2025-06-24 12:53:52 +03:00
parent ad1739f7f4
commit af18d7f423
4 changed files with 56 additions and 52 deletions

View file

@ -3,7 +3,8 @@ import { error, json } from '@sveltejs/kit';
import { db } from '$lib/server/db';
import { user } from '$lib/server/db/schema';
import { eq } from 'drizzle-orm';
import { activeGames } from '$lib/server/games/mines';
import { redis } from '$lib/server/redis';
import { getSessionKey } from '$lib/server/games/mines';
import type { RequestHandler } from './$types';
export const POST: RequestHandler = async ({ request }) => {
@ -17,7 +18,8 @@ export const POST: RequestHandler = async ({ request }) => {
try {
const { sessionToken } = await request.json();
const game = activeGames.get(sessionToken);
const sessionRaw = await redis.get(getSessionKey(sessionToken));
const game = sessionRaw ? JSON.parse(sessionRaw) : null;
const userId = Number(session.user.id);
if (!game) {
@ -36,18 +38,16 @@ export const POST: RequestHandler = async ({ request }) => {
let payout: number;
let newBalance: number;
// If no tiles revealed, treat as abort and return full bet. This could be changed later to keep the initial bet on the Server
// If no tiles revealed, treat as abort and return full bet.
if (game.revealedTiles.length === 0) {
payout = game.betAmount;
newBalance = Math.round((currentBalance + payout) * 100000000) / 100000000;
} else {
// Calculate payout
payout = game.betAmount * game.currentMultiplier;
const roundedPayout = Math.round(payout * 100000000) / 100000000;
newBalance = Math.round((currentBalance + roundedPayout) * 100000000) / 100000000;
}
await tx
.update(user)
.set({
@ -56,8 +56,7 @@ export const POST: RequestHandler = async ({ request }) => {
})
.where(eq(user.id, userId));
activeGames.delete(sessionToken);
await redis.del(getSessionKey(sessionToken));
return {
newBalance,
@ -74,4 +73,4 @@ export const POST: RequestHandler = async ({ request }) => {
const errorMessage = e instanceof Error ? e.message : 'Internal server error';
return json({ error: errorMessage }, { status: 400 });
}
};
};

View file

@ -1,10 +1,12 @@
import { auth } from '$lib/auth';
import { error, json } from '@sveltejs/kit';
import { activeGames, calculateMultiplier } from '$lib/server/games/mines';
import { calculateMultiplier } from '$lib/server/games/mines';
import type { RequestHandler } from './$types';
import { db } from '$lib/server/db';
import { user } from '$lib/server/db/schema';
import { eq } from 'drizzle-orm';
import { redis, } from '$lib/server/redis';
import { getSessionKey } from '$lib/server/games/mines';
export const POST: RequestHandler = async ({ request }) => {
const session = await auth.api.getSession({
@ -17,7 +19,8 @@ export const POST: RequestHandler = async ({ request }) => {
try {
const { sessionToken, tileIndex } = await request.json();
const game = activeGames.get(sessionToken);
const sessionRaw = await redis.get(getSessionKey(sessionToken));
const game = sessionRaw ? JSON.parse(sessionRaw) : null;
if (!game) {
return json({ error: 'Invalid session' }, { status: 400 });
@ -29,7 +32,6 @@ export const POST: RequestHandler = async ({ request }) => {
game.lastActivity = Date.now();
if (game.minePositions.includes(tileIndex)) {
game.status = 'lost';
const minePositions = game.minePositions;
@ -44,7 +46,6 @@ export const POST: RequestHandler = async ({ request }) => {
const currentBalance = Number(userData.baseCurrencyBalance);
await db
.update(user)
.set({
@ -53,9 +54,8 @@ export const POST: RequestHandler = async ({ request }) => {
})
.where(eq(user.id, userId));
activeGames.delete(sessionToken);
await redis.del(getSessionKey(sessionToken));
return json({
hitMine: true,
minePositions,
@ -65,15 +65,14 @@ export const POST: RequestHandler = async ({ request }) => {
});
}
// Safe tile (Yipeee)
// Safe tile
game.revealedTiles.push(tileIndex);
game.currentMultiplier = calculateMultiplier(
game.revealedTiles.length,
game.mineCount,
game.betAmount
);
if (game.revealedTiles.length === 25 - game.mineCount) {
game.status = 'won';
const userId = Number(session.user.id);
@ -97,7 +96,7 @@ export const POST: RequestHandler = async ({ request }) => {
})
.where(eq(user.id, userId));
activeGames.delete(sessionToken);
await redis.del(getSessionKey(sessionToken));
return json({
hitMine: false,
@ -108,6 +107,8 @@ export const POST: RequestHandler = async ({ request }) => {
});
}
await redis.set(getSessionKey(sessionToken), JSON.stringify(game));
return json({
hitMine: false,
currentMultiplier: game.currentMultiplier,
@ -118,4 +119,4 @@ export const POST: RequestHandler = async ({ request }) => {
const errorMessage = e instanceof Error ? e.message : 'Internal server error';
return json({ error: errorMessage }, { status: 400 });
}
};
};

View file

@ -3,7 +3,8 @@ import { error, json } from '@sveltejs/kit';
import { db } from '$lib/server/db';
import { user } from '$lib/server/db/schema';
import { eq } from 'drizzle-orm';
import { activeGames } from '$lib/server/games/mines';
import { redis } from '$lib/server/redis';
import { getSessionKey } from '$lib/server/games/mines';
import type { RequestHandler } from './$types';
export const POST: RequestHandler = async ({ request }) => {
@ -43,17 +44,12 @@ export const POST: RequestHandler = async ({ request }) => {
throw new Error(`Insufficient funds. You need *${roundedAmount.toFixed(2)} but only have *${roundedBalance.toFixed(2)}`);
}
// Generate mine positions
const positions = new Set<number>();
while (positions.size < mineCount) {
positions.add(Math.floor(Math.random() * 25));
}
const safePositions = [];
for (let i = 0; i < 25; i++) {
if (!positions.has(i)) safePositions.push(i);
}
// transaction token for authentication stuff
const randomBytes = new Uint8Array(8);
crypto.getRandomValues(randomBytes);
@ -64,19 +60,21 @@ export const POST: RequestHandler = async ({ request }) => {
const now = Date.now();
const newBalance = roundedBalance - roundedAmount;
// Create session
activeGames.set(sessionToken, {
sessionToken,
betAmount: roundedAmount,
mineCount,
minePositions: Array.from(positions),
revealedTiles: [],
startTime: now,
lastActivity: now,
currentMultiplier: 1,
status: 'active',
userId
});
await redis.set(
getSessionKey(sessionToken),
JSON.stringify({
sessionToken,
betAmount: roundedAmount,
mineCount,
minePositions: Array.from(positions),
revealedTiles: [],
startTime: now,
lastActivity: now,
currentMultiplier: 1,
status: 'active',
userId
})
);
// Update user balance
await tx
@ -87,7 +85,6 @@ export const POST: RequestHandler = async ({ request }) => {
})
.where(eq(user.id, userId));
return {
sessionToken,
newBalance
@ -100,4 +97,4 @@ export const POST: RequestHandler = async ({ request }) => {
const errorMessage = e instanceof Error ? e.message : 'Internal server error';
return json({ error: errorMessage }, { status: 400 });
}
};
};