improved adherence to types

This commit is contained in:
katboi01 2025-07-13 20:28:27 +02:00
parent 473c807461
commit 0a40a8ce5d
14 changed files with 114 additions and 38 deletions

View File

@ -1,9 +1,9 @@
import { userData } from "../Classes/userData.js"; import { userData } from "../Classes/userData.js";
import { characters } from "../Characters/characters.js"; import { characters } from "../Characters/characters.js";
import { users } from "./users.js"; import { userCheckResult, users } from "./users.js";
import { db } from "../index.js" import { db } from "../index.js"
import { Socket } from "socket.io"; import { Socket } from "socket.io";
import { loginResponse } from "../Classes/Outgoing/accountResponses.js"; import { loginResponse, loginResult } from "../Classes/Outgoing/accountResponses.js";
import { Endpoints } from "../endpoints.js"; import { Endpoints } from "../endpoints.js";
export async function login(socket : Socket, data){ export async function login(socket : Socket, data){
@ -14,12 +14,13 @@ export async function login(socket : Socket, data){
return return
} }
const user = await users.readUser(db, json.login, json.password); const userCheck = await users.readUser(db, json.login, json.password);
if(user){ if(userCheck.result == userCheckResult.OK){
const user = userCheck.userData;
console.log(`User ${user.login} logged in`); console.log(`User ${user.login} logged in`);
const character = await characters.readCharacter(db, user.id); const character = await characters.readCharacter(db, user.id);
const result = new loginResponse(user, character) const result = new loginResponse(loginResult.success, user, character)
socket.user = user socket.user = user
socket.character = character socket.character = character
@ -27,7 +28,7 @@ export async function login(socket : Socket, data){
} }
else{ else{
console.log(`User ${json.login} did not log in`); console.log(`User ${json.login} did not log in`);
const result = new loginResponse(null, null) const result = new loginResponse(loginResult.fail, null, null)
socket.emit(Endpoints.Login, JSON.stringify(result)); socket.emit(Endpoints.Login, JSON.stringify(result));
} }
} }

View File

@ -1,8 +1,8 @@
import { userData } from "../Classes/userData.js"; import { userData } from "../Classes/userData.js";
import { users } from "./users.js"; import { userCheckResult, users } from "./users.js";
import { db } from "../index.js" import { db } from "../index.js"
import { Socket } from "socket.io"; import { Socket } from "socket.io";
import { loginResponse } from "../Classes/Outgoing/accountResponses.js"; import { loginResponse, loginResult } from "../Classes/Outgoing/accountResponses.js";
import { Endpoints } from "../endpoints.js"; import { Endpoints } from "../endpoints.js";
import { characters } from "../Characters/characters.js"; import { characters } from "../Characters/characters.js";
@ -14,19 +14,26 @@ export async function register(socket : Socket, data){
return return
} }
const user = await users.createUser(db, json.login, json.password); const checkExisting = await users.readUser(db, json.login, null)
if(checkExisting.result != userCheckResult.NotExist){
const result = new loginResponse(loginResult.accountExists, null, null)
socket.emit(Endpoints.Register, JSON.stringify(result))
return
}
const user = (await users.createUser(db, json.login, json.password)).userData;
if(user){ if(user){
console.log(`User ${user.login} registered`); console.log(`User ${user.login} registered`);
const character = await characters.createCharacter(db, user.id); const character = await characters.createCharacter(db, user.id);
const result = new loginResponse(user, character) const result = new loginResponse(loginResult.success, user, character)
socket.user = user socket.user = user
socket.character = character socket.character = character
socket.emit(Endpoints.Register, JSON.stringify(result)) socket.emit(Endpoints.Register, JSON.stringify(result))
} }
else{ else{
console.log(`User failed to register`); console.log(`User failed to register`);
const result = new loginResponse(null, null) const result = new loginResponse(loginResult.fail, null, null)
socket.emit(Endpoints.Register, JSON.stringify(result)) socket.emit(Endpoints.Register, JSON.stringify(result))
} }
} }

View File

