fix(ai): fix database model mapping for AI matches and missing AI names
This commit is contained in:
@@ -21,7 +21,7 @@ export const AI_LEVELS: StockfishLevel[] = [
|
||||
export class StockfishEngine {
|
||||
private process: ChildProcess | null = null;
|
||||
private ready = false;
|
||||
private resolvers: Array<(move: string) => void> = [];
|
||||
private resolvers: ((move: string) => void)[] = [];
|
||||
private initPromise: Promise<void>;
|
||||
private buffer = "";
|
||||
|
||||
|
||||
@@ -5,20 +5,16 @@ export const activeGames: Game[] = [];
|
||||
|
||||
export const save = async (game: Game) => {
|
||||
try {
|
||||
const white: User = {};
|
||||
const black: User = {};
|
||||
if (typeof game.white?.id === "string") {
|
||||
white.name = game.white?.name;
|
||||
} else {
|
||||
const white: User = { name: game.white?.name };
|
||||
const black: User = { name: game.black?.name };
|
||||
if (typeof game.white?.id !== "string") {
|
||||
white.id = game.white?.id;
|
||||
}
|
||||
if (typeof game.black?.id === "string") {
|
||||
black.name = game.black?.name;
|
||||
} else {
|
||||
if (typeof game.black?.id !== "string") {
|
||||
black.id = game.black?.id;
|
||||
}
|
||||
const res = await db.query(
|
||||
`INSERT INTO "game"(winner, end_reason, pgn, white_id, white_name, black_id, black_name, started_at) VALUES($1, $2, $3, $4, $5, $6, $7, $8) RETURNING *`,
|
||||
`INSERT INTO "game"(winner, end_reason, pgn, white_id, white_name, black_id, black_name, started_at, vs_ai, ai_level) VALUES($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) RETURNING *`,
|
||||
[
|
||||
game.winner || null,
|
||||
game.endReason || null,
|
||||
@@ -27,7 +23,9 @@ export const save = async (game: Game) => {
|
||||
white.name || null,
|
||||
black.id || null,
|
||||
black.name || null,
|
||||
new Date(game.startedAt as number)
|
||||
new Date(game.startedAt as number),
|
||||
game.vsAi || false,
|
||||
game.aiLevel || null
|
||||
]
|
||||
);
|
||||
if (black.id || white.id) {
|
||||
@@ -55,7 +53,7 @@ export const save = async (game: Game) => {
|
||||
return {
|
||||
id: res.rows[0].id,
|
||||
winner: res.rows[0].winner,
|
||||
endReason: res.rows[0].reason,
|
||||
endReason: res.rows[0].end_reason,
|
||||
pgn: res.rows[0].pgn,
|
||||
white: {
|
||||
id: res.rows[0].white_id || undefined,
|
||||
@@ -66,7 +64,9 @@ export const save = async (game: Game) => {
|
||||
name: res.rows[0].black_name || undefined
|
||||
},
|
||||
startedAt: res.rows[0].started_at.getTime(),
|
||||
endedAt: res.rows[0].ended_at?.getTime() || undefined
|
||||
endedAt: res.rows[0].ended_at?.getTime() || undefined,
|
||||
vsAi: res.rows[0].vs_ai || undefined,
|
||||
aiLevel: res.rows[0].ai_level || undefined
|
||||
} as Game;
|
||||
} catch (err: unknown) {
|
||||
console.log(err);
|
||||
@@ -77,7 +77,7 @@ export const save = async (game: Game) => {
|
||||
export const findById = async (id: number) => {
|
||||
try {
|
||||
const res = await db.query(
|
||||
`SELECT game.id, game.winner, game.end_reason, game.pgn, white_user.id AS white_id, COALESCE(white_user.name, game.white_name) AS white_name, black_user.id AS black_id, started_at, ended_at, COALESCE(black_user.name, game.black_name) AS black_name FROM game LEFT JOIN "user" white_user ON white_user.id = game.white_id LEFT JOIN "user" black_user ON black_user.id = game.black_id WHERE game.id=$1`,
|
||||
`SELECT game.id, game.winner, game.end_reason, game.pgn, game.vs_ai, game.ai_level, white_user.id AS white_id, COALESCE(white_user.name, game.white_name) AS white_name, black_user.id AS black_id, started_at, ended_at, COALESCE(black_user.name, game.black_name) AS black_name FROM game LEFT JOIN "user" white_user ON white_user.id = game.white_id LEFT JOIN "user" black_user ON black_user.id = game.black_id WHERE game.id=$1`,
|
||||
[id]
|
||||
);
|
||||
if (res.rowCount) {
|
||||
@@ -89,7 +89,9 @@ export const findById = async (id: number) => {
|
||||
white: { id: res.rows[0].white_id || undefined, name: res.rows[0].white_name },
|
||||
black: { id: res.rows[0].black_id || undefined, name: res.rows[0].black_name },
|
||||
startedAt: res.rows[0].started_at.getTime(),
|
||||
endedAt: res.rows[0].ended_at?.getTime() || undefined
|
||||
endedAt: res.rows[0].ended_at?.getTime() || undefined,
|
||||
vsAi: res.rows[0].vs_ai || undefined,
|
||||
aiLevel: res.rows[0].ai_level || undefined
|
||||
} as Game;
|
||||
} else return null;
|
||||
} catch (err: unknown) {
|
||||
@@ -105,7 +107,7 @@ export const findByUserId = async (id: number, limit = 10) => {
|
||||
try {
|
||||
// TODO: pagination
|
||||
const res = await db.query(
|
||||
`SELECT game.id, game.winner, game.end_reason, game.pgn, white_user.id AS white_id, COALESCE(white_user.name, game.white_name) AS white_name, black_user.id AS black_id, started_at, ended_at, COALESCE(black_user.name, game.black_name) AS black_name FROM game LEFT JOIN "user" white_user ON white_user.id = game.white_id LEFT JOIN "user" black_user ON black_user.id = game.black_id WHERE white_user.id=$1 OR black_user.id=$1 ORDER BY id DESC LIMIT $2`,
|
||||
`SELECT game.id, game.winner, game.end_reason, game.pgn, game.vs_ai, game.ai_level, white_user.id AS white_id, COALESCE(white_user.name, game.white_name) AS white_name, black_user.id AS black_id, started_at, ended_at, COALESCE(black_user.name, game.black_name) AS black_name FROM game LEFT JOIN "user" white_user ON white_user.id = game.white_id LEFT JOIN "user" black_user ON black_user.id = game.black_id WHERE white_user.id=$1 OR black_user.id=$1 ORDER BY id DESC LIMIT $2`,
|
||||
[id, limit]
|
||||
);
|
||||
return res.rows.map((r) => {
|
||||
@@ -117,7 +119,9 @@ export const findByUserId = async (id: number, limit = 10) => {
|
||||
white: { id: r.white_id || undefined, name: r.white_name },
|
||||
black: { id: r.black_id || undefined, name: r.black_name },
|
||||
startedAt: r.started_at.getTime(),
|
||||
endedAt: r.ended_at?.getTime() || undefined
|
||||
endedAt: r.ended_at?.getTime() || undefined,
|
||||
vsAi: r.vs_ai || undefined,
|
||||
aiLevel: r.ai_level || undefined
|
||||
} as Game;
|
||||
});
|
||||
} catch (err: unknown) {
|
||||
@@ -137,7 +141,9 @@ export const remove = async (id: number) => {
|
||||
white: { id: res.rows[0].white_id, name: res.rows[0].white_name },
|
||||
black: { id: res.rows[0].black_id, name: res.rows[0].black_name },
|
||||
startedAt: res.rows[0].started_at.getTime(),
|
||||
endedAt: res.rows[0].ended_at?.getTime() || undefined
|
||||
endedAt: res.rows[0].ended_at?.getTime() || undefined,
|
||||
vsAi: res.rows[0].vs_ai || undefined,
|
||||
aiLevel: res.rows[0].ai_level || undefined
|
||||
} as Game;
|
||||
} catch (err: unknown) {
|
||||
console.log(err);
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import express from "express";
|
||||
import type { Request, Response } from "express";
|
||||
import { AI_LEVELS, getEngine } from "../controllers/stockfish.controller.js";
|
||||
import { requireAuth } from "../middleware/auth.js";
|
||||
import GameModel from "../db/models/game.model.js";
|
||||
import type { Game } from "@michess/types";
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
@@ -28,4 +31,40 @@ router.get("/levels", (_req: Request, res: Response) => {
|
||||
res.status(200).json(AI_LEVELS.map(({ level, name }) => ({ level, name })));
|
||||
});
|
||||
|
||||
router.post("/save", requireAuth, async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { pgn, winner, endReason, playerColor, level, startedAt } = req.body;
|
||||
const user = req.session.user!;
|
||||
|
||||
if (!pgn || !winner || !endReason || !playerColor) {
|
||||
res.status(400).json({ message: "Missing required fields." });
|
||||
return;
|
||||
}
|
||||
|
||||
const humanPlayer = { id: user.id as number, name: user.name };
|
||||
const aiPlayer = { name: `Stockfish` };
|
||||
|
||||
const game: Game = {
|
||||
pgn,
|
||||
winner,
|
||||
endReason,
|
||||
white: playerColor === "white" ? humanPlayer : aiPlayer,
|
||||
black: playerColor === "black" ? humanPlayer : aiPlayer,
|
||||
startedAt: startedAt || Date.now(),
|
||||
vsAi: true,
|
||||
aiLevel: level || null
|
||||
};
|
||||
|
||||
const saved = await GameModel.save(game);
|
||||
if (!saved) {
|
||||
res.status(500).json({ message: "Failed to save game." });
|
||||
return;
|
||||
}
|
||||
res.status(200).json({ id: saved.id });
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
res.status(500).end();
|
||||
}
|
||||
});
|
||||
|
||||
export default router;
|
||||
|
||||
@@ -53,7 +53,7 @@ app.use("/v1", (req: Request, res: Response, next: NextFunction) => {
|
||||
if (req.session.user?.id && typeof req.session.user.id === "number") {
|
||||
const user = req.session.user as { banned?: boolean };
|
||||
if (user.banned) {
|
||||
req.session.destroy(() => {});
|
||||
req.session.destroy((err) => { if (err) console.error(err); });
|
||||
res.status(403).json({ message: "Your account has been banned." });
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user