Skip to content

Commit 77b237d

Browse files
feat(version): v1.0.1
1 parent dc723d0 commit 77b237d

File tree

4 files changed

+106
-68
lines changed

4 files changed

+106
-68
lines changed

server/.env.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
PORT=<YOU-PORT-HERE>

server/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,11 @@
2121
"typescript": "^5.7.3"
2222
},
2323
"dependencies": {
24+
"colors": "^1.4.0",
25+
"dotenv": "^16.4.7",
2426
"express": "^4.21.2",
25-
"socket.io": "^4.8.1"
27+
"socket.io": "^4.8.1",
28+
"winston": "^3.17.0"
2629
},
2730
"engines": {
2831
"npm": ">=8",

server/src/functions/logger.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { createLogger as createWinstonLogger, format, transports, Logger } from "winston";
2+
import colors from "colors";
3+
4+
/**
5+
* Creates a logger with colored output for console.
6+
*
7+
* @param {string | number} [context="Socket"] - The context identifier for the logger.
8+
* @returns {Logger} - A configured Winston logger instance.
9+
*/
10+
export function Logger(context: string): Logger {
11+
return createWinstonLogger({
12+
level: "info",
13+
format: format.combine(
14+
format.timestamp({
15+
format: "YYYY-MM-DD HH:mm:ss", // Example: 2025-01-15 14:30:45
16+
}),
17+
format.printf((info) => {
18+
const timestamp = colors.green(info.timestamp); // Green for timestamp
19+
const prefix = `[${colors.cyan(context)}]`; // Cyan for context
20+
const level = {
21+
error: colors.red(info.level.toUpperCase()), // Red for errors
22+
warn: colors.yellow(info.level.toUpperCase()), // Yellow for warnings
23+
info: colors.blue(info.level.toUpperCase()), // Blue for info
24+
debug: colors.magenta(info.level.toUpperCase()), // Magenta for debug
25+
silly: colors.gray(info.level.toUpperCase()), // Gray for silly
26+
}[info.level] || colors.white(info.level.toUpperCase()); // Default color
27+
28+
const message =
29+
info.message instanceof Error
30+
? colors.red(`Error: ${info.message.message}\nStack: ${info.message.stack}`)
31+
: info.message;
32+
33+
return `${timestamp} ${prefix} ${level}: ${message}`;
34+
})
35+
),
36+
transports: [
37+
new transports.Console(),
38+
],
39+
});
40+
}

server/src/main.ts

Lines changed: 61 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { Logger } from "./functions/logger";
12
import express from "express";
23
import { createServer } from "node:http";
34
import { Server, type Socket } from "socket.io";
@@ -9,6 +10,9 @@ import type {
910
StartGameData,
1011
UpdateCookiesData,
1112
} from "./types/rooms";
13+
import colors from "colors";
14+
import "dotenv/config"
15+
const logger = Logger("Server");
1216

1317
/**
1418
* Initializes the Express application.
@@ -18,12 +22,12 @@ const app = express();
1822
/**
1923
* Creates an HTTP server using the Express application.
2024
*/
21-
const httpServer = createServer(app);
25+
const HTTP = createServer(app);
2226

2327
/**
2428
* Initializes Socket.IO with the HTTP server.
2529
*/
26-
const io = new Server(httpServer);
30+
const io = new Server(HTTP);
2731

2832
/**
2933
* Stores active rooms on the server.
@@ -58,16 +62,14 @@ function generateCode(): string {
5862
*/
5963
app.get("/ping", (req, res) => {
6064
res.status(200).send({
61-
message: "pong",
62-
date: new Date()
65+
message: "pong!",
6366
});
6467
});
6568

6669
/**
6770
* Handles client connections and sets up event listeners.
6871
*/
6972
io.on("connection", (socket: Socket) => {
70-
console.log(`Client connected: ${socket.id}`);
7173

7274
/**
7375
* Handles player joining or creating a room.
@@ -120,10 +122,8 @@ io.on("connection", (socket: Socket) => {
120122
});
121123

122124
io.to(room_code).emit("update_room", { room_player, room });
123-
console.log(
124-
`Player "${room_player}" joined room "${room_code}". Room state:`,
125-
room,
126-
);
125+
126+
logger.info(`Player "${colors.bold.brightGreen.underline(room_player)}" joined room "${colors.bold.brightGreen.underline(room_code)}".`);
127127
});
128128

129129
/**
@@ -144,64 +144,61 @@ io.on("connection", (socket: Socket) => {
144144

145145
if (room.players.length === 0) {
146146
delete ROOMS[room_code];
147-
console.log(`Room ${room_code} has been deleted.`);
147+
logger.info(`Room ${room_code} has been deleted.`);
148148
} else if (room.owner === room_player) {
149149
room.owner = room.players[0]?.room_player || null;
150-
console.log(`New owner of room ${room_code}: ${room.owner}`);
150+
logger.info(`New owner of room ${room_code}: ${room.owner}`);
151151
}
152152

153153
socket.leave(room_code);
154154
io.to(room_code).emit("update_room", { room_player, room });
155155

156-
console.log(
157-
`Player ${room_player} (Socket ID: ${socket.id}) left room ${room_code}`,
158-
);
156+
logger.info(`Player ${room_player} (Socket ID: ${socket.id}) left room ${room_code}`);
159157
});
160158

161159
/**
162-
* Handles joining a random public room.
163-
* Filters for available public rooms with space for more players.
164-
* If no public rooms are available, an error is emitted.
165-
* If the player is already in a room, an error is emitted.
166-
* Otherwise, the player is added to a random room and the room is updated.
167-
* @param {string} room_player - The name/identifier of the player.
168-
*/
160+
* Handles joining a random public room.
161+
* Filters for available public rooms with space for more players.
162+
* If no public rooms are available, an error is emitted.
163+
* If the player is already in a room, an error is emitted.
164+
* Otherwise, the player is added to a random room and the room is updated.
165+
* @param {string} room_player - The name/identifier of the player.
166+
*/
169167
socket.on("join_random_room", ({ room_player }: { room_player: string }) => {
170-
// Filters public rooms that are in "waiting" state and have less than 10 players
171-
const availableRooms = Object.values(ROOMS).filter(
172-
(room) => room.public && room.state === "waiting");
173-
174-
// If no available public rooms
175-
if (availableRooms.length === 0) {
176-
socket.emit("err_socket", { err_socket: "NO_PUBLIC_ROOMS_AVAILABLE" });
177-
return;
178-
}
179-
180-
// Randomly select a room from the available rooms
181-
const randomRoom = availableRooms[Math.floor(Math.random() * availableRooms.length)];
182-
183-
// Check if the player is already in the selected room
184-
if (randomRoom.players.find((player) => player.room_player === room_player)) {
185-
socket.emit("err_socket", { err_socket: "PLAYER_EXISTS_IN_ROOM" });
186-
return;
187-
}
188-
189-
// Add the player to the selected room
190-
socket.join(randomRoom.code);
191-
192-
randomRoom.players.push({
193-
id: generateUuid(),
194-
date: new Date(),
195-
socket: socket.id,
196-
player_data: { cookies: null },
197-
room_player,
198-
});
168+
// Filters public rooms that are in "waiting" state and have less than 10 players
169+
const availableRooms = Object.values(ROOMS).filter(
170+
(room) => room.public && room.state === "waiting");
199171

200-
io.to(randomRoom.code).emit("update_room", { room_player, room: randomRoom });
201-
202-
console.log(`Player "${room_player}" joined random room "${randomRoom.code}". Room state:`, randomRoom);
203-
204-
});
172+
// If no available public rooms
173+
if (availableRooms.length === 0) {
174+
socket.emit("err_socket", { err_socket: "NO_PUBLIC_ROOMS_AVAILABLE" });
175+
return;
176+
}
177+
178+
// Randomly select a room from the available rooms
179+
const randomRoom = availableRooms[Math.floor(Math.random() * availableRooms.length)];
180+
181+
// Check if the player is already in the selected room
182+
if (randomRoom.players.find((player) => player.room_player === room_player)) {
183+
socket.emit("err_socket", { err_socket: "PLAYER_EXISTS_IN_ROOM" });
184+
return;
185+
}
186+
187+
// Add the player to the selected room
188+
socket.join(randomRoom.code);
189+
190+
randomRoom.players.push({
191+
id: generateUuid(),
192+
date: new Date(),
193+
socket: socket.id,
194+
player_data: { cookies: null },
195+
room_player,
196+
});
197+
198+
io.to(randomRoom.code).emit("update_room", { room_player, room: randomRoom });
199+
200+
logger.info(`Player "${colors.bold.brightGreen.underline(room_player)}" joined random room "${randomRoom.code}".`);
201+
});
205202

206203
/**
207204
* Handles player rejoining a room.
@@ -219,7 +216,7 @@ io.on("connection", (socket: Socket) => {
219216
player.socket = socket.id;
220217
socket.join(room_code);
221218
io.to(room_code).emit("update_room", { room_player, room });
222-
console.log(`Player "${room_player}" rejoined room "${room_code}".`);
219+
logger.info(`Player "${room_player}" rejoined room "${room_code}".`);
223220
}
224221
});
225222

@@ -265,13 +262,10 @@ io.on("connection", (socket: Socket) => {
265262

266263
if (room.state === "finished") {
267264
delete ROOMS[room_code];
268-
console.log(`Room ${room_code} has been deleted.`);
265+
logger.info(`Room ${room_code} has been deleted.`);
269266
}
270267

271-
console.log(
272-
`Game in room "${room_code}" finished! Ranking:`,
273-
ranking,
274-
);
268+
logger.info(`Game in room "${room_code}" finished! Ranking: ${JSON.stringify(ranking)}`);
275269
return;
276270
}
277271

@@ -305,8 +299,8 @@ io.on("connection", (socket: Socket) => {
305299

306300
if (player) {
307301
player.player_data.cookies = cookies;
308-
console.log(
309-
`Player "${room_player}" in room "${room_code}" updated cookies to ${cookies}.`,
302+
logger.info(
303+
`Player "${room_player}" in room "${room_code}" updated cookies to ${cookies}.`
310304
);
311305
}
312306
},
@@ -316,12 +310,12 @@ io.on("connection", (socket: Socket) => {
316310
* Handles client disconnection.
317311
*/
318312
socket.on("disconnect", () => {
319-
console.log(`Client disconnected: ${socket.id}`);
313+
logger.info(`Client disconnected: ${socket.id}`);
320314
});
321315

322316
});
323317

324-
// Starts the server on port 3000
325-
httpServer.listen(3000, () => {
326-
console.log("Server is running on http://localhost:3000");
318+
319+
HTTP.listen(process.env.PORT, () => {
320+
logger.info(`Socket running: ` + colors.bold.brightGreen.underline(`http://0.0.0.0:${process.env.PORT}`));
327321
});

0 commit comments

Comments
 (0)