@ -1,25 +1,45 @@
import { userData } from "../Classes/userData.js"; import { userData } from "../Classes/userData.js";
import { DatabaseController } from "../Database/dbcontroller.js"; import { DatabaseController, dbUser } from "../Database/dbcontroller.js";
export class userCheckResponse{
result : userCheckResult
userData : userData
constructor(result : userCheckResult, userData : userData){
this.result = result;
this.userData = userData;
}
}
export enum userCheckResult{
OK,
IncorrectPassword,
NotExist
}
export class users{ export class users{
static async createUser(db: DatabaseController, login : string, password : string){ static async createUser(db: DatabaseController, login : string, password : string){
await db.run('INSERT INTO users (login, password) VALUES (?, ?)', [login, password]); await db.run('INSERT INTO users (login, password) VALUES (?, ?)', [login, password]);
return await this.readUser(db, login, password) return await this.readUser(db, login, password)
} }
static async readUser(db: DatabaseController, login : string, password : string): Promise<userData>{ static async readUser(db: DatabaseController, login : string, password : string): Promise<userCheckResponse>{
let user = await db.select(`SELECT * FROM users WHERE login = ? AND password = ?`, [login, password]) let user = await db.select<dbUser>(`SELECT * FROM users WHERE login = ? LIMIT 1`, [login])
if (user.length > 0){ if (user.length > 0){
let row = user[0] let row = user[0]
return new userData({...row}) if (row.password != password){
return new userCheckResponse(userCheckResult.IncorrectPassword, null)
}
return new userCheckResponse(userCheckResult.OK, new userData({...row}))
} }
else{ else{
return null return new userCheckResponse(userCheckResult.NotExist, null)
} }
} }
static async readUserID(db: DatabaseController, id : number){ static async readUserID(db: DatabaseController, id : number){
let user = await db.select(`SELECT * FROM users WHERE id = ?`, [id]) let user = await db.select<dbUser>(`SELECT * FROM users WHERE id = ?`, [id])
return user; return user;
} }
} }

View File

