TanksJS-Server/src/index.js

153 lines
4.4 KiB
JavaScript

var app = require("express")();
var http = require("http").createServer(app);
var io = require("socket.io")(http);
const port = 3000;
var colours = require("colors");
colours.enable();
colours.setTheme({
request: "green",
connect: "cyan",
disconnect: ["red", "dim"],
room: ["brightWhite"],
data: "grey"
});
const traffic = {
in: colours.data("-> "),
out: colours.data("<- "),
int: colours.data("-- ")
};
var players = {};
var rooms = {};
// Send players json object
app.get("/", (req, res) => {
res.send(players);
});
// Handle Connection
io.on("connection", (socket) => {
// Handle disconnection
socket.on("disconnect", () => {
if (players[socket.id]) {
const room = players[socket.id].room;
var playerUpdate = {};
if (io.sockets.adapter.rooms.get(room)) {
io.sockets.adapter.rooms.get(room).forEach((id) => {
playerUpdate[id] = players[id];
});
}
io.in(room).emit("roomUpdate", playerUpdate);
console.log(traffic.out + colours.disconnect(`User ${String(socket.id)} disconnected from room ${room}`));
if (io.sockets.adapter.rooms.get(room) == undefined) {
console.log(traffic.int + colours.room(`Room ${room} has been deleted due to a lack of players`));
delete rooms[room];
}
}
delete players[socket.id];
});
console.log(traffic.in + colours.request(`Socket ${String(socket.id)} is trying to connect`));
console.log(traffic.out + colours.data(`Requesting identification to client ${String(socket.id)}`));
// Request identification
socket.emit("identify");
// Wait for identification
socket.on("identification", (data) => {
console.log(traffic.in + colours.request(`User ${String(socket.id)} playing ${data.gameID} is trying to join a room with ${data.playersMax} players max`));
// Define room to be joined
var join = "";
// Check if there are any available rooms for the requested game and check if they aren't full
io.sockets.adapter.rooms.forEach((set, room) => {
if (/[0-9]_[0-9].*/i.test(room)) {
var roomId = room.split("_");
if (roomId[0] == data.gameID) {
if (roomId[1] == data.playersMax) {
if (io.sockets.adapter.rooms.get(room).size < data.playersMax) {
if (!rooms[room].started) {
join += room;
} else {
console.log(traffic.int + colours.room(`Room ${room} has already started, skipping.`));
}
} else {
console.log(traffic.int + colours.room(`Room ${room} is full, skipping.`));
}
}
}
}
});
// If no available room is found, make one
if (join == "") {
var count = 0;
var regex = new RegExp(data.gameID + "_" + data.playersMax + "_[0-9].*");
io.sockets.adapter.rooms.forEach((set, room) => {
if (regex.test(room)) {
count++;
}
});
join = data.gameID + "_" + data.playersMax + "_" + count;
rooms[join] = {
started: false
};
console.log(traffic.int + colours.room(`There is no room available for the requested game, making room ${join}`));
}
socket.join(join);
// Start game if the max number of players is reached
if (io.sockets.adapter.rooms.get(join).size == data.playersMax) {
console.log(traffic.int + colours.room(`Room ${join} has reached the maximum amount of players, starting game`));
io.in(join).emit("gameStart");
rooms[join].started = true;
}
players[socket.id] = {
username: data.name,
room: join
};
var playerUpdate = {};
io.sockets.adapter.rooms.get(join).forEach((id) => {
playerUpdate[id] = players[id];
});
io.in(join).emit("roomUpdate", playerUpdate);
console.log(traffic.in + colours.connect(`User ${String(socket.id)} connected to room ${join}`));
});
socket.on("update", (data) => {
if (players[socket.id]) {
socket.to(players[socket.id].room).emit("update", {
uuid: socket.id,
player: data
});
}
});
socket.on("spectate", (data) => {
if (io.sockets.adapter.rooms.has(data)) {
console.log(traffic.in + colours.connect(`User ${String(socket.id)} is spectating room ${data}`));
socket.join(data);
}
});
});
http.listen(port, () => {
console.log(colours.data(`\nServer ready, listening on port ${port}\n`));
});