Initial commit
This commit is contained in:
50
backend/src/SocketIO/LobbyManager/Classes/Lobby.js
Normal file
50
backend/src/SocketIO/LobbyManager/Classes/Lobby.js
Normal file
@@ -0,0 +1,50 @@
|
||||
const socketIO = require("socket.io");
|
||||
const SocketUser = require("./SocketUser");
|
||||
|
||||
class Lobby {
|
||||
/** @param {socketIO.Server} io @param {Map<number, SocketUser>} users*/
|
||||
constructor(io, code) {
|
||||
this.io = io;
|
||||
this.code = code;
|
||||
/** @type {Array<SocketUser>} */
|
||||
this.users = [];
|
||||
}
|
||||
|
||||
addUser(user) {
|
||||
if (this.users.length >= 2) return 1;
|
||||
|
||||
this.users.push(user);
|
||||
|
||||
this.sendLobbyUserUpdate();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
removeUser(user) {
|
||||
const index = this.users.findIndex(u => u.id === user.id);
|
||||
|
||||
if (index === -1) return 1;
|
||||
|
||||
this.users.splice(index, 1);
|
||||
|
||||
this.sendLobbyUserUpdate();
|
||||
|
||||
if (this.users.length === 0) return 2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
sendLobbyUserUpdate() {
|
||||
const data = {
|
||||
code: this.code,
|
||||
users: this.users.map(user => ({
|
||||
id: user.id,
|
||||
username: user.username
|
||||
}))
|
||||
}
|
||||
|
||||
this.io.to(`lobby-${this.code}`).emit("lobbyUserUpdate", data);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Lobby;
|
||||
12
backend/src/SocketIO/LobbyManager/Classes/SocketUser.js
Normal file
12
backend/src/SocketIO/LobbyManager/Classes/SocketUser.js
Normal file
@@ -0,0 +1,12 @@
|
||||
const socketIO = require("socket.io");
|
||||
|
||||
class SocketUser {
|
||||
/** @param {number} id @param {string} username @param {socketIO.Socket} socket */
|
||||
constructor(id, username, socket) {
|
||||
this.id = id;
|
||||
this.username = username;
|
||||
this.socket = socket;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = SocketUser;
|
||||
60
backend/src/SocketIO/LobbyManager/ClientHandler.js
Normal file
60
backend/src/SocketIO/LobbyManager/ClientHandler.js
Normal file
@@ -0,0 +1,60 @@
|
||||
const socketIO = require("socket.io");
|
||||
const LobbyManager = require("./LobbyManager");
|
||||
const SocketUser = require("./Classes/SocketUser");
|
||||
|
||||
class ClientHandler {
|
||||
/** @param {socketIO.Socket} socket @param {LobbyManager} lobbyManager */
|
||||
constructor(socket, lobbyManager) {
|
||||
this.socket = socket;
|
||||
this.lobbyManager = lobbyManager;
|
||||
|
||||
this.user = new SocketUser(
|
||||
this.socket.request.session.user.id,
|
||||
this.socket.request.session.user.username,
|
||||
this.socket
|
||||
);
|
||||
|
||||
|
||||
this.currentLobbyCode = null;
|
||||
|
||||
this.socket.on("createLobby", () => { this.createLobby() })
|
||||
this.socket.on("joinLobby", (code) => { this.joinLobby(code) })
|
||||
this.socket.on("refreshLobby", () => { this.refreshLobby() })
|
||||
this.socket.on("disconnect", () => { this.disconnect() })
|
||||
}
|
||||
|
||||
createLobby(){
|
||||
if(this.currentLobbyCode) return;
|
||||
|
||||
const lobbyCode = this.lobbyManager.createLobby(this.user);
|
||||
this.currentLobbyCode = lobbyCode;
|
||||
this.socket.join(`lobby-${lobbyCode}`);
|
||||
this.socket.emit("lobbyCreated", lobbyCode);
|
||||
this.refreshLobby();
|
||||
}
|
||||
|
||||
joinLobby(code){
|
||||
if(this.currentLobbyCode) return;
|
||||
|
||||
const response = this.lobbyManager.joinLobby(code, this.user);
|
||||
|
||||
if(response === 1) return this.socket.emit("lobbyJoinError", "Diese Lobby existiert nicht");
|
||||
if(response === 2) return this.socket.emit("lobbyJoinError", "Die Lobby ist schon voll");
|
||||
|
||||
this.currentLobbyCode = response;
|
||||
|
||||
this.socket.join(`lobby-${response}`)
|
||||
this.socket.emit("lobbyJoined", response);
|
||||
this.refreshLobby();
|
||||
}
|
||||
|
||||
refreshLobby(){
|
||||
this.lobbyManager.refreshLobby(this.currentLobbyCode);
|
||||
}
|
||||
|
||||
disconnect(){
|
||||
this.lobbyManager.removeFromLobby(this.currentLobbyCode, this.user);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ClientHandler;
|
||||
65
backend/src/SocketIO/LobbyManager/LobbyManager.js
Normal file
65
backend/src/SocketIO/LobbyManager/LobbyManager.js
Normal file
@@ -0,0 +1,65 @@
|
||||
const socketIO = require("socket.io");
|
||||
const Lobby = require("./Classes/Lobby");
|
||||
const SocketUser = require("./Classes/SocketUser");
|
||||
|
||||
class LobbyManager {
|
||||
/** @param {socketIO.Server} io */
|
||||
constructor(io) {
|
||||
this.io = io;
|
||||
|
||||
/** @type {Map<string, Lobby>}*/
|
||||
this.lobbys = new Map();
|
||||
|
||||
// Zeigt die Anzahl der Lobbys an | Für Testing
|
||||
// setInterval(() => {
|
||||
// console.log(this.lobbys.size);
|
||||
// }, 1000);
|
||||
|
||||
}
|
||||
|
||||
/** @param {SocketUser} user */
|
||||
createLobby(user){
|
||||
const code = this.generateNonExistingCode();
|
||||
const lobby = new Lobby(this.io, code);
|
||||
lobby.addUser(user);
|
||||
this.lobbys.set(code, lobby);
|
||||
return code;
|
||||
}
|
||||
|
||||
/** @param {string} code @param {SocketUser} user */
|
||||
joinLobby(code, user){
|
||||
if (!this.lobbys.has(code)) return 1;
|
||||
|
||||
const lobby = this.lobbys.get(code);
|
||||
const response = lobby.addUser(user);
|
||||
if(response === 1) return 2;
|
||||
|
||||
return lobby.code;
|
||||
}
|
||||
|
||||
generateNonExistingCode() {
|
||||
let code;
|
||||
do {
|
||||
code = Math.random().toString(36).substring(2, 8).toUpperCase();
|
||||
} while (this.lobbys.has(code));
|
||||
return code;
|
||||
}
|
||||
|
||||
/** @param {SocketUser} user */
|
||||
removeFromLobby(code, user){
|
||||
if(!this.lobbys.has(code)) return;
|
||||
const lobby = this.lobbys.get(code);
|
||||
|
||||
const reponse = lobby.removeUser(user);
|
||||
|
||||
if (reponse === 2) this.lobbys.delete(code);
|
||||
}
|
||||
|
||||
refreshLobby(code){
|
||||
if(!this.lobbys.has(code)) return;
|
||||
const lobby = this.lobbys.get(code);
|
||||
lobby.sendLobbyUserUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = LobbyManager;
|
||||
69
backend/src/SocketIO/SocketIOManager.js
Normal file
69
backend/src/SocketIO/SocketIOManager.js
Normal file
@@ -0,0 +1,69 @@
|
||||
const socketIO = require("socket.io");
|
||||
const http = require("http");
|
||||
const DataBaseManager = require("../Database/DataBaseManager");
|
||||
const ExpressManager = require("../Express/ExpressManager");
|
||||
const LobbyManager = require("./LobbyManager/LobbyManager");
|
||||
const ClientHandler = require("./LobbyManager/ClientHandler");
|
||||
require("dotenv").config();
|
||||
|
||||
class SocketIOManager {
|
||||
/** @param {DataBaseManager} dbManager @param {ExpressManager} expressManager */
|
||||
constructor(dbManager, expressManager) {
|
||||
this.db = dbManager;
|
||||
this.express = expressManager;
|
||||
|
||||
|
||||
this.server = http.createServer(this.express.app);
|
||||
|
||||
/** @type {import("socket.io").Server} */
|
||||
this.io = socketIO(this.server);
|
||||
|
||||
// Dadurch bekommen wir Zugriff auf den Eingeloggten Nutzer
|
||||
this.io.use((socket, next) => {
|
||||
this.express.sessionMiddleware(socket.request, socket.request.res || {}, next);
|
||||
});
|
||||
|
||||
this.io.use((socket, next) => {this.useAuth(socket, next)});
|
||||
|
||||
/*
|
||||
Der LobbyManager kümmert sich um alle Lobbys
|
||||
Der LobbyHandler kümmert sich um die einzelnen Anfragen der Clients
|
||||
*/
|
||||
this.lobbyManager = new LobbyManager(this.io);
|
||||
|
||||
this.io.on("connection", (socket) => { this.sendToRightManager(socket) });
|
||||
|
||||
// Startet express und socket.io
|
||||
this.server.listen(process.env.PORT, () => {
|
||||
console.log(`Der Server ist gestartet und unter http://localhost:${process.env.PORT} erreichbar!`);
|
||||
});
|
||||
}
|
||||
|
||||
/** @param {socketIO.Socket} socket @param {socketIO.ExtendedError} next */
|
||||
useAuth(socket, next){
|
||||
// User muss eingeloggt sein
|
||||
if(!socket.request.session.user) return next(new Error("Nicht Eingeloggt!"));
|
||||
|
||||
// Der User darf nur eine verbindung gleichzeitig haben
|
||||
const userId = socket.request.session.user.id;
|
||||
const socketConnections = this.io.sockets.sockets;
|
||||
socketConnections.forEach((socket) => {
|
||||
if(socket.request.session.user.id === userId) return next(new Error("Irgendwer anders spielt schon!"));
|
||||
});
|
||||
|
||||
next();
|
||||
}
|
||||
|
||||
/** @param {socketIO.Socket} socket - The socket instance. */
|
||||
sendToRightManager(socket){
|
||||
socket.on("requestIdentification", () => {
|
||||
socket.emit("identification", socket.request.session.user);
|
||||
});
|
||||
|
||||
socket.on("hereForLobby", () => {
|
||||
new ClientHandler(socket, this.lobbyManager);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = SocketIOManager;
|
||||
Reference in New Issue
Block a user