count game history stats for users
This commit is contained in:
@@ -119,6 +119,10 @@ export const registerUser = async (req: Request, res: Response) => {
|
|||||||
throw new Error("Failed to create user");
|
throw new Error("Failed to create user");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const publicUser = {
|
||||||
|
id: newUser.id,
|
||||||
|
name: newUser.name
|
||||||
|
};
|
||||||
if (req.session.user?.id && typeof req.session.user.id === "string") {
|
if (req.session.user?.id && typeof req.session.user.id === "string") {
|
||||||
const game = activeGames.find(
|
const game = activeGames.find(
|
||||||
(g) =>
|
(g) =>
|
||||||
@@ -128,17 +132,17 @@ export const registerUser = async (req: Request, res: Response) => {
|
|||||||
);
|
);
|
||||||
if (game) {
|
if (game) {
|
||||||
if (game.host?.id === req.session.user.id) {
|
if (game.host?.id === req.session.user.id) {
|
||||||
game.host = newUser;
|
game.host = publicUser;
|
||||||
}
|
}
|
||||||
if (game.white && game.white?.id === req.session.user.id) {
|
if (game.white && game.white?.id === req.session.user.id) {
|
||||||
game.white = newUser;
|
game.white = publicUser;
|
||||||
} else if (game.black && game.black?.id === req.session.user.id) {
|
} else if (game.black && game.black?.id === req.session.user.id) {
|
||||||
game.black = newUser;
|
game.black = publicUser;
|
||||||
} else {
|
} else {
|
||||||
const observer = game.observers?.find((o) => o.id === req.session.user.id);
|
const observer = game.observers?.find((o) => o.id === req.session.user.id);
|
||||||
if (observer) {
|
if (observer) {
|
||||||
observer.id = newUser.id;
|
observer.id = publicUser.id;
|
||||||
observer.name = newUser.name;
|
observer.name = publicUser.name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
io.to(game.code as string).emit("receivedLatestGame", game);
|
io.to(game.code as string).emit("receivedLatestGame", game);
|
||||||
@@ -180,10 +184,9 @@ export const loginUser = async (req: Request, res: Response) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const newUser = {
|
const publicUser = {
|
||||||
id: users[0].id,
|
id: users[0].id,
|
||||||
name: users[0].name,
|
name: users[0].name
|
||||||
email: users[0].email
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (req.session.user?.id && typeof req.session.user.id === "string") {
|
if (req.session.user?.id && typeof req.session.user.id === "string") {
|
||||||
@@ -195,17 +198,17 @@ export const loginUser = async (req: Request, res: Response) => {
|
|||||||
);
|
);
|
||||||
if (game) {
|
if (game) {
|
||||||
if (game.host?.id === req.session.user.id) {
|
if (game.host?.id === req.session.user.id) {
|
||||||
game.host = newUser;
|
game.host = publicUser;
|
||||||
}
|
}
|
||||||
if (game.white && game.white?.id === req.session.user.id) {
|
if (game.white && game.white?.id === req.session.user.id) {
|
||||||
game.white = newUser;
|
game.white = publicUser;
|
||||||
} else if (game.black && game.black?.id === req.session.user.id) {
|
} else if (game.black && game.black?.id === req.session.user.id) {
|
||||||
game.black = newUser;
|
game.black = publicUser;
|
||||||
} else {
|
} else {
|
||||||
const observer = game.observers?.find((o) => o.id === req.session.user.id);
|
const observer = game.observers?.find((o) => o.id === req.session.user.id);
|
||||||
if (observer) {
|
if (observer) {
|
||||||
observer.id = newUser.id;
|
observer.id = publicUser.id;
|
||||||
observer.name = newUser.name;
|
observer.name = publicUser.name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
io.to(game.code as string).emit("receivedLatestGame", game);
|
io.to(game.code as string).emit("receivedLatestGame", game);
|
||||||
@@ -214,7 +217,11 @@ export const loginUser = async (req: Request, res: Response) => {
|
|||||||
|
|
||||||
req.session.user = {
|
req.session.user = {
|
||||||
id: users[0].id,
|
id: users[0].id,
|
||||||
name: users[0].name
|
name: users[0].name,
|
||||||
|
email: users[0].email,
|
||||||
|
wins: users[0].wins,
|
||||||
|
losses: users[0].losses,
|
||||||
|
draws: users[0].draws
|
||||||
};
|
};
|
||||||
req.session.save(() => {
|
req.session.save(() => {
|
||||||
res.status(200).json(req.session.user);
|
res.status(200).json(req.session.user);
|
||||||
@@ -263,6 +270,35 @@ export const updateUser = async (req: Request, res: Response) => {
|
|||||||
throw new Error("Failed to update user");
|
throw new Error("Failed to update user");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const publicUser = {
|
||||||
|
id: updatedUser.id,
|
||||||
|
name: updatedUser.name
|
||||||
|
};
|
||||||
|
|
||||||
|
const game = activeGames.find(
|
||||||
|
(g) =>
|
||||||
|
g.white?.id === req.session.user.id ||
|
||||||
|
g.black?.id === req.session.user.id ||
|
||||||
|
g.observers?.find((o) => o.id === req.session.user.id)
|
||||||
|
);
|
||||||
|
if (game) {
|
||||||
|
if (game.host?.id === req.session.user.id) {
|
||||||
|
game.host = publicUser;
|
||||||
|
}
|
||||||
|
if (game.white && game.white?.id === req.session.user.id) {
|
||||||
|
game.white = publicUser;
|
||||||
|
} else if (game.black && game.black?.id === req.session.user.id) {
|
||||||
|
game.black = publicUser;
|
||||||
|
} else {
|
||||||
|
const observer = game.observers?.find((o) => o.id === req.session.user.id);
|
||||||
|
if (observer) {
|
||||||
|
observer.id = publicUser.id;
|
||||||
|
observer.name = publicUser.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
io.to(game.code as string).emit("receivedLatestGame", game);
|
||||||
|
}
|
||||||
|
|
||||||
req.session.user = updatedUser;
|
req.session.user = updatedUser;
|
||||||
req.session.save(() => {
|
req.session.save(() => {
|
||||||
res.status(200).json(req.session.user);
|
res.status(200).json(req.session.user);
|
||||||
|
|||||||
@@ -8,6 +8,9 @@ export const INIT_TABLES = /* sql */ `
|
|||||||
name VARCHAR(128) UNIQUE NOT NULL,
|
name VARCHAR(128) UNIQUE NOT NULL,
|
||||||
email VARCHAR(128),
|
email VARCHAR(128),
|
||||||
password TEXT,
|
password TEXT,
|
||||||
|
wins INTEGER DEFAULT 0,
|
||||||
|
losses INTEGER DEFAULT 0,
|
||||||
|
draws INTEGER DEFAULT 0,
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
);
|
);
|
||||||
CREATE TABLE IF NOT EXISTS "game" (
|
CREATE TABLE IF NOT EXISTS "game" (
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ export const activeGames: Array<Game> = [];
|
|||||||
|
|
||||||
// todo: join user and game relationship
|
// todo: join user and game relationship
|
||||||
|
|
||||||
export const create = async (game: Game) => {
|
export const save = async (game: Game) => {
|
||||||
try {
|
try {
|
||||||
const white: User = {};
|
const white: User = {};
|
||||||
const black: User = {};
|
const black: User = {};
|
||||||
@@ -31,6 +31,28 @@ export const create = async (game: Game) => {
|
|||||||
black.name || null
|
black.name || null
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
if (black.id || white.id) {
|
||||||
|
// draws
|
||||||
|
if (game.winner === "draw") {
|
||||||
|
if (white.id) {
|
||||||
|
await db.query(`UPDATE "user" SET draws = draws + 1 WHERE id = $1`, [white.id]);
|
||||||
|
}
|
||||||
|
if (black.id) {
|
||||||
|
await db.query(`UPDATE "user" SET draws = draws + 1 WHERE id = $1`, [black.id]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const winner = game.winner === "white" ? white : black;
|
||||||
|
const loser = game.winner === "white" ? black : white;
|
||||||
|
if (winner.id) {
|
||||||
|
await db.query(`UPDATE "user" SET wins = wins + 1 WHERE id = $1`, [winner.id]);
|
||||||
|
}
|
||||||
|
if (loser.id) {
|
||||||
|
await db.query(`UPDATE "user" SET losses = losses + 1 WHERE id = $1`, [
|
||||||
|
loser.id
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
id: res.rows[0].id,
|
id: res.rows[0].id,
|
||||||
winner: res.rows[0].winner,
|
winner: res.rows[0].winner,
|
||||||
@@ -135,7 +157,7 @@ export const remove = async (id: number) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const GameModel = {
|
const GameModel = {
|
||||||
create,
|
save,
|
||||||
findById,
|
findById,
|
||||||
findByUserId,
|
findByUserId,
|
||||||
update,
|
update,
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ export const create = async (user: User, password: string) => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await db.query(
|
const res = await db.query(
|
||||||
`INSERT INTO "user"(name, email, password) VALUES($1, $2, $3) RETURNING id, name, email`,
|
`INSERT INTO "user"(name, email, password) VALUES($1, $2, $3) RETURNING id, name, email, wins, losses, draws`,
|
||||||
[user.name, user.email || null, password]
|
[user.name, user.email || null, password]
|
||||||
);
|
);
|
||||||
return res.rows[0] as User;
|
return res.rows[0] as User;
|
||||||
@@ -23,7 +23,10 @@ export const findById = async (id: number) => {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const res = await db.query(`SELECT id, name, email FROM "user" WHERE id=$1`, [id]);
|
const res = await db.query(
|
||||||
|
`SELECT id, name, email, wins, losses, draws FROM "user" WHERE id=$1`,
|
||||||
|
[id]
|
||||||
|
);
|
||||||
if (res.rowCount) {
|
if (res.rowCount) {
|
||||||
return res.rows[0] as User;
|
return res.rows[0] as User;
|
||||||
} else return null;
|
} else return null;
|
||||||
@@ -37,9 +40,10 @@ export const findByNameEmail = async (user: User, includePassword = false, limit
|
|||||||
// if user is not specified, get all users
|
// if user is not specified, get all users
|
||||||
if (!user) {
|
if (!user) {
|
||||||
try {
|
try {
|
||||||
const res = await db.query(`SELECT id, name, email FROM "user" LIMIT $1`, [
|
const res = await db.query(
|
||||||
limit ?? 10
|
`SELECT id, name, email, wins, losses, draws FROM "user" LIMIT $1`,
|
||||||
]);
|
[limit ?? 10]
|
||||||
|
);
|
||||||
return res.rows as Array<User & { password?: string }>;
|
return res.rows as Array<User & { password?: string }>;
|
||||||
} catch (err: unknown) {
|
} catch (err: unknown) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
@@ -49,7 +53,7 @@ export const findByNameEmail = async (user: User, includePassword = false, limit
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await db.query(
|
const res = await db.query(
|
||||||
`SELECT id, name, email${
|
`SELECT id, name, email, wins, losses, draws${
|
||||||
includePassword ? `, password` : ""
|
includePassword ? `, password` : ""
|
||||||
} FROM "user" WHERE name=$1 OR email=$2 LIMIT $3`,
|
} FROM "user" WHERE name=$1 OR email=$2 LIMIT $3`,
|
||||||
[user.name, user.email, limit ?? 1]
|
[user.name, user.email, limit ?? 1]
|
||||||
@@ -67,11 +71,11 @@ export const update = async (id: number, updatedUser: User & { password?: string
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let query = `UPDATE "user" SET name=$1, email=$2 WHERE id=$3 RETURNING id, name, email`;
|
let query = `UPDATE "user" SET name=$1, email=$2 WHERE id=$3 RETURNING id, name, email, wins, losses, draws`;
|
||||||
let values = [updatedUser.name, updatedUser.email, id];
|
let values = [updatedUser.name, updatedUser.email, id];
|
||||||
|
|
||||||
if (updatedUser.password) {
|
if (updatedUser.password) {
|
||||||
query = `UPDATE "user" SET name=$1, email=$2, password=$3 WHERE id=$4 RETURNING id, name, email`;
|
query = `UPDATE "user" SET name=$1, email=$2, password=$3 WHERE id=$4 RETURNING id, name, email, wins, losses, draws`;
|
||||||
values = [updatedUser.name, updatedUser.email, updatedUser.password, id];
|
values = [updatedUser.name, updatedUser.email, updatedUser.password, id];
|
||||||
}
|
}
|
||||||
const res = await db.query(query, values);
|
const res = await db.query(query, values);
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ export async function claimAbandoned(this: Socket, type: "win" | "draw") {
|
|||||||
game.winner = "black";
|
game.winner = "black";
|
||||||
}
|
}
|
||||||
|
|
||||||
const { id } = (await GameModel.create(game)) as Game;
|
const { id } = (await GameModel.save(game)) as Game;
|
||||||
game.id = id;
|
game.id = id;
|
||||||
|
|
||||||
const gameOver = {
|
const gameOver = {
|
||||||
@@ -202,7 +202,7 @@ export async function sendMove(this: Socket, m: { from: string; to: string; prom
|
|||||||
}
|
}
|
||||||
game.endReason = reason;
|
game.endReason = reason;
|
||||||
|
|
||||||
const { id } = (await GameModel.create(game)) as Game; // save game to db
|
const { id } = (await GameModel.save(game)) as Game; // save game to db
|
||||||
game.id = id;
|
game.id = id;
|
||||||
io.to(game.code as string).emit("gameOver", { reason, winnerName, winnerSide, id });
|
io.to(game.code as string).emit("gameOver", { reason, winnerName, winnerSide, id });
|
||||||
}
|
}
|
||||||
|
|||||||
3
types/index.d.ts
vendored
3
types/index.d.ts
vendored
@@ -16,6 +16,9 @@ export interface User {
|
|||||||
id?: number | string; // string for guest IDs
|
id?: number | string; // string for guest IDs
|
||||||
name?: string | null;
|
name?: string | null;
|
||||||
email?: string;
|
email?: string;
|
||||||
|
wins?: number;
|
||||||
|
losses?: number;
|
||||||
|
draws?: number;
|
||||||
|
|
||||||
// mainly for players, not spectators
|
// mainly for players, not spectators
|
||||||
connected?: boolean;
|
connected?: boolean;
|
||||||
|
|||||||
Reference in New Issue
Block a user