@ -1,5 +1,5 @@
import { characterData } from "../Classes/characterData.js"; import { characterData } from "../Classes/characterData.js";
import { DatabaseController } from "../Database/dbcontroller.js"; import { DatabaseController, dbCharacter } from "../Database/dbcontroller.js";
export class characters{ export class characters{
static async createCharacter(db: DatabaseController, userId : number){ static async createCharacter(db: DatabaseController, userId : number){
@ -8,7 +8,7 @@ export class characters{
} }
static async readCharacter(db: DatabaseController, userId : number): Promise<characterData>{ static async readCharacter(db: DatabaseController, userId : number): Promise<characterData>{
let player = await db.select(`SELECT * FROM characters WHERE user_id = ? LIMIT 1`, [userId]) let player = await db.select<dbCharacter>(`SELECT * FROM characters WHERE user_id = ? LIMIT 1`, [userId])
if (player.length > 0){ if (player.length > 0){
let row = player[0] let row = player[0]
return new characterData({ return new characterData({
@ -23,7 +23,7 @@ export class characters{
} }
static async savePlayer(db: DatabaseController, data: characterData){ static async savePlayer(db: DatabaseController, data: characterData){
await db.run(`UPDATE characters SET (inventory, questBook) VALUES (?,?) WHERE id = ?`, await db.run(`UPDATE characters SET inventory = ?, questBook = ? WHERE id = ?`,
[JSON.stringify(data.inventory), JSON.stringify(data.questBook), data.id]) [JSON.stringify(data.inventory), JSON.stringify(data.questBook), data.id])
} }
} }

View File

@ -1,7 +1,10 @@
import { levelState } from "../levelState.js"; import { levelState } from "../levelState.js";
import { characterData } from "../characterData.js"; import { characterData } from "../characterData.js";
import { Type } from "class-transformer";
export class levelUpdateHost{ export class levelUpdateHost{
@Type(() => characterData)
player : characterData player : characterData
@Type(() => levelState)
room : levelState room : levelState
} }

View File

@ -1,18 +1,24 @@
import { characterData } from "../characterData.js"; import { characterData } from "../characterData.js";
import { userData } from "../userData.js"; import { userData } from "../userData.js";
export enum loginResult{
success,
fail,
accountExists
}
export class loginResponse{ export class loginResponse{
result : boolean result : loginResult
userData : userData userData : userData
playerData : characterData playerData : characterData
constructor(user : userData, player : characterData){ constructor(result: loginResult, user : userData, player : characterData){
if (!user || !player){ if (!user || !player){
this.result = false; this.result = result;
this.userData = this.playerData = null; this.userData = this.playerData = null;
} }
else{ else{
this.result = true; this.result = result;
this.userData = user.makeSafe(); this.userData = user.makeSafe();
this.playerData = player; this.playerData = player;
} }

View File

@ -2,6 +2,7 @@ import { enemyData } from "./enemyData.js";
import { characterData } from "./characterData.js"; import { characterData } from "./characterData.js";
import { propData } from "./propData.js"; import { propData } from "./propData.js";
import { levelStateStart, levelStateState as levelStateInfo, levelStateUpdate } from "./Outgoing/levelStatePartial.js"; import { levelStateStart, levelStateState as levelStateInfo, levelStateUpdate } from "./Outgoing/levelStatePartial.js";
import { Type } from "class-transformer";
export class levelState{ export class levelState{
id : string id : string
@ -9,8 +10,11 @@ export class levelState{
hostId : number = -1 hostId : number = -1
completed : boolean = false completed : boolean = false
isDungeon : boolean = false isDungeon : boolean = false
@Type(() => enemyData)
enemies : enemyData[] = [] enemies : enemyData[] = []
@Type(() => propData)
objects : propData[] = [] objects : propData[] = []
@Type(() => characterData)
players : characterData[] = [] players : characterData[] = []
getRandomInt(max) { getRandomInt(max) {

View File

@ -1,6 +1,20 @@
import sqlite3 from 'sqlite3' import sqlite3 from 'sqlite3'
import { open, Database } from 'sqlite' import { open, Database } from 'sqlite'
export class dbUser{
id : number
login : string
password : string
}
export class dbCharacter{
id : number
user_id : number
level : number
inventory : string
questBook : string
}
export class DatabaseController { export class DatabaseController {
private db: Database; private db: Database;

View File

@ -2,10 +2,11 @@ import { Socket } from "socket.io";
import { levelUpdateHost } from "../Classes/Incoming/levelUpdateHost.js"; import { levelUpdateHost } from "../Classes/Incoming/levelUpdateHost.js";
import { characterData } from "../Classes/characterData.js"; import { characterData } from "../Classes/characterData.js";
import { game } from "../game.js"; import { game } from "../game.js";
import { plainToInstance } from "class-transformer";
export function update(socket : Socket, data){ export function update(socket : Socket, data){
let buff = Buffer.from(data, 'base64'); let buff = Buffer.from(data, 'base64');
let data1 : levelUpdateHost = JSON.parse(buff.toString('utf-8')); let data1 : levelUpdateHost = plainToInstance(levelUpdateHost, JSON.parse(buff.toString('utf-8')));
let character : characterData = socket.character let character : characterData = socket.character
let room = game.lobbyState.rooms.find(l=>l.id == data1.room.id) let room = game.lobbyState.rooms.find(l=>l.id == data1.room.id)

View File

@ -2,7 +2,6 @@ import { lobbyJoin } from "../Classes/Incoming/lobbyJoin.js";
import { levelState } from "../Classes/levelState.js"; import { levelState } from "../Classes/levelState.js";
import { lobbyMessage } from "../Classes/lobbyMessage.js"; import { lobbyMessage } from "../Classes/lobbyMessage.js";
import { characterData } from "../Classes/characterData.js"; import { characterData } from "../Classes/characterData.js";
import { userData } from "../Classes/userData.js";
import { game } from "../game.js"; import { game } from "../game.js";
import { Socket } from "socket.io"; import { Socket } from "socket.io";
import { Endpoints } from "../endpoints.js"; import { Endpoints } from "../endpoints.js";
@ -12,8 +11,6 @@ export function playerJoin(socket : Socket, data){
let data1 : lobbyJoin = JSON.parse(buff.toString('utf-8')); let data1 : lobbyJoin = JSON.parse(buff.toString('utf-8'));
let character : characterData = socket.character let character : characterData = socket.character
console.log(character)
character.room = "0_0" character.room = "0_0"
character.characterId = data1.player.characterId character.characterId = data1.player.characterId
game.lobbyState.addUser(socket) game.lobbyState.addUser(socket)
@ -36,10 +33,6 @@ export function playerJoin(socket : Socket, data){
}) })
} }
console.log(spawnRoom)
console.log(spawnRoom.copyStart())
console.log(existingUsers)
//send only player to all existing players //send only player to all existing players
socket.broadcast.emit(Endpoints.PlayerJoin, JSON.stringify(newUser)); socket.broadcast.emit(Endpoints.PlayerJoin, JSON.stringify(newUser));

View File

@ -1,7 +1,8 @@
import './socketExtended.js'; import './socketExtended.js';
import 'reflect-metadata';
import express from 'express'; import express from 'express';
import { createServer } from 'http'; import { createServer } from 'http';
import { Socket, Server as SocketIOServer } from 'socket.io'; import { Server as SocketIOServer } from 'socket.io';
import { game } from "./game.js"; import { game } from "./game.js";
import { characters } from "./Characters/characters.js"; import { characters } from "./Characters/characters.js";
import { registerItemCallbacks } from "./Items/itemSocket.js"; import { registerItemCallbacks } from "./Items/itemSocket.js";
@ -51,9 +52,9 @@ io.on('connection', (socket : SocketExtended) => {
console.log(socket.id + " disconnected"); console.log(socket.id + " disconnected");
}); });
socket.on('error',function(er){ // socket.on('error',function(er){
console.log(er); // console.log(er);
}); // });
}); });
//Send player updates to everyone //Send player updates to everyone

22
package-lock.json generated
View File

@ -13,8 +13,10 @@
"@types/node": "^17.0.25", "@types/node": "^17.0.25",
"@types/socket.io": "^3.0.2", "@types/socket.io": "^3.0.2",
"better-sqlite3": "^12.2.0", "better-sqlite3": "^12.2.0",
"class-transformer": "^0.5.1",
"cors": "^2.8.5", "cors": "^2.8.5",
"express": "^4.17.3", "express": "^4.17.3",
"reflect-metadata": "^0.2.2",
"socket.io": "^4.4.1", "socket.io": "^4.4.1",
"sqlite": "^5.1.1", "sqlite": "^5.1.1",
"sqlite3": "^5.1.7", "sqlite3": "^5.1.7",
@ -531,6 +533,11 @@
"node": ">=10" "node": ">=10"
} }
}, },
"node_modules/class-transformer": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.5.1.tgz",
"integrity": "sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw=="
},
"node_modules/clean-stack": { "node_modules/clean-stack": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
@ -1857,6 +1864,11 @@
"node": ">= 6" "node": ">= 6"
} }
}, },
"node_modules/reflect-metadata": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz",
"integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q=="
},
"node_modules/retry": { "node_modules/retry": {
"version": "0.12.0", "version": "0.12.0",
"resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
@ -3013,6 +3025,11 @@
"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="
}, },
"class-transformer": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.5.1.tgz",
"integrity": "sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw=="
},
"clean-stack": { "clean-stack": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
@ -4001,6 +4018,11 @@
"util-deprecate": "^1.0.1" "util-deprecate": "^1.0.1"
} }
}, },
"reflect-metadata": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz",
"integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q=="
},
"retry": { "retry": {
"version": "0.12.0", "version": "0.12.0",
"resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",

View File

@ -14,8 +14,10 @@
"@types/node": "^17.0.25", "@types/node": "^17.0.25",
"@types/socket.io": "^3.0.2", "@types/socket.io": "^3.0.2",
"better-sqlite3": "^12.2.0", "better-sqlite3": "^12.2.0",
"class-transformer": "^0.5.1",
"cors": "^2.8.5", "cors": "^2.8.5",
"express": "^4.17.3", "express": "^4.17.3",
"reflect-metadata": "^0.2.2",
"socket.io": "^4.4.1", "socket.io": "^4.4.1",
"sqlite": "^5.1.1", "sqlite": "^5.1.1",
"sqlite3": "^5.1.7", "sqlite3": "^5.1.7",

View File

@ -6,6 +6,8 @@
"esModuleInterop": true, "esModuleInterop": true,
"allowSyntheticDefaultImports": true, "allowSyntheticDefaultImports": true,
"sourceMap": true, "sourceMap": true,
"noImplicitAny": false "noImplicitAny": false,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
} }
} }