diff --git a/Account/accountSocket.ts b/Account/accountSocket.ts index f34ab50..403ecbe 100644 --- a/Account/accountSocket.ts +++ b/Account/accountSocket.ts @@ -1,36 +1,39 @@ import { game } from "../game"; -import { publicUserData, userData } from "./userData"; +import { userData } from "../Classes/userData"; import { users } from "./users"; export function registerAccountCallbacks(socket){ function emitLogin(result : userData, registered:boolean = false){ - socket.emit("account/login", JSON.stringify(new publicUserData(result, socket.id))); if(result != null){ - socket.userId = result.Id; + socket.emit("account/login", JSON.stringify(userData.makeSafe(result, socket.id))); + socket.user = result if(registered){ - console.log(`User ${(result as userData).Login} registerd and logged in`); + console.log(`User ${(result as userData).login} registerd and logged in`); } else{ - console.log(`User ${(result as userData).Login} logged in`); + console.log(`User ${(result as userData).login} logged in`); } } else{ + socket.emit("account/login", ""); console.log("Login Failed"); } } socket.on('account/register', (data) => { let buff = Buffer.from(data, 'base64'); - let json = JSON.parse(buff.toString('utf-8')); - let result = users.createUser(json.Login, json.Password); + let json : userData = JSON.parse(buff.toString('utf-8')); + if (!json.login || !json.password) return + let result = users.createUser(json.login, json.password); emitLogin(result, true); }); socket.on('account/login', (data) => { let buff = Buffer.from(data, 'base64'); - let json = JSON.parse(buff.toString('utf-8')); - let result = users.readUser(json.Login, json.Password); + let json : userData = JSON.parse(buff.toString('utf-8')); + if (!json.login || !json.password) return + let result = users.readUser(json.login, json.password); emitLogin(result); }); diff --git a/Account/userData.ts b/Account/userData.ts deleted file mode 100644 index 47ed8a3..0000000 --- a/Account/userData.ts +++ /dev/null @@ -1,28 +0,0 @@ -export class userData{ - Id: number; - Checksum: number; - Login: string; - Password: string; - Characters: number[] = []; - - constructor(id:number, login:string, password:string){ - this.Id = id; - this.Login = login; - this.Password = password; - } -} - -export class publicUserData{ - Id: number; - Login: string; - SocketId: string; - - constructor(user:userData, socket: string){ - if(user == null){ - return null; - } - this.Id = user.Id; - this.Login = user.Login; - this.SocketId = socket; - } -} \ No newline at end of file diff --git a/Account/users.ts b/Account/users.ts index ea1b13b..c14e373 100644 --- a/Account/users.ts +++ b/Account/users.ts @@ -1,10 +1,10 @@ import { game } from "../game"; -import { userData } from "./userData"; +import { userData } from "../Classes/userData"; const fs = require('fs'); export class users{ static createUser(login, password){ - if(game.accountsDB.filter(u=>u.Login == login)[0] != undefined){ + if (game.accountsDB.find(u=>u.login == login) != null){ console.log(`User ${login} alread exists`); return null; } @@ -15,43 +15,51 @@ export class users{ } static readUser(login, password){ - let user = game.accountsDB.filter(u=>u.Login == login && u.Password == password)[0]; - if(user != undefined){ + let user = game.accountsDB.find(u=>u.login == login && u.password == password) + if(user != null){ return user; } return null; } static readUserID(id : number){ - let user = game.accountsDB.filter(u=>u.Id == id)[0]; + let user = game.accountsDB.filter(u=>u.id == id)[0]; return user; } static updateUser(userNew : userData){ - let user = this.readUserID(userNew.Id); + let user = this.readUserID(userNew.id); let sum = Math.floor(Math.random() * 99999); - while(sum == userNew.Checksum){ + while(sum == userNew.checksum){ sum = Math.floor(Math.random() * 99999); } - userNew.Checksum = sum; + userNew.checksum = sum; game.accountsDB[game.accountsDB.indexOf(user)] = userNew; } static saveUsers(){ game.accountsDB.forEach(user => { let data = JSON.stringify(user, null, 2); - fs.writeFileSync(`Database/Users/${user.Id}_${user.Login}.json`, data); + fs.writeFileSync(`Database/Users/${user.id}_${user.login}.json`, data); }); } static loadUsers(){ + let maxItemId = 0; fs.readdir(`Database/Users/`, (err, files) => { files.forEach(file => { fs.readFile(`Database/Users/${file}`, (err, data) => { if (err) throw err; let user = JSON.parse(data); game.accountsDB.push(user); - console.log(`Loaded ${user.Login}`); + if(user.playerData != null){ + user.playerData.inventory.items.forEach(i=>{ + if(i.id > maxItemId){ + game.itemCount = maxItemId = i.id + } + }) + } + console.log(`Loaded ${user.login}`); }); }); }); diff --git a/Classes/enums.ts b/Classes/enums.ts new file mode 100644 index 0000000..a549bb4 --- /dev/null +++ b/Classes/enums.ts @@ -0,0 +1,15 @@ +export class enums{ + static itemType = { + undefined: 0, + currency: 1, + consumable: 2, + equipment: 3 + } + + static equipmentType = { + undefined: 0, + weapon: 1, + armor: 2, + accessory: 3 + } +} \ No newline at end of file diff --git a/Classes/itemData.ts b/Classes/itemData.ts new file mode 100644 index 0000000..69e7d3c --- /dev/null +++ b/Classes/itemData.ts @@ -0,0 +1,9 @@ +import { enums } from "./enums" + +export class itemData{ + name : string + id : number + rarity: number + itemType : number + stats = {} +} diff --git a/Classes/itemGenerated.ts b/Classes/itemGenerated.ts new file mode 100644 index 0000000..dec0bb8 --- /dev/null +++ b/Classes/itemGenerated.ts @@ -0,0 +1,6 @@ +import { itemData } from "./itemData" + +export class itemGenerated{ + instanceId: number + item: itemData +} \ No newline at end of file diff --git a/Classes/itemPickup.ts b/Classes/itemPickup.ts new file mode 100644 index 0000000..c99d56c --- /dev/null +++ b/Classes/itemPickup.ts @@ -0,0 +1,6 @@ +import { itemData } from "./itemData" + +export class itemPickup{ + instanceId: number + item: itemData +} \ No newline at end of file diff --git a/Classes/itemRequest.ts b/Classes/itemRequest.ts new file mode 100644 index 0000000..5743ac2 --- /dev/null +++ b/Classes/itemRequest.ts @@ -0,0 +1,4 @@ +export class itemRequest{ + instanceId: number + itemType: number +} \ No newline at end of file diff --git a/Classes/lobbyMessage.ts b/Classes/lobbyMessage.ts new file mode 100644 index 0000000..14b302d --- /dev/null +++ b/Classes/lobbyMessage.ts @@ -0,0 +1,12 @@ +export class lobbyMessage{ + id: number; + user: string; + timestamp: string; + content: string; + + constructor(text : string){ + this.user = "Server" + this.timestamp = new Date().toLocaleString(); + this.content = text + } +} \ No newline at end of file diff --git a/Classes/lobbyState.ts b/Classes/lobbyState.ts new file mode 100644 index 0000000..d39a0b9 --- /dev/null +++ b/Classes/lobbyState.ts @@ -0,0 +1,17 @@ +import { physicsObject } from "../Classes/physicsObject"; +import { playerData } from "../Classes/playerData"; + +export class lobbyState{ + hostSocket : string + players : playerData[] = []; + objects : physicsObject[] = []; + + copyLight(){ + let lobby = Object.assign({}, this); + lobby.players = [] + for (let i = 0; i < this.players.length; i++) { + lobby.players.push(playerData.copyLight(this.players[i])); + } + return lobby + } +} \ No newline at end of file diff --git a/Classes/playerData.ts b/Classes/playerData.ts new file mode 100644 index 0000000..19f9b19 --- /dev/null +++ b/Classes/playerData.ts @@ -0,0 +1,18 @@ +import { physicsObject } from "./physicsObject"; +import { playerInventory } from "./playerInventory"; + +export class playerData{ + socketId : string + userName : string + characterId : number + inventory : playerInventory = new playerInventory() + rigidbody : physicsObject = new physicsObject() + + static copyLight(data : playerData){ + let player : any = Object.assign({}, data); + delete player.userName + delete player.characterId + delete player.inventory + return player + } +} \ No newline at end of file diff --git a/Classes/playerInventory.ts b/Classes/playerInventory.ts new file mode 100644 index 0000000..81300da --- /dev/null +++ b/Classes/playerInventory.ts @@ -0,0 +1,19 @@ +import { itemData } from "./itemData"; + +export class playerInventory{ + weapon : number = -1 + equipment : number[] = [-1,-1] + items : itemData[] = [] + + static validate(inv : playerInventory){ + if(inv.equipment[0] == inv.weapon){ + inv.equipment[0] = -1 + } + if(inv.equipment[1] == inv.weapon){ + inv.equipment[1] = -1 + } + if(inv.equipment[1] == inv.equipment[0]){ + inv.equipment[1] = -1 + } + } +} \ No newline at end of file diff --git a/Classes/userData.ts b/Classes/userData.ts new file mode 100644 index 0000000..235a224 --- /dev/null +++ b/Classes/userData.ts @@ -0,0 +1,25 @@ +import { itemData } from "./itemData"; +import { playerData } from "./playerData"; + +export class userData{ + id: number; + checksum: number; + login: string; + password: string; + playerData: playerData = null + + constructor(id:number, login:string, password:string){ + this.id = id; + this.login = login; + this.password = password; + this.checksum = 0; + } + + static makeSafe(user : userData, socketId : string){ + let safeUser : any = Object.assign({}, user); + safeUser.socketId = socketId + delete safeUser.password + delete safeUser.checksum + return safeUser + } +} \ No newline at end of file diff --git a/Items/itemGeneration.ts b/Items/itemGeneration.ts new file mode 100644 index 0000000..e619057 --- /dev/null +++ b/Items/itemGeneration.ts @@ -0,0 +1,38 @@ +import { enums } from "../Classes/enums"; +import { itemData } from "../Classes/itemData"; +import {game} from "../game"; + +let consumableNames = ["soda", "bread"] +let currencyNames = ["stick", "rock", "leaf", "coin"] +let equipmentNames = ["umbrella", "sock", "bag"] +let miscNames = ["book", "envelope"] + +export function generateItem(itemType : number){ + let item = new itemData() + item.id = ++game.itemCount; + item.itemType = itemType + item.rarity = Math.floor(Math.random()*100) + switch(itemType){ + case enums.itemType.undefined:{ + item.name = miscNames[Math.floor(Math.random()*miscNames.length)]; + + break + } + case enums.itemType.consumable:{ + item.name = consumableNames[Math.floor(Math.random()*consumableNames.length)]; + + break + } + case enums.itemType.currency:{ + item.name = currencyNames[Math.floor(Math.random()*currencyNames.length)]; + + break + } + case enums.itemType.equipment:{ + item.name = equipmentNames[Math.floor(Math.random()*equipmentNames.length)]; + + break + } + } + return item +} \ No newline at end of file diff --git a/Items/itemSocket.ts b/Items/itemSocket.ts new file mode 100644 index 0000000..a90dff9 --- /dev/null +++ b/Items/itemSocket.ts @@ -0,0 +1,66 @@ +import { itemData } from "../Classes/itemData"; +import { itemGenerated } from "../Classes/itemGenerated"; +import { generateItem } from "./itemGeneration"; +import { itemRequest } from "../Classes/itemRequest"; +import { lobbyMessage } from "../Classes/lobbyMessage"; +import { userData } from "../Classes/userData"; +import { game } from "../game"; +import { playerData } from "../Classes/playerData"; + +export function registerItemCallbacks(socket){ + socket.on('item/pickup', (data) => { + if(!socket.hasOwnProperty("user")) return; + + let buff = Buffer.from(data, 'base64'); + let data1 : itemData = JSON.parse(buff.toString('utf-8')); + + let player : playerData = socket.user.playerData + if(player != null){ + let message = socket.user.login + " picked up " + if(data1.rarity >= 90){ + console.log("epic") + message += "" + data1.name + " (epic)" + } + else if(data1.rarity >= 60){ + console.log("rare") + message += "" + data1.name + " (rare)" + } + else if(data1.rarity >= 40){ + console.log("uncommon") + message += "" + data1.name + " (uncommon)" + } + else + message += data1.name; + + player.inventory.items.push(data1) + game.addMessage(new lobbyMessage(message)) + } + }); + + socket.on('item/delete', (data) => { + if(!socket.hasOwnProperty("user")) return; + + let buff = Buffer.from(data, 'base64'); + let data1 = Number(buff.toString('utf-8')); + + let player : playerData = socket.user.playerData + let item = player.inventory.items.findIndex(i=>i.id == data1); + if(item == -1){ + console.log("Error! Item " + item + " not found!") + } + player.inventory.items.splice(item, 1) + }); + + socket.on('item/request', (data) => { + if(!socket.hasOwnProperty("user")) return; + + let buff = Buffer.from(data, 'base64'); + let data1 : itemRequest = JSON.parse(buff.toString('utf-8')); + + let response = new itemGenerated() + response.instanceId = data1.instanceId + response.item = generateItem(data1.itemType) + + socket.emit("item/generated", JSON.stringify(response)) + }); +} \ No newline at end of file diff --git a/Lobby/lobbyMessageData.ts b/Lobby/lobbyMessageData.ts deleted file mode 100644 index 32af7c1..0000000 --- a/Lobby/lobbyMessageData.ts +++ /dev/null @@ -1,6 +0,0 @@ -export class lobbyMessageData{ - Id: number; - User: string; - Timestamp: string; - Content: string; -} \ No newline at end of file diff --git a/Lobby/lobbySocket.ts b/Lobby/lobbySocket.ts index 0a3a924..94fefb7 100644 --- a/Lobby/lobbySocket.ts +++ b/Lobby/lobbySocket.ts @@ -1,16 +1,38 @@ -import { playerData } from "../Player/playerData" +import { lobbyMessage } from "../Classes/lobbyMessage"; +import { playerData } from "../Classes/playerData" +import { playerInventory } from "../Classes/playerInventory"; +import { userData } from "../Classes/userData"; import { game } from "../game"; export function registerLobbyCallbacks(socket){ - socket.on('lobby/playerUpdate', (data) => { - if(!socket.hasOwnProperty("userId")) return; + socket.on('lobby/playerJoin', (data) => { + if(!socket.hasOwnProperty("user")) return; let buff = Buffer.from(data, 'base64'); let data1 : playerData = JSON.parse(buff.toString('utf-8')); - data1.socketId = socket.id; + + if(socket.user.playerData == null){ + let pd = new playerData() + socket.user.playerData = pd + } + + socket.user.playerData.characterId = data1.characterId; + socket.user.playerData.socketId = socket.id + + game.lobbyState.players.push(socket.user.playerData) + game.socketIO.emit("lobby/playerJoin", JSON.stringify(socket.user.playerData)) + }); + + socket.on('lobby/playerUpdate', (data) => { + if(!socket.hasOwnProperty("user")) return; + + let buff = Buffer.from(data, 'base64'); + let data1 : playerData = JSON.parse(buff.toString('utf-8')); + data1.socketId = socket.id let idx = game.lobbyState.players.findIndex((pl) => pl.socketId == socket.id) if(idx == -1){ + socket.player = data1 game.lobbyState.players.push(data1) socket.emit('lobby/messages', JSON.stringify(game.messages)) } @@ -20,7 +42,7 @@ export function registerLobbyCallbacks(socket){ }); socket.on('lobby/lobbyUpdate', (data) => { - if(!socket.hasOwnProperty("userId")) return; + if(!socket.hasOwnProperty("user")) return; let buff = Buffer.from(data, 'base64'); let data1 = JSON.parse(buff.toString('utf-8')); @@ -28,18 +50,25 @@ export function registerLobbyCallbacks(socket){ game.lobbyState.objects = data1.objects }); - socket.on('lobby/message', (data) => { - if(!socket.hasOwnProperty("userId")) return; + socket.on('lobby/loadoutChanged', (data) => { + if(!socket.hasOwnProperty("user")) return; let buff = Buffer.from(data, 'base64'); - data = JSON.parse(buff.toString('utf-8')); - data.timestamp = new Date().toLocaleString(); + let data1 : playerData = JSON.parse(buff.toString('utf-8')); - while(game.messages.length >= 20){ - game.messages.pop(); - } + socket.user.playerData.inventory = data1.inventory + playerInventory.validate(socket.user.playerData.inventory) - game.messages.unshift(data) - socket.io.emit('lobby/messages', JSON.stringify(game.messages)) + game.socketIO.emit("lobby/loadoutChanged", JSON.stringify(socket.user.playerData)) + }); + + socket.on('lobby/message', (data) => { + if(!socket.hasOwnProperty("user")) return; + + let buff = Buffer.from(data, 'base64'); + let data1 : lobbyMessage = JSON.parse(buff.toString('utf-8')); + data1.timestamp = new Date().toLocaleString(); + + game.addMessage(data1) }); } \ No newline at end of file diff --git a/Lobby/lobbyState.ts b/Lobby/lobbyState.ts deleted file mode 100644 index 9245903..0000000 --- a/Lobby/lobbyState.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { physicsObject } from "../Classes/physicsObject"; -import { playerData } from "../Player/playerData"; - -export class lobbyState{ - hostSocket : string - players : playerData[] = []; - objects : physicsObject[] = []; -} \ No newline at end of file diff --git a/Player/playerData.ts b/Player/playerData.ts deleted file mode 100644 index a01e49f..0000000 --- a/Player/playerData.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { publicUserData } from "../Account/userData"; -import { physicsObject } from "../Classes/physicsObject"; - -export class playerData{ - socketId : string - userName : string - characterId : number - rigidbody : physicsObject -} \ No newline at end of file diff --git a/game.ts b/game.ts index 8b22dd6..e8ebe55 100644 --- a/game.ts +++ b/game.ts @@ -1,15 +1,26 @@ -import { userData } from "./Account/userData"; -import { lobbyMessageData } from "./Lobby/lobbyMessageData"; -import { lobbyState } from "./Lobby/lobbyState"; -import { playerData } from "./Player/playerData"; +import { userData } from "./Classes/userData"; +import { lobbyMessage } from "./Classes/lobbyMessage"; +import { lobbyState } from "./Classes/lobbyState"; const fs = require('fs'); export class game{ + static socketIO : any + + static itemCount : number = 0 static accountsDB : userData[] = [] /** Key: socket ID*/ static lobbyState : lobbyState = new lobbyState() /** Max items: 20 */ - static messages : lobbyMessageData[] = []; + static messages : lobbyMessage[] = []; + + static addMessage(message:lobbyMessage) { + while(game.messages.length >= 20){ + game.messages.pop(); + } + + game.messages.unshift(message) + game.socketIO.emit('lobby/messages', JSON.stringify(game.messages)) + } } \ No newline at end of file diff --git a/index.ts b/index.ts index fbe5646..0d454d1 100644 --- a/index.ts +++ b/index.ts @@ -1,8 +1,9 @@ import { registerAccountCallbacks } from "./Account/accountSocket"; import { users } from "./Account/users"; import { registerLobbyCallbacks } from "./Lobby/lobbySocket"; -import { playerData } from "./Player/playerData"; +import { playerData } from "./Classes/playerData"; import { game } from "./game"; +import { registerItemCallbacks } from "./Items/itemSocket"; const express = require("express"); const app = express(); @@ -28,16 +29,19 @@ io.on('connection', (socket) => { registerAccountCallbacks(socket); registerLobbyCallbacks(socket); + registerItemCallbacks(socket); - socket.io = io; + socket.io = game.socketIO = io; socket.on("disconnect", () => { socket.disconnect() - let idx = game.lobbyState.players.findIndex((pl) => pl.socketId == socket.id) - if(idx != -1){ - game.lobbyState.players.splice(idx, 1) + if(socket.hasOwnProperty("user")){ + let idx = game.lobbyState.players.findIndex((pl) => pl.socketId == socket.id) + if(idx != -1){ + game.lobbyState.players.splice(idx, 1) + } + delete socket.user } - delete socket.userId console.log(socket.id + " disconnected"); }); @@ -51,7 +55,7 @@ setInterval(() => { let userCount = game.lobbyState.players.length if(userCount > 0){ game.lobbyState.hostSocket = game.lobbyState.players[0].socketId - io.emit('lobby', JSON.stringify(game.lobbyState)) + io.emit('lobby', JSON.stringify(game.lobbyState.copyLight())) } }, 1000/30)