Items and inventory

This commit is contained in:
Katboi01 2023-09-15 23:42:42 +02:00
parent 2bcdb780c3
commit 7e6bfdbd98
21 changed files with 335 additions and 96 deletions

View File

@ -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);
});

View File

@ -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;
}
}

View File

@ -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}`);
});
});
});

15
Classes/enums.ts Normal file
View File

@ -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
}
}

9
Classes/itemData.ts Normal file
View File

@ -0,0 +1,9 @@
import { enums } from "./enums"
export class itemData{
name : string
id : number
rarity: number
itemType : number
stats = {}
}

6
Classes/itemGenerated.ts Normal file
View File

@ -0,0 +1,6 @@
import { itemData } from "./itemData"
export class itemGenerated{
instanceId: number
item: itemData
}

6
Classes/itemPickup.ts Normal file
View File

@ -0,0 +1,6 @@
import { itemData } from "./itemData"
export class itemPickup{
instanceId: number
item: itemData
}

4
Classes/itemRequest.ts Normal file
View File

@ -0,0 +1,4 @@
export class itemRequest{
instanceId: number
itemType: number
}

12
Classes/lobbyMessage.ts Normal file
View File

@ -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
}
}

17
Classes/lobbyState.ts Normal file
View File

@ -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
}
}

18
Classes/playerData.ts Normal file
View File

@ -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
}
}

View File

@ -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
}
}
}

25
Classes/userData.ts Normal file
View File

@ -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
}
}

38
Items/itemGeneration.ts Normal file
View File

@ -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
}

66
Items/itemSocket.ts Normal file
View File

@ -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 += "<color=purple>" + data1.name + "</color> (epic)"
}
else if(data1.rarity >= 60){
console.log("rare")
message += "<color=red>" + data1.name + "</color> (rare)"
}
else if(data1.rarity >= 40){
console.log("uncommon")
message += "<color=yellow>" + data1.name + "</color> (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))
});
}

View File

@ -1,6 +0,0 @@
export class lobbyMessageData{
Id: number;
User: string;
Timestamp: string;
Content: string;
}

View File

@ -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)
});
}

View File

@ -1,8 +0,0 @@
import { physicsObject } from "../Classes/physicsObject";
import { playerData } from "../Player/playerData";
export class lobbyState{
hostSocket : string
players : playerData[] = [];
objects : physicsObject[] = [];
}

View File

@ -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
}

21
game.ts
View File

@ -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))
}
}

View File

@ -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)