NPM update, removed CRUD functions from object repository, added prettier
This commit is contained in:
parent
792abdfaf6
commit
6131a8455a
8
.prettierrc.json
Normal file
8
.prettierrc.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/prettierrc",
|
||||
"semi": false,
|
||||
"tabWidth": 2,
|
||||
"singleQuote": true,
|
||||
"printWidth": 300,
|
||||
"trailingComma": "none"
|
||||
}
|
27
package-lock.json
generated
27
package-lock.json
generated
@ -5,25 +5,26 @@
|
||||
"packages": {
|
||||
"": {
|
||||
"dependencies": {
|
||||
"@prisma/client": "^5.13.0",
|
||||
"@prisma/client": "^5.17.0",
|
||||
"bcryptjs": "^2.4.3",
|
||||
"cors": "^2.8.5",
|
||||
"dotenv": "^16.4.5",
|
||||
"express": "^4.19.2",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"prisma": "^5.13.0",
|
||||
"prisma": "^5.17.0",
|
||||
"sharp": "^0.33.4",
|
||||
"socket.io": "^4.7.5",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.4.5",
|
||||
"typescript": "^5.5.3",
|
||||
"zod": "^3.23.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bcryptjs": "^2.4.6",
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/jsonwebtoken": "^9.0.6",
|
||||
"@types/node": "^20.12.11",
|
||||
"nodemon": "^3.1.0"
|
||||
"@types/node": "^20.14.11",
|
||||
"nodemon": "^3.1.4",
|
||||
"prettier": "^3.3.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@cspotcode/source-map-support": {
|
||||
@ -1886,6 +1887,22 @@
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/prettier": {
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz",
|
||||
"integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"prettier": "bin/prettier.cjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/prisma": {
|
||||
"version": "5.17.0",
|
||||
"resolved": "https://registry.npmjs.org/prisma/-/prisma-5.17.0.tgz",
|
||||
|
14
package.json
14
package.json
@ -2,27 +2,29 @@
|
||||
"scripts": {
|
||||
"start": "npx prisma migrate deploy && node dist/server.js",
|
||||
"dev": "nodemon --exec ts-node src/server.ts",
|
||||
"build": "tsc"
|
||||
"build": "tsc",
|
||||
"format": "prettier --write src/"
|
||||
},
|
||||
"dependencies": {
|
||||
"@prisma/client": "^5.13.0",
|
||||
"@prisma/client": "^5.17.0",
|
||||
"bcryptjs": "^2.4.3",
|
||||
"cors": "^2.8.5",
|
||||
"dotenv": "^16.4.5",
|
||||
"express": "^4.19.2",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"prisma": "^5.13.0",
|
||||
"prisma": "^5.17.0",
|
||||
"sharp": "^0.33.4",
|
||||
"socket.io": "^4.7.5",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.4.5",
|
||||
"typescript": "^5.5.3",
|
||||
"zod": "^3.23.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bcryptjs": "^2.4.6",
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/jsonwebtoken": "^9.0.6",
|
||||
"@types/node": "^20.12.11",
|
||||
"nodemon": "^3.1.0"
|
||||
"@types/node": "^20.14.11",
|
||||
"nodemon": "^3.1.4",
|
||||
"prettier": "^3.3.3"
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { Server } from "socket.io";
|
||||
import { Server } from 'socket.io'
|
||||
|
||||
type CommandInput = string[]
|
||||
|
||||
export default function (input: CommandInput, io: Server) {
|
||||
const message: string = input.join(' ') ?? null;
|
||||
if (!message) return console.log('message is required');
|
||||
io.emit('notification', {message: message});
|
||||
};
|
||||
const message: string = input.join(' ') ?? null
|
||||
if (!message) return console.log('message is required')
|
||||
io.emit('notification', { message: message })
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { Server } from "socket.io";
|
||||
import ZoneManager from "../managers/ZoneManager";
|
||||
import { Server } from 'socket.io'
|
||||
import ZoneManager from '../managers/ZoneManager'
|
||||
|
||||
type CommandInput = string[]
|
||||
|
||||
export default function (input: CommandInput, io: Server) {
|
||||
console.log(ZoneManager.getLoadedZones())
|
||||
};
|
||||
}
|
||||
|
@ -1,23 +1,23 @@
|
||||
import { Server } from "socket.io";
|
||||
import {TSocket} from "../utilities/Types";
|
||||
import ZoneManager from "../managers/ZoneManager";
|
||||
import { Server } from 'socket.io'
|
||||
import { TSocket } from '../utilities/Types'
|
||||
import ZoneManager from '../managers/ZoneManager'
|
||||
|
||||
export default function (socket: TSocket, io: Server) {
|
||||
socket.on('disconnect', (data: any) => {
|
||||
if (!socket.user) {
|
||||
console.log('User disconnected but had no user set');
|
||||
return;
|
||||
console.log('User disconnected but had no user set')
|
||||
return
|
||||
}
|
||||
|
||||
io.emit('user:disconnect', socket.user.id);
|
||||
io.emit('user:disconnect', socket.user.id)
|
||||
|
||||
if (!socket.character) {
|
||||
console.log('User disconnected but had no character set');
|
||||
return;
|
||||
console.log('User disconnected but had no character set')
|
||||
return
|
||||
}
|
||||
|
||||
ZoneManager.removeCharacterFromZone(socket.character.zoneId, socket.character);
|
||||
ZoneManager.removeCharacterFromZone(socket.character.zoneId, socket.character)
|
||||
|
||||
io.emit('character:disconnect', socket.character.id);
|
||||
});
|
||||
io.emit('character:disconnect', socket.character.id)
|
||||
})
|
||||
}
|
@ -1,9 +1,9 @@
|
||||
import { Server } from "socket.io";
|
||||
import {TSocket} from "../utilities/Types";
|
||||
import { Server } from 'socket.io'
|
||||
import { TSocket } from '../utilities/Types'
|
||||
|
||||
export default function (socket: TSocket, io: Server) {
|
||||
socket.on('login', () => {
|
||||
// return user data
|
||||
socket.emit('logged_in', {user: socket.user});
|
||||
});
|
||||
socket.emit('logged_in', { user: socket.user })
|
||||
})
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
import { Socket, Server } from "socket.io";
|
||||
import {TSocket} from "../../utilities/Types";
|
||||
import CharacterRepository from "../../repositories/CharacterRepository";
|
||||
import {Character, User} from "@prisma/client";
|
||||
import { Socket, Server } from 'socket.io'
|
||||
import { TSocket } from '../../utilities/Types'
|
||||
import CharacterRepository from '../../repositories/CharacterRepository'
|
||||
import { Character, User } from '@prisma/client'
|
||||
|
||||
type SocketResponseT = {
|
||||
character_id: number
|
||||
@ -9,12 +9,12 @@ type SocketResponseT = {
|
||||
|
||||
export default function (socket: TSocket, io: Server) {
|
||||
socket.on('character:connect', async (data: SocketResponseT) => {
|
||||
console.log('character:connect requested', data);
|
||||
console.log('character:connect requested', data)
|
||||
try {
|
||||
socket.character = await CharacterRepository.getByUserAndId(socket.user?.id as number, data.character_id) as Character;
|
||||
socket.character = (await CharacterRepository.getByUserAndId(socket.user?.id as number, data.character_id)) as Character
|
||||
socket.emit('character:connect', socket.character)
|
||||
} catch (error: any) {
|
||||
console.log('character:connect error', error);
|
||||
console.log('character:connect error', error)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
@ -1,37 +1,37 @@
|
||||
import { Server } from "socket.io";
|
||||
import {TSocket} from "../../utilities/Types";
|
||||
import {Character} from "@prisma/client";
|
||||
import CharacterRepository from "../../repositories/CharacterRepository";
|
||||
import {ZCharacterCreate} from "../../utilities/ZodTypes";
|
||||
import { Server } from 'socket.io'
|
||||
import { TSocket } from '../../utilities/Types'
|
||||
import { Character } from '@prisma/client'
|
||||
import CharacterRepository from '../../repositories/CharacterRepository'
|
||||
import { ZCharacterCreate } from '../../utilities/ZodTypes'
|
||||
|
||||
export default function (socket: TSocket, io: Server) {
|
||||
socket.on('character:create', async (data: any) => {
|
||||
// zod validate
|
||||
try {
|
||||
data = ZCharacterCreate.parse(data);
|
||||
data = ZCharacterCreate.parse(data)
|
||||
|
||||
const user_id = socket.user?.id as number;
|
||||
const user_id = socket.user?.id as number
|
||||
|
||||
// Check if character name already exists
|
||||
const characterExists = await CharacterRepository.getByName(data.name);
|
||||
const characterExists = await CharacterRepository.getByName(data.name)
|
||||
|
||||
if (characterExists) {
|
||||
return socket.emit('notification', {message: 'Character name already exists'});
|
||||
return socket.emit('notification', { message: 'Character name already exists' })
|
||||
}
|
||||
|
||||
let characters: Character[] = await CharacterRepository.getByUserId(user_id) as Character[];
|
||||
let characters: Character[] = (await CharacterRepository.getByUserId(user_id)) as Character[]
|
||||
|
||||
if (characters.length >= 4) {
|
||||
return socket.emit('notification', {message: 'You can only have 4 characters'});
|
||||
return socket.emit('notification', { message: 'You can only have 4 characters' })
|
||||
}
|
||||
|
||||
const character: Character = await CharacterRepository.create(user_id, data.name, 'player') as Character;
|
||||
characters = [...characters, character];
|
||||
const character: Character = (await CharacterRepository.create(user_id, data.name, 'player')) as Character
|
||||
characters = [...characters, character]
|
||||
|
||||
socket.emit('character:create:success');
|
||||
socket.emit('character:list', characters);
|
||||
socket.emit('character:create:success')
|
||||
socket.emit('character:list', characters)
|
||||
} catch (error: any) {
|
||||
return socket.emit('notification', {message: error.errors[0]?.message ?? 'Invalid data'});
|
||||
return socket.emit('notification', { message: error.errors[0]?.message ?? 'Invalid data' })
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
@ -1,30 +1,30 @@
|
||||
import {Server} from "socket.io";
|
||||
import {TSocket} from "../../utilities/Types";
|
||||
import { Server } from 'socket.io'
|
||||
import { TSocket } from '../../utilities/Types'
|
||||
import { Character, Zone } from '@prisma/client'
|
||||
import CharacterRepository from "../../repositories/CharacterRepository";
|
||||
import CharacterRepository from '../../repositories/CharacterRepository'
|
||||
|
||||
type TypePayload = {
|
||||
character_id: number;
|
||||
character_id: number
|
||||
}
|
||||
|
||||
type TypeResponse = {
|
||||
zone: Zone;
|
||||
characters: Character[];
|
||||
zone: Zone
|
||||
characters: Character[]
|
||||
}
|
||||
|
||||
export default function (socket: TSocket, io: Server) {
|
||||
socket.on('character:delete', async (data: TypePayload, callback: (response: TypeResponse) => void) => {
|
||||
// zod validate
|
||||
try {
|
||||
await CharacterRepository.deleteByUserIdAndId(socket.user?.id as number, data.character_id as number);
|
||||
await CharacterRepository.deleteByUserIdAndId(socket.user?.id as number, data.character_id as number)
|
||||
|
||||
const user_id = socket.user?.id as number;
|
||||
const characters: Character[] = await CharacterRepository.getByUserId(user_id) as Character[];
|
||||
const user_id = socket.user?.id as number
|
||||
const characters: Character[] = (await CharacterRepository.getByUserId(user_id)) as Character[]
|
||||
|
||||
socket.emit('character:list', characters);
|
||||
socket.emit('character:list', characters)
|
||||
} catch (error: any) {
|
||||
console.log(error);
|
||||
return socket.emit('notification', {message: 'Character delete failed. Please try again.'});
|
||||
console.log(error)
|
||||
return socket.emit('notification', { message: 'Character delete failed. Please try again.' })
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
@ -1,17 +1,17 @@
|
||||
import { Socket, Server } from "socket.io";
|
||||
import {TSocket} from "../../utilities/Types";
|
||||
import {Character} from "@prisma/client";
|
||||
import CharacterRepository from "../../repositories/CharacterRepository";
|
||||
import { Socket, Server } from 'socket.io'
|
||||
import { TSocket } from '../../utilities/Types'
|
||||
import { Character } from '@prisma/client'
|
||||
import CharacterRepository from '../../repositories/CharacterRepository'
|
||||
|
||||
export default function CharacterList(socket: TSocket, io: Server) {
|
||||
socket.on('character:list', async (data: any) => {
|
||||
try {
|
||||
console.log('character:list requested');
|
||||
const user_id = socket.user?.id as number;
|
||||
const characters: Character[] = await CharacterRepository.getByUserId(user_id) as Character[];
|
||||
socket.emit('character:list', characters);
|
||||
console.log('character:list requested')
|
||||
const user_id = socket.user?.id as number
|
||||
const characters: Character[] = (await CharacterRepository.getByUserId(user_id)) as Character[]
|
||||
socket.emit('character:list', characters)
|
||||
} catch (error: any) {
|
||||
console.log('character:list error', error);
|
||||
console.log('character:list error', error)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
@ -1,33 +1,33 @@
|
||||
import { Server } from "socket.io";
|
||||
import {TSocket} from "../../utilities/Types";
|
||||
import CharacterRepository from "../../repositories/CharacterRepository";
|
||||
import ZoneManager from "../../managers/ZoneManager";
|
||||
import { Server } from 'socket.io'
|
||||
import { TSocket } from '../../utilities/Types'
|
||||
import CharacterRepository from '../../repositories/CharacterRepository'
|
||||
import ZoneManager from '../../managers/ZoneManager'
|
||||
|
||||
type SocketResponseT = {
|
||||
position_x: number,
|
||||
position_y: number,
|
||||
position_x: number
|
||||
position_y: number
|
||||
}
|
||||
|
||||
export default function (socket: TSocket, io: Server) {
|
||||
socket.on('character:move', async (data: SocketResponseT) => {
|
||||
try {
|
||||
console.log('character:move requested', data);
|
||||
console.log('character:move requested', data)
|
||||
|
||||
if (!socket.character) {
|
||||
console.log('character:move error', 'Character not found');
|
||||
return;
|
||||
console.log('character:move error', 'Character not found')
|
||||
return
|
||||
}
|
||||
|
||||
socket.character.position_x = data.position_x;
|
||||
socket.character.position_y = data.position_y;
|
||||
socket.character.position_x = data.position_x
|
||||
socket.character.position_y = data.position_y
|
||||
|
||||
await CharacterRepository.updatePosition(socket.character.id as number, data.position_x, data.position_y);
|
||||
ZoneManager.updateCharacterInZone(socket.character.zoneId, socket.character);
|
||||
console.log(socket.character);
|
||||
await CharacterRepository.updatePosition(socket.character.id as number, data.position_x, data.position_y)
|
||||
ZoneManager.updateCharacterInZone(socket.character.zoneId, socket.character)
|
||||
console.log(socket.character)
|
||||
|
||||
io.in(socket.character.zoneId.toString()).emit('character:moved', socket.character);
|
||||
io.in(socket.character.zoneId.toString()).emit('character:moved', socket.character)
|
||||
} catch (error: any) {
|
||||
console.log('character:move error', error);
|
||||
console.log('character:move error', error)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
import { Server } from "socket.io";
|
||||
import {TSocket} from "../../utilities/Types";
|
||||
import ZoneRepository from "../../repositories/ZoneRepository";
|
||||
import ZoneManager from "../../managers/ZoneManager";
|
||||
import {Character, Zone} from "@prisma/client";
|
||||
import { Server } from 'socket.io'
|
||||
import { TSocket } from '../../utilities/Types'
|
||||
import ZoneRepository from '../../repositories/ZoneRepository'
|
||||
import ZoneManager from '../../managers/ZoneManager'
|
||||
import { Character, Zone } from '@prisma/client'
|
||||
|
||||
/**
|
||||
* Handle character zone leave event
|
||||
@ -11,35 +11,35 @@ import {Character, Zone} from "@prisma/client";
|
||||
*/
|
||||
export default function (socket: TSocket, io: Server) {
|
||||
socket.on('character:zone:leave', async () => {
|
||||
console.log(`---Socket ${socket.character?.id} has leaved zone.`);
|
||||
console.log(`---Socket ${socket.character?.id} has leaved zone.`)
|
||||
|
||||
if (!socket.character) {
|
||||
console.log('Socket leaved zone but had no character set');
|
||||
return;
|
||||
console.log('Socket leaved zone but had no character set')
|
||||
return
|
||||
}
|
||||
|
||||
if (!socket.character.zoneId) {
|
||||
console.log(`---Zone id not provided.`);
|
||||
return;
|
||||
console.log(`---Zone id not provided.`)
|
||||
return
|
||||
}
|
||||
|
||||
const zone = await ZoneRepository.getById(socket.character.zoneId);
|
||||
const zone = await ZoneRepository.getById(socket.character.zoneId)
|
||||
|
||||
if (!zone) {
|
||||
console.log(`---Zone not found.`);
|
||||
return;
|
||||
console.log(`---Zone not found.`)
|
||||
return
|
||||
}
|
||||
|
||||
socket.leave(zone.id.toString());
|
||||
socket.leave(zone.id.toString())
|
||||
|
||||
socket.emit('character:zone:unload');
|
||||
socket.emit('character:zone:unload')
|
||||
|
||||
// let other clients know of new character
|
||||
io.to(zone.id.toString()).emit('zone:character:leave', socket.character);
|
||||
io.to(zone.id.toString()).emit('zone:character:leave', socket.character)
|
||||
|
||||
// add character to zone manager
|
||||
ZoneManager.removeCharacterFromZone(zone.id, socket.character as Character);
|
||||
});
|
||||
ZoneManager.removeCharacterFromZone(zone.id, socket.character as Character)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,16 +1,16 @@
|
||||
import { Server } from "socket.io";
|
||||
import {TSocket} from "../../utilities/Types";
|
||||
import ZoneRepository from "../../repositories/ZoneRepository";
|
||||
import ZoneManager from "../../managers/ZoneManager";
|
||||
import {Character, Zone} from "@prisma/client";
|
||||
import { Server } from 'socket.io'
|
||||
import { TSocket } from '../../utilities/Types'
|
||||
import ZoneRepository from '../../repositories/ZoneRepository'
|
||||
import ZoneManager from '../../managers/ZoneManager'
|
||||
import { Character, Zone } from '@prisma/client'
|
||||
|
||||
interface IPayload {
|
||||
zoneId: number;
|
||||
zoneId: number
|
||||
}
|
||||
|
||||
interface IResponse {
|
||||
zone: Zone;
|
||||
characters: Character[];
|
||||
zone: Zone
|
||||
characters: Character[]
|
||||
}
|
||||
|
||||
/**
|
||||
@ -20,29 +20,29 @@ interface IResponse {
|
||||
*/
|
||||
export default function (socket: TSocket, io: Server) {
|
||||
socket.on('character:zone:request', async (data: IPayload, callback: (response: IResponse) => void) => {
|
||||
console.log(`---User ${socket.character?.id} has requested zone.`);
|
||||
console.log(`---User ${socket.character?.id} has requested zone.`)
|
||||
|
||||
if (!data.zoneId) {
|
||||
console.log(`---Zone id not provided.`);
|
||||
return;
|
||||
console.log(`---Zone id not provided.`)
|
||||
return
|
||||
}
|
||||
|
||||
const zone = await ZoneRepository.getById(data.zoneId);
|
||||
const zone = await ZoneRepository.getById(data.zoneId)
|
||||
|
||||
if (!zone) {
|
||||
console.log(`---Zone not found.`);
|
||||
return;
|
||||
console.log(`---Zone not found.`)
|
||||
return
|
||||
}
|
||||
|
||||
socket.join(zone.id.toString());
|
||||
socket.join(zone.id.toString())
|
||||
|
||||
// send over zone and characters to socket
|
||||
callback({zone, characters: ZoneManager.getCharactersInZone(zone.id)});
|
||||
callback({ zone, characters: ZoneManager.getCharactersInZone(zone.id) })
|
||||
|
||||
// let other clients know of new character
|
||||
io.to(zone.id.toString()).emit('zone:character:join', socket.character);
|
||||
io.to(zone.id.toString()).emit('zone:character:join', socket.character)
|
||||
|
||||
// add character to zone manager
|
||||
ZoneManager.addCharacterToZone(zone.id, socket.character as Character);
|
||||
});
|
||||
ZoneManager.addCharacterToZone(zone.id, socket.character as Character)
|
||||
})
|
||||
}
|
@ -1,10 +1,9 @@
|
||||
import { Server } from "socket.io";
|
||||
import {TSocket} from "../../../utilities/Types";
|
||||
import { Server } from 'socket.io'
|
||||
import { TSocket } from '../../../utilities/Types'
|
||||
import { Object } from '@prisma/client'
|
||||
import ObjectRepository from '../../../repositories/ObjectRepository'
|
||||
|
||||
interface IPayload {
|
||||
}
|
||||
interface IPayload {}
|
||||
|
||||
/**
|
||||
* Handle game master list object event
|
||||
@ -13,14 +12,13 @@ interface IPayload {
|
||||
*/
|
||||
export default function (socket: TSocket, io: Server) {
|
||||
socket.on('gm:object:list', async (data: any, callback: (response: Object[]) => void) => {
|
||||
|
||||
if (socket.character?.role !== 'gm') {
|
||||
console.log(`---Character #${socket.character?.id} is not a game master.`);
|
||||
return;
|
||||
console.log(`---Character #${socket.character?.id} is not a game master.`)
|
||||
return
|
||||
}
|
||||
|
||||
// get all objects
|
||||
const objects = await ObjectRepository.getAll();
|
||||
callback(objects);
|
||||
});
|
||||
const objects = await ObjectRepository.getAll()
|
||||
callback(objects)
|
||||
})
|
||||
}
|
@ -1,11 +1,11 @@
|
||||
import { Server } from "socket.io";
|
||||
import {TSocket} from "../../../utilities/Types";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
import ObjectRepository from '../../../repositories/ObjectRepository'
|
||||
import { Server } from 'socket.io'
|
||||
import { TSocket } from '../../../utilities/Types'
|
||||
import path from 'path'
|
||||
import fs from 'fs'
|
||||
import prisma from '../../../utilities/Prisma'
|
||||
|
||||
interface IPayload {
|
||||
object: string;
|
||||
object: string
|
||||
}
|
||||
|
||||
/**
|
||||
@ -15,31 +15,34 @@ interface IPayload {
|
||||
*/
|
||||
export default function (socket: TSocket, io: Server) {
|
||||
socket.on('gm:object:remove', async (data: IPayload, callback: (response: boolean) => void) => {
|
||||
|
||||
if (socket.character?.role !== 'gm') {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
await ObjectRepository.delete(data.object);
|
||||
await prisma.object.delete({
|
||||
where: {
|
||||
id: data.object
|
||||
}
|
||||
})
|
||||
|
||||
// get root path
|
||||
const public_folder = path.join(process.cwd(), 'public', 'objects');
|
||||
const public_folder = path.join(process.cwd(), 'public', 'objects')
|
||||
|
||||
// remove the tile from the disk
|
||||
const finalFilePath = path.join(public_folder, data.object + '.png');
|
||||
const finalFilePath = path.join(public_folder, data.object + '.png')
|
||||
fs.unlink(finalFilePath, (err) => {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
callback(false);
|
||||
return;
|
||||
console.log(err)
|
||||
callback(false)
|
||||
return
|
||||
}
|
||||
|
||||
callback(true);
|
||||
});
|
||||
callback(true)
|
||||
})
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
callback(false);
|
||||
console.log(e)
|
||||
callback(false)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
@ -1,14 +1,14 @@
|
||||
import { Server } from "socket.io";
|
||||
import {TSocket} from "../../../utilities/Types";
|
||||
import ObjectRepository from '../../../repositories/ObjectRepository'
|
||||
import { Object } from '@prisma/client'
|
||||
import { Server } from 'socket.io'
|
||||
import { TSocket } from '../../../utilities/Types'
|
||||
import prisma from '../../../utilities/Prisma'
|
||||
|
||||
interface IPayload {
|
||||
id: string;
|
||||
name: string;
|
||||
tags: string[];
|
||||
origin_x: number;
|
||||
origin_y: number;
|
||||
id: string
|
||||
name: string
|
||||
tags: string[]
|
||||
origin_x: number
|
||||
origin_y: number
|
||||
isAnimated: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
@ -18,18 +18,27 @@ interface IPayload {
|
||||
*/
|
||||
export default function (socket: TSocket, io: Server) {
|
||||
socket.on('gm:object:update', async (data: IPayload, callback: (success: boolean) => void) => {
|
||||
|
||||
if (socket.character?.role !== 'gm') {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const object = await ObjectRepository.update(data.id, data.name, data.tags, data.origin_x, data.origin_y);
|
||||
|
||||
callback(true);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
callback(false);
|
||||
const object = await prisma.object.update({
|
||||
where: {
|
||||
id: data.id
|
||||
},
|
||||
data: {
|
||||
name: data.name,
|
||||
tags: data.tags,
|
||||
origin_x: data.origin_x,
|
||||
origin_y: data.origin_y,
|
||||
isAnimated: data.isAnimated
|
||||
}
|
||||
});
|
||||
})
|
||||
callback(true)
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
callback(false)
|
||||
}
|
||||
})
|
||||
}
|
@ -1,12 +1,12 @@
|
||||
import { Server } from "socket.io";
|
||||
import { TSocket } from "../../../utilities/Types";
|
||||
import { writeFile } from "node:fs/promises";
|
||||
import path from "path";
|
||||
import fs from "fs/promises";
|
||||
import objectRepository from '../../../repositories/ObjectRepository'
|
||||
import { Server } from 'socket.io'
|
||||
import { TSocket } from '../../../utilities/Types'
|
||||
import { writeFile } from 'node:fs/promises'
|
||||
import path from 'path'
|
||||
import fs from 'fs/promises'
|
||||
import prisma from '../../../utilities/Prisma'
|
||||
|
||||
interface IObjectData {
|
||||
[key: string]: Buffer;
|
||||
[key: string]: Buffer
|
||||
}
|
||||
|
||||
/**
|
||||
@ -18,29 +18,38 @@ export default function (socket: TSocket, io: Server) {
|
||||
socket.on('gm:object:upload', async (data: IObjectData, callback: (response: boolean) => void) => {
|
||||
try {
|
||||
if (socket.character?.role !== 'gm') {
|
||||
callback(false);
|
||||
return;
|
||||
callback(false)
|
||||
return
|
||||
}
|
||||
|
||||
const public_folder = path.join(process.cwd(), 'public', 'objects');
|
||||
const public_folder = path.join(process.cwd(), 'public', 'objects')
|
||||
|
||||
// Ensure the folder exists
|
||||
await fs.mkdir(public_folder, { recursive: true });
|
||||
await fs.mkdir(public_folder, { recursive: true })
|
||||
|
||||
const uploadPromises = Object.entries(data).map(async ([key, objectData]) => {
|
||||
const object = await objectRepository.create('New object', 0, 0);
|
||||
const uuid = object.id;
|
||||
const filename = `${uuid}.png`;
|
||||
const finalFilePath = path.join(public_folder, filename);
|
||||
await writeFile(finalFilePath, objectData);
|
||||
});
|
||||
|
||||
await Promise.all(uploadPromises);
|
||||
|
||||
callback(true);
|
||||
} catch (error) {
|
||||
console.error('Error uploading tile:', error);
|
||||
callback(false);
|
||||
const object = await prisma.object.create({
|
||||
data: {
|
||||
name: key,
|
||||
tags: [],
|
||||
origin_x: 0,
|
||||
origin_y: 0,
|
||||
isAnimated: false
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
const uuid = object.id
|
||||
const filename = `${uuid}.png`
|
||||
const finalFilePath = path.join(public_folder, filename)
|
||||
await writeFile(finalFilePath, objectData)
|
||||
})
|
||||
|
||||
await Promise.all(uploadPromises)
|
||||
|
||||
callback(true)
|
||||
} catch (error) {
|
||||
console.error('Error uploading tile:', error)
|
||||
callback(false)
|
||||
}
|
||||
})
|
||||
}
|
@ -1,10 +1,9 @@
|
||||
import { Server } from "socket.io";
|
||||
import {TSocket} from "../../../utilities/Types";
|
||||
import { Server } from 'socket.io'
|
||||
import { TSocket } from '../../../utilities/Types'
|
||||
import { Sprite } from '@prisma/client'
|
||||
import SpriteRepository from '../../../repositories/SpriteRepository'
|
||||
|
||||
interface IPayload {
|
||||
}
|
||||
interface IPayload {}
|
||||
|
||||
/**
|
||||
* Handle game master list sprite event
|
||||
@ -13,14 +12,13 @@ interface IPayload {
|
||||
*/
|
||||
export default function (socket: TSocket, io: Server) {
|
||||
socket.on('gm:sprite:list', async (data: any, callback: (response: Sprite[]) => void) => {
|
||||
|
||||
if (socket.character?.role !== 'gm') {
|
||||
console.log(`---Character #${socket.character?.id} is not a game master.`);
|
||||
return;
|
||||
console.log(`---Character #${socket.character?.id} is not a game master.`)
|
||||
return
|
||||
}
|
||||
|
||||
// get all sprites
|
||||
const sprites = await SpriteRepository.getAll();
|
||||
callback(sprites);
|
||||
});
|
||||
const sprites = await SpriteRepository.getAll()
|
||||
callback(sprites)
|
||||
})
|
||||
}
|
@ -1,11 +1,11 @@
|
||||
import { Server } from "socket.io";
|
||||
import {TSocket} from "../../../utilities/Types";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
import { Server } from 'socket.io'
|
||||
import { TSocket } from '../../../utilities/Types'
|
||||
import path from 'path'
|
||||
import fs from 'fs'
|
||||
import SpriteRepository from '../../../repositories/SpriteRepository'
|
||||
|
||||
interface IPayload {
|
||||
sprite: string;
|
||||
sprite: string
|
||||
}
|
||||
|
||||
/**
|
||||
@ -15,31 +15,30 @@ interface IPayload {
|
||||
*/
|
||||
export default function (socket: TSocket, io: Server) {
|
||||
socket.on('gm:sprite:remove', async (data: IPayload, callback: (response: boolean) => void) => {
|
||||
|
||||
if (socket.character?.role !== 'gm') {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
await SpriteRepository.delete(data.sprite);
|
||||
await SpriteRepository.delete(data.sprite)
|
||||
|
||||
// get root path
|
||||
const public_folder = path.join(process.cwd(), 'public', 'sprites');
|
||||
const public_folder = path.join(process.cwd(), 'public', 'sprites')
|
||||
|
||||
// remove the tile from the disk
|
||||
const finalFilePath = path.join(public_folder, data.sprite + '.png');
|
||||
const finalFilePath = path.join(public_folder, data.sprite + '.png')
|
||||
fs.unlink(finalFilePath, (err) => {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
callback(false);
|
||||
return;
|
||||
console.log(err)
|
||||
callback(false)
|
||||
return
|
||||
}
|
||||
|
||||
callback(true);
|
||||
});
|
||||
callback(true)
|
||||
})
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
callback(false);
|
||||
console.log(e)
|
||||
callback(false)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
@ -1,13 +1,13 @@
|
||||
import { Server } from "socket.io";
|
||||
import {TSocket} from "../../../utilities/Types";
|
||||
import { Server } from 'socket.io'
|
||||
import { TSocket } from '../../../utilities/Types'
|
||||
import SpriteRepository from '../../../repositories/SpriteRepository'
|
||||
import { Sprite } from '@prisma/client'
|
||||
|
||||
interface IPayload {
|
||||
id: string;
|
||||
name: string;
|
||||
origin_x: number;
|
||||
origin_y: number;
|
||||
id: string
|
||||
name: string
|
||||
origin_x: number
|
||||
origin_y: number
|
||||
}
|
||||
|
||||
/**
|
||||
@ -17,18 +17,17 @@ interface IPayload {
|
||||
*/
|
||||
export default function (socket: TSocket, io: Server) {
|
||||
socket.on('gm:sprite:update', async (data: IPayload, callback: (success: boolean) => void) => {
|
||||
|
||||
if (socket.character?.role !== 'gm') {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const sprite = await SpriteRepository.update(data.id, data.name, data.origin_x, data.origin_y);
|
||||
const sprite = await SpriteRepository.update(data.id, data.name, data.origin_x, data.origin_y)
|
||||
|
||||
callback(true);
|
||||
callback(true)
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
callback(false);
|
||||
console.error(error)
|
||||
callback(false)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
@ -1,12 +1,12 @@
|
||||
import { Server } from "socket.io";
|
||||
import { TSocket } from "../../../utilities/Types";
|
||||
import { writeFile } from "node:fs/promises";
|
||||
import path from "path";
|
||||
import fs from "fs/promises";
|
||||
import { Server } from 'socket.io'
|
||||
import { TSocket } from '../../../utilities/Types'
|
||||
import { writeFile } from 'node:fs/promises'
|
||||
import path from 'path'
|
||||
import fs from 'fs/promises'
|
||||
import spriteRepository from '../../../repositories/SpriteRepository'
|
||||
|
||||
interface ISpriteData {
|
||||
[key: string]: Buffer;
|
||||
[key: string]: Buffer
|
||||
}
|
||||
|
||||
/**
|
||||
@ -18,29 +18,29 @@ export default function (socket: TSocket, io: Server) {
|
||||
socket.on('gm:sprite:upload', async (data: ISpriteData, callback: (response: boolean) => void) => {
|
||||
try {
|
||||
if (socket.character?.role !== 'gm') {
|
||||
callback(false);
|
||||
return;
|
||||
callback(false)
|
||||
return
|
||||
}
|
||||
|
||||
const public_folder = path.join(process.cwd(), 'public', 'sprites');
|
||||
const public_folder = path.join(process.cwd(), 'public', 'sprites')
|
||||
|
||||
// Ensure the folder exists
|
||||
await fs.mkdir(public_folder, { recursive: true });
|
||||
await fs.mkdir(public_folder, { recursive: true })
|
||||
|
||||
const uploadPromises = Object.entries(data).map(async ([key, spriteData]) => {
|
||||
const sprite = await spriteRepository.create('New sprite', 0, 0);
|
||||
const uuid = sprite.id;
|
||||
const filename = `${uuid}.png`;
|
||||
const finalFilePath = path.join(public_folder, filename);
|
||||
await writeFile(finalFilePath, spriteData);
|
||||
});
|
||||
const sprite = await spriteRepository.create('New sprite', 0, 0)
|
||||
const uuid = sprite.id
|
||||
const filename = `${uuid}.png`
|
||||
const finalFilePath = path.join(public_folder, filename)
|
||||
await writeFile(finalFilePath, spriteData)
|
||||
})
|
||||
|
||||
await Promise.all(uploadPromises);
|
||||
await Promise.all(uploadPromises)
|
||||
|
||||
callback(true);
|
||||
callback(true)
|
||||
} catch (error) {
|
||||
console.error('Error uploading tile:', error);
|
||||
callback(false);
|
||||
console.error('Error uploading tile:', error)
|
||||
callback(false)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
@ -1,10 +1,9 @@
|
||||
import { Server } from "socket.io";
|
||||
import {TSocket} from "../../../utilities/Types";
|
||||
import { Server } from 'socket.io'
|
||||
import { TSocket } from '../../../utilities/Types'
|
||||
import { Tile } from '@prisma/client'
|
||||
import TileRepository from '../../../repositories/TileRepository'
|
||||
|
||||
interface IPayload {
|
||||
}
|
||||
interface IPayload {}
|
||||
|
||||
/**
|
||||
* Handle game master list tile event
|
||||
@ -13,14 +12,13 @@ interface IPayload {
|
||||
*/
|
||||
export default function (socket: TSocket, io: Server) {
|
||||
socket.on('gm:tile:list', async (data: any, callback: (response: Tile[]) => void) => {
|
||||
|
||||
if (socket.character?.role !== 'gm') {
|
||||
console.log(`---Character #${socket.character?.id} is not a game master.`);
|
||||
return;
|
||||
console.log(`---Character #${socket.character?.id} is not a game master.`)
|
||||
return
|
||||
}
|
||||
|
||||
// get all tiles
|
||||
const tiles = await TileRepository.getAll();
|
||||
callback(tiles);
|
||||
});
|
||||
const tiles = await TileRepository.getAll()
|
||||
callback(tiles)
|
||||
})
|
||||
}
|
@ -1,11 +1,11 @@
|
||||
import { Server } from "socket.io";
|
||||
import {TSocket} from "../../../utilities/Types";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
import { Server } from 'socket.io'
|
||||
import { TSocket } from '../../../utilities/Types'
|
||||
import path from 'path'
|
||||
import fs from 'fs'
|
||||
import TileRepository from '../../../repositories/TileRepository'
|
||||
|
||||
interface IPayload {
|
||||
tile: string;
|
||||
tile: string
|
||||
}
|
||||
|
||||
/**
|
||||
@ -15,31 +15,30 @@ interface IPayload {
|
||||
*/
|
||||
export default function (socket: TSocket, io: Server) {
|
||||
socket.on('gm:tile:remove', async (data: IPayload, callback: (response: boolean) => void) => {
|
||||
|
||||
if (socket.character?.role !== 'gm') {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
await TileRepository.delete(data.tile);
|
||||
await TileRepository.delete(data.tile)
|
||||
|
||||
// get root path
|
||||
const public_folder = path.join(process.cwd(), 'public', 'tiles');
|
||||
const public_folder = path.join(process.cwd(), 'public', 'tiles')
|
||||
|
||||
// remove the tile from the disk
|
||||
const finalFilePath = path.join(public_folder, data.tile + '.png');
|
||||
const finalFilePath = path.join(public_folder, data.tile + '.png')
|
||||
fs.unlink(finalFilePath, (err) => {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
callback(false);
|
||||
return;
|
||||
console.log(err)
|
||||
callback(false)
|
||||
return
|
||||
}
|
||||
|
||||
callback(true);
|
||||
});
|
||||
callback(true)
|
||||
})
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
callback(false);
|
||||
console.log(e)
|
||||
callback(false)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
@ -1,11 +1,11 @@
|
||||
import { Server } from "socket.io";
|
||||
import {TSocket} from "../../../utilities/Types";
|
||||
import { Server } from 'socket.io'
|
||||
import { TSocket } from '../../../utilities/Types'
|
||||
import TileRepository from '../../../repositories/TileRepository'
|
||||
|
||||
interface IPayload {
|
||||
id: string;
|
||||
name: string;
|
||||
tags: string[];
|
||||
id: string
|
||||
name: string
|
||||
tags: string[]
|
||||
}
|
||||
|
||||
/**
|
||||
@ -15,18 +15,17 @@ interface IPayload {
|
||||
*/
|
||||
export default function (socket: TSocket, io: Server) {
|
||||
socket.on('gm:tile:update', async (data: IPayload, callback: (success: boolean) => void) => {
|
||||
|
||||
if (socket.character?.role !== 'gm') {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const Tile = await TileRepository.update(data.id, data.name, data.tags);
|
||||
const Tile = await TileRepository.update(data.id, data.name, data.tags)
|
||||
|
||||
callback(true);
|
||||
callback(true)
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
callback(false);
|
||||
console.error(error)
|
||||
callback(false)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
@ -1,12 +1,12 @@
|
||||
import { Server } from "socket.io";
|
||||
import { TSocket } from "../../../utilities/Types";
|
||||
import { writeFile } from "node:fs/promises";
|
||||
import path from "path";
|
||||
import fs from "fs/promises";
|
||||
import { Server } from 'socket.io'
|
||||
import { TSocket } from '../../../utilities/Types'
|
||||
import { writeFile } from 'node:fs/promises'
|
||||
import path from 'path'
|
||||
import fs from 'fs/promises'
|
||||
import tileRepository from '../../../repositories/TileRepository'
|
||||
|
||||
interface ITileData {
|
||||
[key: string]: Buffer;
|
||||
[key: string]: Buffer
|
||||
}
|
||||
|
||||
/**
|
||||
@ -18,29 +18,29 @@ export default function (socket: TSocket, io: Server) {
|
||||
socket.on('gm:tile:upload', async (data: ITileData, callback: (response: boolean) => void) => {
|
||||
try {
|
||||
if (socket.character?.role !== 'gm') {
|
||||
callback(false);
|
||||
return;
|
||||
callback(false)
|
||||
return
|
||||
}
|
||||
|
||||
const public_folder = path.join(process.cwd(), 'public', 'tiles');
|
||||
const public_folder = path.join(process.cwd(), 'public', 'tiles')
|
||||
|
||||
// Ensure the folder exists
|
||||
await fs.mkdir(public_folder, { recursive: true });
|
||||
await fs.mkdir(public_folder, { recursive: true })
|
||||
|
||||
const uploadPromises = Object.entries(data).map(async ([key, tileData]) => {
|
||||
const tile = await tileRepository.create('New tile');
|
||||
const uuid = tile.id;
|
||||
const filename = `${uuid}.png`;
|
||||
const finalFilePath = path.join(public_folder, filename);
|
||||
await writeFile(finalFilePath, tileData);
|
||||
});
|
||||
const tile = await tileRepository.create('New tile')
|
||||
const uuid = tile.id
|
||||
const filename = `${uuid}.png`
|
||||
const finalFilePath = path.join(public_folder, filename)
|
||||
await writeFile(finalFilePath, tileData)
|
||||
})
|
||||
|
||||
await Promise.all(uploadPromises);
|
||||
await Promise.all(uploadPromises)
|
||||
|
||||
callback(true);
|
||||
callback(true)
|
||||
} catch (error) {
|
||||
console.error('Error uploading tile:', error);
|
||||
callback(false);
|
||||
console.error('Error uploading tile:', error)
|
||||
callback(false)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
@ -1,13 +1,13 @@
|
||||
import { Server } from "socket.io";
|
||||
import {TSocket} from "../../../utilities/Types";
|
||||
import ZoneRepository from "../../../repositories/ZoneRepository";
|
||||
import ZoneManager from "../../../managers/ZoneManager";
|
||||
import {Character, Zone} from "@prisma/client";
|
||||
import { Server } from 'socket.io'
|
||||
import { TSocket } from '../../../utilities/Types'
|
||||
import ZoneRepository from '../../../repositories/ZoneRepository'
|
||||
import ZoneManager from '../../../managers/ZoneManager'
|
||||
import { Character, Zone } from '@prisma/client'
|
||||
|
||||
interface IPayload {
|
||||
name: string;
|
||||
width: number;
|
||||
height: number;
|
||||
name: string
|
||||
width: number
|
||||
height: number
|
||||
}
|
||||
|
||||
/**
|
||||
@ -17,29 +17,28 @@ interface IPayload {
|
||||
*/
|
||||
export default function (socket: TSocket, io: Server) {
|
||||
socket.on('gm:zone_editor:zone:create', async (data: IPayload, callback: (response: Zone[]) => void) => {
|
||||
|
||||
if (socket.character?.role !== 'gm') {
|
||||
console.log(`---Character #${socket.character?.id} is not a game master.`);
|
||||
return;
|
||||
console.log(`---Character #${socket.character?.id} is not a game master.`)
|
||||
return
|
||||
}
|
||||
|
||||
console.log(`---GM ${socket.character?.id} has created a new zone via zone editor.`);
|
||||
let zoneList: Zone[] = [];
|
||||
console.log(`---GM ${socket.character?.id} has created a new zone via zone editor.`)
|
||||
let zoneList: Zone[] = []
|
||||
try {
|
||||
const zone = await ZoneRepository.create(
|
||||
data.name,
|
||||
data.width,
|
||||
data.height,
|
||||
Array.from({length: data.height}, () => Array.from({length: data.width}, () => 'blank_tile')),
|
||||
);
|
||||
Array.from({ length: data.height }, () => Array.from({ length: data.width }, () => 'blank_tile'))
|
||||
)
|
||||
|
||||
zoneList = await ZoneRepository.getAll();
|
||||
callback(zoneList);
|
||||
zoneList = await ZoneRepository.getAll()
|
||||
callback(zoneList)
|
||||
// send over zone and characters to socket
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
socket.emit('notification', {message: 'Failed to create zone.'});
|
||||
callback(zoneList);
|
||||
console.error(e)
|
||||
socket.emit('notification', { message: 'Failed to create zone.' })
|
||||
callback(zoneList)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
@ -1,11 +1,11 @@
|
||||
import { Server } from "socket.io";
|
||||
import {TSocket} from "../../../utilities/Types";
|
||||
import ZoneRepository from "../../../repositories/ZoneRepository";
|
||||
import ZoneManager from "../../../managers/ZoneManager";
|
||||
import {Character, Zone} from "@prisma/client";
|
||||
import { Server } from 'socket.io'
|
||||
import { TSocket } from '../../../utilities/Types'
|
||||
import ZoneRepository from '../../../repositories/ZoneRepository'
|
||||
import ZoneManager from '../../../managers/ZoneManager'
|
||||
import { Character, Zone } from '@prisma/client'
|
||||
|
||||
interface IPayload {
|
||||
zoneId: number;
|
||||
zoneId: number
|
||||
}
|
||||
|
||||
/**
|
||||
@ -15,28 +15,27 @@ interface IPayload {
|
||||
*/
|
||||
export default function (socket: TSocket, io: Server) {
|
||||
socket.on('gm:zone_editor:zone:delete', async (data: IPayload, callback: (response: boolean) => void) => {
|
||||
|
||||
if (socket.character?.role !== 'gm') {
|
||||
console.log(`---Character #${socket.character?.id} is not a game master.`);
|
||||
return;
|
||||
console.log(`---Character #${socket.character?.id} is not a game master.`)
|
||||
return
|
||||
}
|
||||
|
||||
console.log(`---GM ${socket.character?.id} has deleted a zone via zone editor.`);
|
||||
console.log(`---GM ${socket.character?.id} has deleted a zone via zone editor.`)
|
||||
|
||||
try {
|
||||
const zone = await ZoneRepository.getById(data.zoneId);
|
||||
const zone = await ZoneRepository.getById(data.zoneId)
|
||||
|
||||
if (!zone) {
|
||||
console.log(`---Zone not found.`);
|
||||
return;
|
||||
console.log(`---Zone not found.`)
|
||||
return
|
||||
}
|
||||
|
||||
await ZoneRepository.delete(data.zoneId);
|
||||
await ZoneRepository.delete(data.zoneId)
|
||||
|
||||
callback(true);
|
||||
callback(true)
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
callback(false);
|
||||
console.error(e)
|
||||
callback(false)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import { Server } from "socket.io";
|
||||
import {TSocket} from '../../../utilities/Types'
|
||||
import { Server } from 'socket.io'
|
||||
import { TSocket } from '../../../utilities/Types'
|
||||
import { Zone } from '@prisma/client'
|
||||
import ZoneRepository from '../../../repositories/ZoneRepository'
|
||||
|
||||
@ -12,20 +12,19 @@ interface IPayload {}
|
||||
*/
|
||||
export default function (socket: TSocket, io: Server) {
|
||||
socket.on('gm:zone_editor:zone:list', async (data: IPayload, callback: (response: Zone[]) => void) => {
|
||||
|
||||
if (socket.character?.role !== 'gm') {
|
||||
console.log(`---Character #${socket.character?.id} is not a game master.`);
|
||||
return;
|
||||
console.log(`---Character #${socket.character?.id} is not a game master.`)
|
||||
return
|
||||
}
|
||||
|
||||
console.log(`---GM ${socket.character?.id} has requested zone list via zone editor.`);
|
||||
console.log(`---GM ${socket.character?.id} has requested zone list via zone editor.`)
|
||||
|
||||
try {
|
||||
const zones = await ZoneRepository.getAll();
|
||||
callback(zones);
|
||||
const zones = await ZoneRepository.getAll()
|
||||
callback(zones)
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
callback([]);
|
||||
console.error(e)
|
||||
callback([])
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
import { Server } from "socket.io";
|
||||
import {TSocket} from "../../../utilities/Types";
|
||||
import ZoneRepository from "../../../repositories/ZoneRepository";
|
||||
import {Zone} from "@prisma/client";
|
||||
import { Server } from 'socket.io'
|
||||
import { TSocket } from '../../../utilities/Types'
|
||||
import ZoneRepository from '../../../repositories/ZoneRepository'
|
||||
import { Zone } from '@prisma/client'
|
||||
|
||||
interface IPayload {
|
||||
zoneId: number;
|
||||
zoneId: number
|
||||
}
|
||||
|
||||
/**
|
||||
@ -14,29 +14,28 @@ interface IPayload {
|
||||
*/
|
||||
export default function (socket: TSocket, io: Server) {
|
||||
socket.on('gm:zone_editor:zone:request', async (data: IPayload, callback: (response: Zone) => void) => {
|
||||
|
||||
if (socket.character?.role !== 'gm') {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
console.log(`---GM ${socket.character?.id} has requested zone via zone editor.`);
|
||||
console.log(`---GM ${socket.character?.id} has requested zone via zone editor.`)
|
||||
|
||||
if (!data.zoneId) {
|
||||
console.log(`---Zone id not provided.`);
|
||||
return;
|
||||
console.log(`---Zone id not provided.`)
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const zone = await ZoneRepository.getById(data.zoneId);
|
||||
const zone = await ZoneRepository.getById(data.zoneId)
|
||||
|
||||
if (!zone) {
|
||||
console.log(`---Zone not found.`);
|
||||
return;
|
||||
console.log(`---Zone not found.`)
|
||||
return
|
||||
}
|
||||
|
||||
callback(zone);
|
||||
callback(zone)
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
console.error(e)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
@ -1,17 +1,17 @@
|
||||
import { Server } from "socket.io";
|
||||
import {TSocket} from "../../../utilities/Types";
|
||||
import ZoneRepository from "../../../repositories/ZoneRepository";
|
||||
import ZoneManager from "../../../managers/ZoneManager";
|
||||
import { Server } from 'socket.io'
|
||||
import { TSocket } from '../../../utilities/Types'
|
||||
import ZoneRepository from '../../../repositories/ZoneRepository'
|
||||
import ZoneManager from '../../../managers/ZoneManager'
|
||||
import { Character, Zone, ZoneEventTile, ZoneObject } from '@prisma/client'
|
||||
|
||||
interface IPayload {
|
||||
zoneId: number;
|
||||
name: string;
|
||||
width: number;
|
||||
height: number;
|
||||
tiles: string[][];
|
||||
zoneEventTiles: ZoneEventTile[];
|
||||
zoneObjects: ZoneObject[];
|
||||
zoneId: number
|
||||
name: string
|
||||
width: number
|
||||
height: number
|
||||
tiles: string[][]
|
||||
zoneEventTiles: ZoneEventTile[]
|
||||
zoneObjects: ZoneObject[]
|
||||
}
|
||||
|
||||
/**
|
||||
@ -21,43 +21,34 @@ interface IPayload {
|
||||
*/
|
||||
export default function (socket: TSocket, io: Server) {
|
||||
socket.on('gm:zone_editor:zone:update', async (data: IPayload) => {
|
||||
|
||||
if (socket.character?.role !== 'gm') {
|
||||
console.log(`---Character #${socket.character?.id} is not a game master.`);
|
||||
return;
|
||||
console.log(`---Character #${socket.character?.id} is not a game master.`)
|
||||
return
|
||||
}
|
||||
|
||||
console.log(`---GM ${socket.character?.id} has updated zone via zone editor.`);
|
||||
console.log(`---GM ${socket.character?.id} has updated zone via zone editor.`)
|
||||
|
||||
if (!data.zoneId) {
|
||||
console.log(`---Zone id not provided.`);
|
||||
return;
|
||||
console.log(`---Zone id not provided.`)
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
let zone = await ZoneRepository.getById(data.zoneId);
|
||||
let zone = await ZoneRepository.getById(data.zoneId)
|
||||
|
||||
if (!zone) {
|
||||
console.log(`---Zone not found.`);
|
||||
return;
|
||||
console.log(`---Zone not found.`)
|
||||
return
|
||||
}
|
||||
|
||||
await ZoneRepository.update(
|
||||
data.zoneId,
|
||||
data.name,
|
||||
data.width,
|
||||
data.height,
|
||||
data.tiles,
|
||||
data.zoneEventTiles,
|
||||
data.zoneObjects
|
||||
);
|
||||
await ZoneRepository.update(data.zoneId, data.name, data.width, data.height, data.tiles, data.zoneEventTiles, data.zoneObjects)
|
||||
|
||||
zone = await ZoneRepository.getById(data.zoneId);
|
||||
zone = await ZoneRepository.getById(data.zoneId)
|
||||
|
||||
// send over zone and characters to socket
|
||||
socket.emit('gm:zone_editor:zone:load', zone);
|
||||
socket.emit('gm:zone_editor:zone:load', zone)
|
||||
} catch (error: any) {
|
||||
console.log(`---Error updating zone: ${error.message}`);
|
||||
console.log(`---Error updating zone: ${error.message}`)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
@ -1,98 +1,95 @@
|
||||
import * as readline from 'readline';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { Server } from 'socket.io';
|
||||
import * as readline from 'readline'
|
||||
import * as fs from 'fs'
|
||||
import * as path from 'path'
|
||||
import { Server } from 'socket.io'
|
||||
|
||||
class CommandManager {
|
||||
private commands: Map<string, Function> = new Map();
|
||||
private rl: readline.Interface;
|
||||
private io: Server | null = null;
|
||||
private rlClosed: boolean = false;
|
||||
private commands: Map<string, Function> = new Map()
|
||||
private rl: readline.Interface
|
||||
private io: Server | null = null
|
||||
private rlClosed: boolean = false
|
||||
|
||||
constructor() {
|
||||
this.rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout
|
||||
});
|
||||
})
|
||||
|
||||
this.rl.on('close', () => {
|
||||
this.rlClosed = true;
|
||||
});
|
||||
this.rlClosed = true
|
||||
})
|
||||
}
|
||||
|
||||
public async boot(io: Server) {
|
||||
this.io = io;
|
||||
await this.loadCommands();
|
||||
console.log('[✅] Command manager loaded');
|
||||
this.startPrompt();
|
||||
this.io = io
|
||||
await this.loadCommands()
|
||||
console.log('[✅] Command manager loaded')
|
||||
this.startPrompt()
|
||||
}
|
||||
|
||||
private startPrompt() {
|
||||
if (this.rlClosed) return;
|
||||
if (this.rlClosed) return
|
||||
|
||||
this.rl.question('> ', (command: string) => {
|
||||
this.processCommand(command);
|
||||
this.startPrompt();
|
||||
});
|
||||
this.processCommand(command)
|
||||
this.startPrompt()
|
||||
})
|
||||
}
|
||||
|
||||
private async processCommand(command: string): Promise<void> {
|
||||
const [cmd, ...args] = command.trim().split(' ');
|
||||
const [cmd, ...args] = command.trim().split(' ')
|
||||
if (this.commands.has(cmd)) {
|
||||
this.commands.get(cmd)?.(args, this.io as Server);
|
||||
this.commands.get(cmd)?.(args, this.io as Server)
|
||||
} else {
|
||||
this.handleUnknownCommand(cmd);
|
||||
this.handleUnknownCommand(cmd)
|
||||
}
|
||||
}
|
||||
|
||||
private handleUnknownCommand(command: string) {
|
||||
switch (command) {
|
||||
case 'exit':
|
||||
console.log('Goodbye!');
|
||||
this.rl.close();
|
||||
break;
|
||||
console.log('Goodbye!')
|
||||
this.rl.close()
|
||||
break
|
||||
default:
|
||||
console.error(`Unknown command: ${command}`);
|
||||
break;
|
||||
console.error(`Unknown command: ${command}`)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
private async loadCommands() {
|
||||
const commandsDir = path.resolve(__dirname, 'commands');
|
||||
const commandsDir = path.resolve(__dirname, 'commands')
|
||||
try {
|
||||
const files: string[] = await fs.promises.readdir(commandsDir);
|
||||
const files: string[] = await fs.promises.readdir(commandsDir)
|
||||
|
||||
for (const file of files) {
|
||||
await this.loadCommand(commandsDir, file);
|
||||
await this.loadCommand(commandsDir, file)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[❌] Failed to read commands directory:', error);
|
||||
console.error('[❌] Failed to read commands directory:', error)
|
||||
}
|
||||
}
|
||||
|
||||
private async loadCommand(commandsDir: string, file: string) {
|
||||
try {
|
||||
const ext = path.extname(file);
|
||||
const commandName = path.basename(file, ext);
|
||||
const commandPath = path.join(commandsDir, file);
|
||||
const module = await import(commandPath);
|
||||
const ext = path.extname(file)
|
||||
const commandName = path.basename(file, ext)
|
||||
const commandPath = path.join(commandsDir, file)
|
||||
const module = await import(commandPath)
|
||||
|
||||
this.registerCommand(commandName, module.default);
|
||||
this.registerCommand(commandName, module.default)
|
||||
} catch (error) {
|
||||
console.error('[❌] Failed to load command:', file, error);
|
||||
console.error('[❌] Failed to load command:', file, error)
|
||||
}
|
||||
}
|
||||
|
||||
private registerCommand(
|
||||
name: string,
|
||||
command: (args: string[], io: Server) => void
|
||||
) {
|
||||
private registerCommand(name: string, command: (args: string[], io: Server) => void) {
|
||||
if (this.commands.has(name)) {
|
||||
console.warn(`Command '${name}' is already registered. Overwriting...`);
|
||||
console.warn(`Command '${name}' is already registered. Overwriting...`)
|
||||
}
|
||||
this.commands.set(name, command);
|
||||
console.log(`Registered command: ${name}`);
|
||||
this.commands.set(name, command)
|
||||
console.log(`Registered command: ${name}`)
|
||||
}
|
||||
}
|
||||
|
||||
export default new CommandManager();
|
||||
export default new CommandManager()
|
||||
|
@ -1,37 +1,37 @@
|
||||
import {User} from "@prisma/client";
|
||||
import { User } from '@prisma/client'
|
||||
|
||||
type TLoggedInUsers = {
|
||||
users: User[];
|
||||
users: User[]
|
||||
}
|
||||
|
||||
class UserManager {
|
||||
private loggedInUsers: TLoggedInUsers[] = [];
|
||||
private loggedInUsers: TLoggedInUsers[] = []
|
||||
|
||||
// Method to initialize user manager
|
||||
public async boot() {
|
||||
console.log('[✅] User manager loaded');
|
||||
console.log('[✅] User manager loaded')
|
||||
}
|
||||
|
||||
// Function that adds user to logged in users
|
||||
public loginUser(user: User) {
|
||||
this.loggedInUsers.push({
|
||||
users: [user]
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
// Function that checks if a user is already logged in
|
||||
public findUser(user: User) {
|
||||
return this.loggedInUsers.find((loggedInUser) => {
|
||||
return loggedInUser.users.includes(user);
|
||||
});
|
||||
return loggedInUser.users.includes(user)
|
||||
})
|
||||
}
|
||||
|
||||
// Function that lists all logged in users
|
||||
public listUsers() {
|
||||
return this.loggedInUsers.map((loggedInUser) => {
|
||||
return loggedInUser.users;
|
||||
});
|
||||
return loggedInUser.users
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default new UserManager();
|
||||
export default new UserManager()
|
||||
|
@ -1,29 +1,29 @@
|
||||
import {Character, Zone} from "@prisma/client";
|
||||
import ZoneRepository from "../repositories/ZoneRepository";
|
||||
import ZoneService from "../services/ZoneService";
|
||||
import { Character, Zone } from '@prisma/client'
|
||||
import ZoneRepository from '../repositories/ZoneRepository'
|
||||
import ZoneService from '../services/ZoneService'
|
||||
|
||||
type TLoadedZone = {
|
||||
zone: Zone;
|
||||
characters: Character[];
|
||||
zone: Zone
|
||||
characters: Character[]
|
||||
}
|
||||
|
||||
class ZoneManager {
|
||||
private loadedZones: TLoadedZone[] = [];
|
||||
private loadedZones: TLoadedZone[] = []
|
||||
|
||||
// Method to initialize zone manager
|
||||
public async boot() {
|
||||
if (!await ZoneRepository.getById(1)) {
|
||||
const zoneService = new ZoneService();
|
||||
await zoneService.createDemoZone();
|
||||
if (!(await ZoneRepository.getById(1))) {
|
||||
const zoneService = new ZoneService()
|
||||
await zoneService.createDemoZone()
|
||||
}
|
||||
|
||||
const zones = await ZoneRepository.getAll();
|
||||
const zones = await ZoneRepository.getAll()
|
||||
|
||||
for (const zone of zones) {
|
||||
this.loadZone(zone);
|
||||
this.loadZone(zone)
|
||||
}
|
||||
|
||||
console.log('[✅] Zone manager loaded');
|
||||
console.log('[✅] Zone manager loaded')
|
||||
}
|
||||
|
||||
// Method to handle individual zone loading
|
||||
@ -31,63 +31,63 @@ class ZoneManager {
|
||||
this.loadedZones.push({
|
||||
zone,
|
||||
characters: []
|
||||
});
|
||||
console.log(`[✅] Zone ID ${zone.id} loaded`);
|
||||
})
|
||||
console.log(`[✅] Zone ID ${zone.id} loaded`)
|
||||
}
|
||||
|
||||
// Method to handle individual zone unloading
|
||||
public unloadZone(zoneId: number) {
|
||||
this.loadedZones = this.loadedZones.filter((loadedZone) => {
|
||||
return loadedZone.zone.id !== zoneId;
|
||||
});
|
||||
console.log(`[❌] Zone ID ${zoneId} unloaded`);
|
||||
return loadedZone.zone.id !== zoneId
|
||||
})
|
||||
console.log(`[❌] Zone ID ${zoneId} unloaded`)
|
||||
}
|
||||
|
||||
// Getter for loaded zones
|
||||
public getLoadedZones(): TLoadedZone[] {
|
||||
return this.loadedZones;
|
||||
return this.loadedZones
|
||||
}
|
||||
|
||||
public addCharacterToZone(zoneId: number, character: Character) {
|
||||
const loadedZone = this.loadedZones.find((loadedZone) => {
|
||||
return loadedZone.zone.id === zoneId;
|
||||
});
|
||||
return loadedZone.zone.id === zoneId
|
||||
})
|
||||
if (loadedZone) {
|
||||
loadedZone.characters.push(character);
|
||||
loadedZone.characters.push(character)
|
||||
}
|
||||
}
|
||||
|
||||
public removeCharacterFromZone(zoneId: number, character: Character) {
|
||||
const loadedZone = this.loadedZones.find((loadedZone) => {
|
||||
return loadedZone.zone.id === zoneId;
|
||||
});
|
||||
return loadedZone.zone.id === zoneId
|
||||
})
|
||||
if (loadedZone) {
|
||||
loadedZone.characters = loadedZone.characters.filter((loadedCharacter) => {
|
||||
return loadedCharacter.id !== character.id;
|
||||
});
|
||||
return loadedCharacter.id !== character.id
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
public updateCharacterInZone(zoneId: number, character: Character) {
|
||||
const loadedZone = this.loadedZones.find((loadedZone) => {
|
||||
return loadedZone.zone.id === zoneId;
|
||||
});
|
||||
return loadedZone.zone.id === zoneId
|
||||
})
|
||||
if (loadedZone) {
|
||||
const characterIndex = loadedZone.characters.findIndex((loadedCharacter) => {
|
||||
return loadedCharacter.id === character.id;
|
||||
});
|
||||
return loadedCharacter.id === character.id
|
||||
})
|
||||
if (characterIndex !== -1) {
|
||||
loadedZone.characters[characterIndex] = character;
|
||||
loadedZone.characters[characterIndex] = character
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public getCharactersInZone(zoneId: number): Character[] {
|
||||
const loadedZone = this.loadedZones.find((loadedZone) => {
|
||||
return loadedZone.zone.id === zoneId;
|
||||
});
|
||||
return loadedZone ? loadedZone.characters : [];
|
||||
return loadedZone.zone.id === zoneId
|
||||
})
|
||||
return loadedZone ? loadedZone.characters : []
|
||||
}
|
||||
}
|
||||
|
||||
export default new ZoneManager;
|
||||
export default new ZoneManager()
|
||||
|
@ -1,37 +1,36 @@
|
||||
// socket io jwt auth middleware
|
||||
import { verify } from 'jsonwebtoken';
|
||||
import { TSocket } from '../utilities/Types';
|
||||
import config from "../utilities/Config";
|
||||
import UserRepository from "../repositories/UserRepository";
|
||||
import {User} from "@prisma/client";
|
||||
import { verify } from 'jsonwebtoken'
|
||||
import { TSocket } from '../utilities/Types'
|
||||
import config from '../utilities/Config'
|
||||
import UserRepository from '../repositories/UserRepository'
|
||||
import { User } from '@prisma/client'
|
||||
|
||||
export async function Authentication (socket: TSocket, next: any)
|
||||
{
|
||||
export async function Authentication(socket: TSocket, next: any) {
|
||||
if (!socket.request.headers.cookie) {
|
||||
console.log('No cookie provided');
|
||||
return next(new Error('Authentication error'));
|
||||
console.log('No cookie provided')
|
||||
return next(new Error('Authentication error'))
|
||||
}
|
||||
|
||||
const cookies = socket.request.headers.cookie.split('; ').reduce((prev: any, current: any) => {
|
||||
const [name, value] = current.split('=');
|
||||
prev[name] = value;
|
||||
return prev;
|
||||
}, {});
|
||||
const [name, value] = current.split('=')
|
||||
prev[name] = value
|
||||
return prev
|
||||
}, {})
|
||||
|
||||
const token = cookies['token'];
|
||||
const token = cookies['token']
|
||||
|
||||
if (token) {
|
||||
verify(token, config.JWT_SECRET, async (err: any, decoded: any) => {
|
||||
if (err) {
|
||||
console.log('err');
|
||||
return next(new Error('Authentication error'));
|
||||
console.log('err')
|
||||
return next(new Error('Authentication error'))
|
||||
}
|
||||
|
||||
socket.user = await UserRepository.getById(decoded.id) as User;
|
||||
next();
|
||||
});
|
||||
socket.user = (await UserRepository.getById(decoded.id)) as User
|
||||
next()
|
||||
})
|
||||
} else {
|
||||
console.log('No token provided');
|
||||
next(new Error('Authentication error'));
|
||||
console.log('No token provided')
|
||||
next(new Error('Authentication error'))
|
||||
}
|
||||
}
|
@ -1,17 +1,17 @@
|
||||
import prisma from '../utilities/Prisma'; // Import the global Prisma instance
|
||||
import {Character} from '@prisma/client';
|
||||
import prisma from '../utilities/Prisma' // Import the global Prisma instance
|
||||
import { Character } from '@prisma/client'
|
||||
|
||||
class CharacterRepository {
|
||||
async getByUserId(userId: number): Promise<Character[] | null> {
|
||||
try {
|
||||
return await prisma.character.findMany({
|
||||
where: {
|
||||
userId,
|
||||
},
|
||||
});
|
||||
userId
|
||||
}
|
||||
})
|
||||
} catch (error: any) {
|
||||
// Handle error
|
||||
throw new Error(`Failed to get character by user ID: ${error.message}`);
|
||||
throw new Error(`Failed to get character by user ID: ${error.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,15 +20,15 @@ class CharacterRepository {
|
||||
return await prisma.character.findFirst({
|
||||
where: {
|
||||
userId,
|
||||
id: characterId,
|
||||
id: characterId
|
||||
},
|
||||
include: {
|
||||
zone: true
|
||||
}
|
||||
});
|
||||
})
|
||||
} catch (error: any) {
|
||||
// Handle error
|
||||
throw new Error(`Failed to get character by user ID and character ID: ${error.message}`);
|
||||
throw new Error(`Failed to get character by user ID and character ID: ${error.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,12 +36,12 @@ class CharacterRepository {
|
||||
try {
|
||||
return await prisma.character.findUnique({
|
||||
where: {
|
||||
id,
|
||||
},
|
||||
});
|
||||
id
|
||||
}
|
||||
})
|
||||
} catch (error: any) {
|
||||
// Handle error
|
||||
throw new Error(`Failed to get character by ID: ${error.message}`);
|
||||
throw new Error(`Failed to get character by ID: ${error.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
@ -55,29 +55,29 @@ class CharacterRepository {
|
||||
position_x: 0, // @TODO Set default registration values in the database
|
||||
position_y: 0, // @TODO Set default registration values in the database
|
||||
rotation: 0, // @TODO Set default registration values in the database
|
||||
zoneId: 1, // @TODO Set default registration values in the database
|
||||
},
|
||||
});
|
||||
zoneId: 1 // @TODO Set default registration values in the database
|
||||
}
|
||||
})
|
||||
} catch (error: any) {
|
||||
// Handle error
|
||||
throw new Error(`Failed to create character: ${error.message}`);
|
||||
throw new Error(`Failed to create character: ${error.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
async updatePosition(id:number, position_x: number, position_y: number): Promise<Character | null> {
|
||||
async updatePosition(id: number, position_x: number, position_y: number): Promise<Character | null> {
|
||||
try {
|
||||
return await prisma.character.update({
|
||||
where: {
|
||||
id: id,
|
||||
id: id
|
||||
},
|
||||
data: {
|
||||
position_x,
|
||||
position_y,
|
||||
},
|
||||
});
|
||||
position_y
|
||||
}
|
||||
})
|
||||
} catch (error: any) {
|
||||
// Handle error
|
||||
throw new Error(`Failed to update character: ${error.message}`);
|
||||
throw new Error(`Failed to update character: ${error.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
@ -85,12 +85,12 @@ class CharacterRepository {
|
||||
try {
|
||||
return await prisma.character.delete({
|
||||
where: {
|
||||
id,
|
||||
},
|
||||
});
|
||||
id
|
||||
}
|
||||
})
|
||||
} catch (error: any) {
|
||||
// Handle error
|
||||
throw new Error(`Failed to delete character: ${error.message}`);
|
||||
throw new Error(`Failed to delete character: ${error.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
@ -99,12 +99,12 @@ class CharacterRepository {
|
||||
return await prisma.character.delete({
|
||||
where: {
|
||||
userId,
|
||||
id: characterId,
|
||||
},
|
||||
});
|
||||
id: characterId
|
||||
}
|
||||
})
|
||||
} catch (error: any) {
|
||||
// Handle error
|
||||
throw new Error(`Failed to delete character by user ID and character ID: ${error.message}`);
|
||||
throw new Error(`Failed to delete character by user ID and character ID: ${error.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
@ -112,14 +112,14 @@ class CharacterRepository {
|
||||
try {
|
||||
return await prisma.character.findFirst({
|
||||
where: {
|
||||
name,
|
||||
},
|
||||
});
|
||||
name
|
||||
}
|
||||
})
|
||||
} catch (error: any) {
|
||||
// Handle error
|
||||
throw new Error(`Failed to get character by name: ${error.message}`);
|
||||
throw new Error(`Failed to get character by name: ${error.message}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default new CharacterRepository;
|
||||
export default new CharacterRepository()
|
||||
|
@ -1,44 +1,16 @@
|
||||
import prisma from '../utilities/Prisma'; // Import the global Prisma instance
|
||||
import prisma from '../utilities/Prisma' // Import the global Prisma instance
|
||||
import { Object } from '@prisma/client'
|
||||
|
||||
class ObjectRepository {
|
||||
async getById(id: string): Promise<Object | null> {
|
||||
return prisma.object.findUnique({
|
||||
where: { id },
|
||||
});
|
||||
where: { id }
|
||||
})
|
||||
}
|
||||
|
||||
async getAll(): Promise<Object[]> {
|
||||
return prisma.object.findMany();
|
||||
}
|
||||
|
||||
async create(name: string, origin_x: number, origin_y: number): Promise<Object> {
|
||||
return prisma.object.create({
|
||||
data: {
|
||||
name,
|
||||
origin_x,
|
||||
origin_y
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async update(id: string, name: string, tags: string[], origin_x: number, origin_y: number): Promise<Object> {
|
||||
return prisma.object.update({
|
||||
where: { id },
|
||||
data: {
|
||||
name,
|
||||
tags,
|
||||
origin_x,
|
||||
origin_y
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async delete(id: string): Promise<Object> {
|
||||
return prisma.object.delete({
|
||||
where: { id },
|
||||
});
|
||||
return prisma.object.findMany()
|
||||
}
|
||||
}
|
||||
|
||||
export default new ObjectRepository();
|
||||
export default new ObjectRepository()
|
||||
|
@ -1,15 +1,15 @@
|
||||
import prisma from '../utilities/Prisma'; // Import the global Prisma instance
|
||||
import prisma from '../utilities/Prisma' // Import the global Prisma instance
|
||||
import { Sprite } from '@prisma/client'
|
||||
|
||||
class SpriteRepository {
|
||||
async getById(id: string): Promise<Sprite | null> {
|
||||
return prisma.sprite.findUnique({
|
||||
where: { id },
|
||||
});
|
||||
where: { id }
|
||||
})
|
||||
}
|
||||
|
||||
async getAll(): Promise<Sprite[]> {
|
||||
return prisma.sprite.findMany();
|
||||
return prisma.sprite.findMany()
|
||||
}
|
||||
|
||||
async create(name: string, origin_x: number, origin_y: number): Promise<Sprite> {
|
||||
@ -18,8 +18,8 @@ class SpriteRepository {
|
||||
name,
|
||||
origin_x,
|
||||
origin_y
|
||||
},
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async update(id: string, name: string, origin_x: number, origin_y: number): Promise<Sprite> {
|
||||
@ -29,15 +29,15 @@ class SpriteRepository {
|
||||
name,
|
||||
origin_x,
|
||||
origin_y
|
||||
},
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async delete(id: string): Promise<Sprite> {
|
||||
return prisma.sprite.delete({
|
||||
where: { id },
|
||||
});
|
||||
where: { id }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default new SpriteRepository();
|
||||
export default new SpriteRepository()
|
||||
|
@ -1,15 +1,15 @@
|
||||
import prisma from '../utilities/Prisma'; // Import the global Prisma instance
|
||||
import prisma from '../utilities/Prisma' // Import the global Prisma instance
|
||||
import { Tile } from '@prisma/client'
|
||||
|
||||
class TileRepository {
|
||||
async getById(id: string): Promise<Tile | null> {
|
||||
return prisma.tile.findUnique({
|
||||
where: { id },
|
||||
});
|
||||
where: { id }
|
||||
})
|
||||
}
|
||||
|
||||
async getAll(): Promise<Tile[]> {
|
||||
return prisma.tile.findMany();
|
||||
return prisma.tile.findMany()
|
||||
}
|
||||
|
||||
async create(name: string): Promise<Tile> {
|
||||
@ -17,8 +17,8 @@ class TileRepository {
|
||||
data: {
|
||||
name,
|
||||
tags: []
|
||||
},
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async update(id: string, name: string, tags: string[]): Promise<Tile> {
|
||||
@ -27,21 +27,21 @@ class TileRepository {
|
||||
data: {
|
||||
name,
|
||||
tags
|
||||
},
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async delete(id: string): Promise<boolean> {
|
||||
try {
|
||||
await prisma.tile.delete({
|
||||
where: { id },
|
||||
});
|
||||
return true;
|
||||
where: { id }
|
||||
})
|
||||
return true
|
||||
} catch (error) {
|
||||
console.log('Error deleting tile:', error)
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default new TileRepository();
|
||||
export default new TileRepository()
|
||||
|
@ -1,29 +1,29 @@
|
||||
import prisma from '../utilities/Prisma'; // Import the global Prisma instance
|
||||
import { User } from '@prisma/client';
|
||||
import prisma from '../utilities/Prisma' // Import the global Prisma instance
|
||||
import { User } from '@prisma/client'
|
||||
|
||||
class UserRepository {
|
||||
async getById(id: number): Promise<User | null> {
|
||||
try {
|
||||
return await prisma.user.findUnique({
|
||||
where: {
|
||||
id,
|
||||
},
|
||||
});
|
||||
id
|
||||
}
|
||||
})
|
||||
} catch (error: any) {
|
||||
// Handle error
|
||||
throw new Error(`Failed to get user by ID: ${error.message}`);
|
||||
throw new Error(`Failed to get user by ID: ${error.message}`)
|
||||
}
|
||||
}
|
||||
async getByUsername(username: string): Promise<User | null> {
|
||||
try {
|
||||
return await prisma.user.findUnique({
|
||||
where: {
|
||||
username,
|
||||
},
|
||||
});
|
||||
username
|
||||
}
|
||||
})
|
||||
} catch (error: any) {
|
||||
// Handle error
|
||||
throw new Error(`Failed to get user by username: ${error.message}`);
|
||||
throw new Error(`Failed to get user by username: ${error.message}`)
|
||||
}
|
||||
}
|
||||
async create(username: string, password: string): Promise<User> {
|
||||
@ -31,14 +31,14 @@ class UserRepository {
|
||||
return await prisma.user.create({
|
||||
data: {
|
||||
username,
|
||||
password,
|
||||
},
|
||||
});
|
||||
password
|
||||
}
|
||||
})
|
||||
} catch (error: any) {
|
||||
// Handle error
|
||||
throw new Error(`Failed to create user: ${error.message}`);
|
||||
throw new Error(`Failed to create user: ${error.message}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default new UserRepository;
|
||||
export default new UserRepository()
|
||||
|
@ -1,22 +1,22 @@
|
||||
import { Zone, ZoneEventTile, ZoneObject } from '@prisma/client'
|
||||
import prisma from '../utilities/Prisma'; // Import the global Prisma instance
|
||||
import prisma from '../utilities/Prisma' // Import the global Prisma instance
|
||||
|
||||
class ZoneRepository {
|
||||
async getFirst(): Promise<Zone | null> {
|
||||
try {
|
||||
return await prisma.zone.findFirst();
|
||||
return await prisma.zone.findFirst()
|
||||
} catch (error: any) {
|
||||
// Handle error
|
||||
throw new Error(`Failed to get first zone: ${error.message}`);
|
||||
throw new Error(`Failed to get first zone: ${error.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
async getAll(): Promise<Zone[]> {
|
||||
try {
|
||||
return await prisma.zone.findMany();
|
||||
return await prisma.zone.findMany()
|
||||
} catch (error: any) {
|
||||
// Handle error
|
||||
throw new Error(`Failed to get all zone: ${error.message}`);
|
||||
throw new Error(`Failed to get all zone: ${error.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,10 +38,10 @@ class ZoneRepository {
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
} catch (error: any) {
|
||||
// Handle error
|
||||
throw new Error(`Failed to get zone by id: ${error.message}`);
|
||||
throw new Error(`Failed to get zone by id: ${error.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,10 +54,10 @@ class ZoneRepository {
|
||||
height: height,
|
||||
tiles: tiles
|
||||
}
|
||||
});
|
||||
})
|
||||
} catch (error: any) {
|
||||
// Handle error
|
||||
throw new Error(`Failed to create zone: ${error.message}`);
|
||||
throw new Error(`Failed to create zone: ${error.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,7 +77,7 @@ class ZoneRepository {
|
||||
zoneId: id // Ensure only event tiles related to the zone are deleted
|
||||
},
|
||||
// Save new zone event tiles
|
||||
create: zoneEventTiles.map(zoneEventTile => ({
|
||||
create: zoneEventTiles.map((zoneEventTile) => ({
|
||||
type: zoneEventTile.type,
|
||||
position_x: zoneEventTile.position_x,
|
||||
position_y: zoneEventTile.position_y
|
||||
@ -88,7 +88,7 @@ class ZoneRepository {
|
||||
zoneId: id // Ensure only objects related to the zone are deleted
|
||||
},
|
||||
// Save new zone objects
|
||||
create: zoneObjects.map(zoneObject => ({
|
||||
create: zoneObjects.map((zoneObject) => ({
|
||||
objectId: zoneObject.objectId,
|
||||
depth: zoneObject.depth,
|
||||
position_x: zoneObject.position_x,
|
||||
@ -96,10 +96,10 @@ class ZoneRepository {
|
||||
}))
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
} catch (error: any) {
|
||||
// Handle error
|
||||
throw new Error(`Failed to update zone: ${error.message}`);
|
||||
throw new Error(`Failed to update zone: ${error.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
@ -109,12 +109,12 @@ class ZoneRepository {
|
||||
where: {
|
||||
id: id
|
||||
}
|
||||
});
|
||||
})
|
||||
} catch (error: any) {
|
||||
// Handle error
|
||||
throw new Error(`Failed to delete zone: ${error.message}`);
|
||||
throw new Error(`Failed to delete zone: ${error.message}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default new ZoneRepository;
|
||||
export default new ZoneRepository()
|
||||
|
@ -1,35 +1,34 @@
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import express, {Application} from 'express';
|
||||
import {createServer as httpServer} from 'http';
|
||||
import {addHttpRoutes} from './utilities/Http';
|
||||
import cors from 'cors';
|
||||
import {Server as SocketServer} from 'socket.io';
|
||||
import {TSocket} from "./utilities/Types";
|
||||
import config from './utilities/Config';
|
||||
import prisma from './utilities/Prisma';
|
||||
import ZoneManager from "./managers/ZoneManager";
|
||||
import UserManager from "./managers/UserManager";
|
||||
import {Authentication} from "./middleware/Authentication";
|
||||
import CommandManager from "./managers/CommandManager";
|
||||
import {Dirent} from "node:fs";
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
import express, { Application } from 'express'
|
||||
import { createServer as httpServer } from 'http'
|
||||
import { addHttpRoutes } from './utilities/Http'
|
||||
import cors from 'cors'
|
||||
import { Server as SocketServer } from 'socket.io'
|
||||
import { TSocket } from './utilities/Types'
|
||||
import config from './utilities/Config'
|
||||
import prisma from './utilities/Prisma'
|
||||
import ZoneManager from './managers/ZoneManager'
|
||||
import UserManager from './managers/UserManager'
|
||||
import { Authentication } from './middleware/Authentication'
|
||||
import CommandManager from './managers/CommandManager'
|
||||
import { Dirent } from 'node:fs'
|
||||
|
||||
export class Server
|
||||
{
|
||||
private readonly app: Application;
|
||||
private readonly http: any;
|
||||
private readonly io: SocketServer;
|
||||
export class Server {
|
||||
private readonly app: Application
|
||||
private readonly http: any
|
||||
private readonly io: SocketServer
|
||||
|
||||
/**
|
||||
* Creates an instance of GameServer.
|
||||
*/
|
||||
constructor() {
|
||||
this.app = express();
|
||||
this.app.use(cors());
|
||||
this.app.use(express.json());
|
||||
this.app.use(express.urlencoded({ extended: true }));
|
||||
this.app = express()
|
||||
this.app.use(cors())
|
||||
this.app.use(express.json())
|
||||
this.app.use(express.urlencoded({ extended: true }))
|
||||
this.http = httpServer(this.app)
|
||||
this.io = new SocketServer(this.http);
|
||||
this.io = new SocketServer(this.http)
|
||||
this.io.use(Authentication)
|
||||
}
|
||||
|
||||
@ -39,34 +38,34 @@ export class Server
|
||||
public async start() {
|
||||
// Check prisma connection
|
||||
try {
|
||||
await prisma.$connect();
|
||||
console.log('[✅] Database connected');
|
||||
await prisma.$connect()
|
||||
console.log('[✅] Database connected')
|
||||
} catch (error: any) {
|
||||
throw new Error(`[❌] Database connection failed: ${error.message}`);
|
||||
throw new Error(`[❌] Database connection failed: ${error.message}`)
|
||||
}
|
||||
|
||||
// Start the server
|
||||
try {
|
||||
await this.http.listen(config.PORT, config.HOST);
|
||||
console.log('[✅] Socket.IO running on port', config.PORT);
|
||||
await this.http.listen(config.PORT, config.HOST)
|
||||
console.log('[✅] Socket.IO running on port', config.PORT)
|
||||
} catch (error: any) {
|
||||
throw new Error(`[❌] Socket.IO failed to start: ${error.message}`);
|
||||
throw new Error(`[❌] Socket.IO failed to start: ${error.message}`)
|
||||
}
|
||||
|
||||
// Add http API routes
|
||||
await addHttpRoutes(this.app);
|
||||
await addHttpRoutes(this.app)
|
||||
|
||||
// Load user manager
|
||||
await UserManager.boot();
|
||||
await UserManager.boot()
|
||||
|
||||
// Load zone manager
|
||||
await ZoneManager.boot();
|
||||
await ZoneManager.boot()
|
||||
|
||||
// Load command manager - Disabled for now
|
||||
// await CommandManager.boot(this.io);
|
||||
|
||||
// Listen for socket connections
|
||||
this.io.on('connection', this.handleConnection.bind(this));
|
||||
this.io.on('connection', this.handleConnection.bind(this))
|
||||
}
|
||||
|
||||
/**
|
||||
@ -75,30 +74,30 @@ export class Server
|
||||
* @private
|
||||
*/
|
||||
private async handleConnection(socket: TSocket) {
|
||||
const eventsPath = path.join(__dirname, 'events');
|
||||
const eventsPath = path.join(__dirname, 'events')
|
||||
try {
|
||||
await this.loadEventHandlers(eventsPath, socket);
|
||||
await this.loadEventHandlers(eventsPath, socket)
|
||||
} catch (error: any) {
|
||||
throw new Error('[❌] Failed to load event handlers: ' + error.message);
|
||||
throw new Error('[❌] Failed to load event handlers: ' + error.message)
|
||||
}
|
||||
}
|
||||
|
||||
private async loadEventHandlers(dir: string, socket: TSocket) {
|
||||
const files: Dirent[] = await fs.promises.readdir(dir, { withFileTypes: true });
|
||||
const files: Dirent[] = await fs.promises.readdir(dir, { withFileTypes: true })
|
||||
|
||||
for (const file of files) {
|
||||
const fullPath = path.join(dir, file.name);
|
||||
const fullPath = path.join(dir, file.name)
|
||||
|
||||
if (file.isDirectory()) {
|
||||
await this.loadEventHandlers(fullPath, socket);
|
||||
await this.loadEventHandlers(fullPath, socket)
|
||||
} else if (file.isFile()) {
|
||||
const module = await import(fullPath);
|
||||
module.default(socket, this.io);
|
||||
const module = await import(fullPath)
|
||||
module.default(socket, this.io)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Start the server
|
||||
const server = new Server();
|
||||
server.start();
|
||||
const server = new Server()
|
||||
server.start()
|
||||
|
@ -1,6 +1,3 @@
|
||||
class AssetService {}
|
||||
|
||||
class AssetService
|
||||
{
|
||||
}
|
||||
|
||||
export default AssetService;
|
||||
export default AssetService
|
||||
|
@ -1,8 +1,5 @@
|
||||
import {Character} from "@prisma/client";
|
||||
import { Character } from '@prisma/client'
|
||||
|
||||
class CharacterService
|
||||
{
|
||||
class CharacterService {}
|
||||
|
||||
}
|
||||
|
||||
export default CharacterService;
|
||||
export default CharacterService
|
||||
|
@ -1,31 +1,30 @@
|
||||
import bcrypt from 'bcryptjs'
|
||||
import UserRepository from '../repositories/UserRepository'
|
||||
|
||||
class UserService
|
||||
{
|
||||
class UserService {
|
||||
async login(username: string, password: string): Promise<boolean | any> {
|
||||
const user = await UserRepository.getByUsername(username);
|
||||
const user = await UserRepository.getByUsername(username)
|
||||
if (!user) {
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
|
||||
const passwordMatch = await bcrypt.compare(password, user.password);
|
||||
const passwordMatch = await bcrypt.compare(password, user.password)
|
||||
if (!passwordMatch) {
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
|
||||
return user;
|
||||
return user
|
||||
}
|
||||
|
||||
async register(username: string, password: string): Promise<boolean | any> {
|
||||
const user = await UserRepository.getByUsername(username);
|
||||
const user = await UserRepository.getByUsername(username)
|
||||
if (user) {
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
|
||||
const hashedPassword = await bcrypt.hash(password, 10);
|
||||
const hashedPassword = await bcrypt.hash(password, 10)
|
||||
return await UserRepository.create(username, hashedPassword)
|
||||
}
|
||||
}
|
||||
|
||||
export default UserService;
|
||||
export default UserService
|
||||
|
@ -1,12 +1,9 @@
|
||||
import {Zone} from "@prisma/client";
|
||||
import ZoneRepository from "../repositories/ZoneRepository";
|
||||
import { Zone } from '@prisma/client'
|
||||
import ZoneRepository from '../repositories/ZoneRepository'
|
||||
|
||||
class ZoneService
|
||||
{
|
||||
async createDemoZone(): Promise<boolean>
|
||||
{
|
||||
await ZoneRepository.create("Demo Zone", 10, 10, [
|
||||
['blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile'],
|
||||
class ZoneService {
|
||||
async createDemoZone(): Promise<boolean> {
|
||||
await ZoneRepository.create('Demo Zone', 10, 10, [
|
||||
['blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile'],
|
||||
['blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile'],
|
||||
['blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile'],
|
||||
@ -16,10 +13,11 @@ class ZoneService
|
||||
['blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile'],
|
||||
['blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile'],
|
||||
['blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile'],
|
||||
['blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile', 'blank_tile']
|
||||
])
|
||||
console.log("Demo zone created.");
|
||||
return true;
|
||||
console.log('Demo zone created.')
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
export default ZoneService;
|
||||
export default ZoneService
|
||||
|
@ -1,17 +1,16 @@
|
||||
import dotenv from "dotenv";
|
||||
import dotenv from 'dotenv'
|
||||
|
||||
dotenv.config();
|
||||
dotenv.config()
|
||||
|
||||
class config
|
||||
{
|
||||
static ENV: string = process.env.ENV || "prod";
|
||||
static HOST: string = process.env.HOST || "0.0.0.0";
|
||||
static PORT: number = process.env.PORT ? parseInt(process.env.PORT) : 6969;
|
||||
static JWT_SECRET: string = process.env.JWT_SECRET || "secret";
|
||||
class config {
|
||||
static ENV: string = process.env.ENV || 'prod'
|
||||
static HOST: string = process.env.HOST || '0.0.0.0'
|
||||
static PORT: number = process.env.PORT ? parseInt(process.env.PORT) : 6969
|
||||
static JWT_SECRET: string = process.env.JWT_SECRET || 'secret'
|
||||
|
||||
static DEFAULT_CHARACTER_ZONE: number = parseInt(process.env.DEFAULT_CHARACTER_ZONE || "1");
|
||||
static DEFAULT_CHARACTER_X: number = parseInt(process.env.DEFAULT_CHARACTER_POS_X || "0");
|
||||
static DEFAULT_CHARACTER_Y: number = parseInt(process.env.DEFAULT_CHARACTER_POS_Y || "0");
|
||||
static DEFAULT_CHARACTER_ZONE: number = parseInt(process.env.DEFAULT_CHARACTER_ZONE || '1')
|
||||
static DEFAULT_CHARACTER_X: number = parseInt(process.env.DEFAULT_CHARACTER_POS_X || '0')
|
||||
static DEFAULT_CHARACTER_Y: number = parseInt(process.env.DEFAULT_CHARACTER_POS_Y || '0')
|
||||
}
|
||||
|
||||
export default config;
|
||||
export default config
|
||||
|
@ -2,12 +2,12 @@
|
||||
* Resources:
|
||||
* https://stackoverflow.com/questions/76131891/what-is-the-best-method-for-socket-io-authentication
|
||||
*/
|
||||
import {Application, Request, Response} from 'express';
|
||||
import UserService from '../services/UserService';
|
||||
import jwt from "jsonwebtoken";
|
||||
import config from "./Config";
|
||||
import {loginAccountSchema, registerAccountSchema} from "./ZodTypes";
|
||||
import path from "path";
|
||||
import { Application, Request, Response } from 'express'
|
||||
import UserService from '../services/UserService'
|
||||
import jwt from 'jsonwebtoken'
|
||||
import config from './Config'
|
||||
import { loginAccountSchema, registerAccountSchema } from './ZodTypes'
|
||||
import path from 'path'
|
||||
import { TAsset } from './Types'
|
||||
import tileRepository from '../repositories/TileRepository'
|
||||
import objectRepository from '../repositories/ObjectRepository'
|
||||
@ -15,89 +15,90 @@ import spriteRepository from '../repositories/SpriteRepository'
|
||||
|
||||
async function addHttpRoutes(app: Application) {
|
||||
app.get('/assets', async (req: Request, res: Response) => {
|
||||
let assets: TAsset[] = [];
|
||||
const tiles = await tileRepository.getAll();
|
||||
tiles.forEach(tile => {
|
||||
let assets: TAsset[] = []
|
||||
const tiles = await tileRepository.getAll()
|
||||
tiles.forEach((tile) => {
|
||||
assets.push({
|
||||
key: tile.id,
|
||||
value: '/assets/tiles/' + tile.id + '.png',
|
||||
group: 'tiles',
|
||||
type: 'link'
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
|
||||
const objects = await objectRepository.getAll();
|
||||
objects.forEach(object => {
|
||||
const objects = await objectRepository.getAll()
|
||||
objects.forEach((object) => {
|
||||
assets.push({
|
||||
key: object.id,
|
||||
value: '/assets/objects/' + object.id + '.png',
|
||||
group: 'objects',
|
||||
type: 'link'
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
|
||||
res.json(assets);
|
||||
});
|
||||
res.json(assets)
|
||||
})
|
||||
app.get('/assets/:type/:file', (req: Request, res: Response) => {
|
||||
const assetName = req.params.file;
|
||||
const assetName = req.params.file
|
||||
|
||||
// if (!isValidAsset(assetName)) {
|
||||
// return res.status(400).send('Invalid asset name');
|
||||
// }
|
||||
|
||||
const options = {
|
||||
root: path.join(process.cwd(), 'public', req.params.type),
|
||||
};
|
||||
root: path.join(process.cwd(), 'public', req.params.type)
|
||||
}
|
||||
|
||||
res.sendFile(assetName, options, (err) => {
|
||||
if (err) {
|
||||
console.error('Error sending file:', err);
|
||||
res.status(500).send('Error downloading the asset');
|
||||
console.error('Error sending file:', err)
|
||||
res.status(500).send('Error downloading the asset')
|
||||
}
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
|
||||
app.post('/login', async (req: Request, res: Response) => {
|
||||
const { username, password } = req.body;
|
||||
const { username, password } = req.body
|
||||
|
||||
try {
|
||||
loginAccountSchema.parse({ username, password });
|
||||
loginAccountSchema.parse({ username, password })
|
||||
} catch (error: any) {
|
||||
return res.status(400).json({ message: error.errors[0]?.message });
|
||||
return res.status(400).json({ message: error.errors[0]?.message })
|
||||
}
|
||||
|
||||
const userService = new UserService();
|
||||
const user = await userService.login(username, password);
|
||||
|
||||
if (user) { //test
|
||||
const token = jwt.sign({ id: user.id }, config.JWT_SECRET, { expiresIn: '4h' });
|
||||
return res.status(200).json({ token });
|
||||
}
|
||||
|
||||
return res.status(400).json({ message: 'Failed to login' });
|
||||
});
|
||||
|
||||
app.post('/register', async (req: Request, res: Response) => {
|
||||
const { username, password } = req.body;
|
||||
|
||||
try {
|
||||
registerAccountSchema.parse({ username, password });
|
||||
} catch (error: any) {
|
||||
return res.status(400).json({ message: error.errors[0]?.message });
|
||||
}
|
||||
|
||||
const userService = new UserService();
|
||||
const user = await userService.register(username, password);
|
||||
const userService = new UserService()
|
||||
const user = await userService.login(username, password)
|
||||
|
||||
if (user) {
|
||||
const token = jwt.sign({ id: user.id }, config.JWT_SECRET, { expiresIn: '4h' });
|
||||
return res.status(200).json({ token });
|
||||
//test
|
||||
const token = jwt.sign({ id: user.id }, config.JWT_SECRET, { expiresIn: '4h' })
|
||||
return res.status(200).json({ token })
|
||||
}
|
||||
|
||||
return res.status(400).json({ message: 'Failed to register user' });
|
||||
});
|
||||
return res.status(400).json({ message: 'Failed to login' })
|
||||
})
|
||||
|
||||
console.log('[✅] Web routes added');
|
||||
app.post('/register', async (req: Request, res: Response) => {
|
||||
const { username, password } = req.body
|
||||
|
||||
try {
|
||||
registerAccountSchema.parse({ username, password })
|
||||
} catch (error: any) {
|
||||
return res.status(400).json({ message: error.errors[0]?.message })
|
||||
}
|
||||
|
||||
const userService = new UserService()
|
||||
const user = await userService.register(username, password)
|
||||
|
||||
if (user) {
|
||||
const token = jwt.sign({ id: user.id }, config.JWT_SECRET, { expiresIn: '4h' })
|
||||
return res.status(200).json({ token })
|
||||
}
|
||||
|
||||
return res.status(400).json({ message: 'Failed to register user' })
|
||||
})
|
||||
|
||||
console.log('[✅] Web routes added')
|
||||
}
|
||||
|
||||
export { addHttpRoutes };
|
||||
export { addHttpRoutes }
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
import { PrismaClient } from '@prisma/client'
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
const prisma = new PrismaClient()
|
||||
|
||||
export default prisma;
|
||||
export default prisma
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Socket } from 'socket.io';
|
||||
import {Character, User} from "@prisma/client";
|
||||
import { Socket } from 'socket.io'
|
||||
import { Character, User } from '@prisma/client'
|
||||
|
||||
export type TSocket = Socket & {
|
||||
user?: User
|
||||
@ -17,13 +17,11 @@ export type TSocket = Socket & {
|
||||
}
|
||||
|
||||
export type TCharacter = Socket & {
|
||||
user?: User,
|
||||
user?: User
|
||||
character?: Character
|
||||
}
|
||||
|
||||
export type TZoneCharacter = Character & {
|
||||
|
||||
}
|
||||
export type TZoneCharacter = Character & {}
|
||||
|
||||
export type TAsset = {
|
||||
key: string
|
||||
|
@ -1,28 +1,37 @@
|
||||
import { z } from 'zod';
|
||||
import { z } from 'zod'
|
||||
|
||||
export const loginAccountSchema = z.object({
|
||||
username:z.string()
|
||||
username: z
|
||||
.string()
|
||||
.min(3, { message: 'Name must be at least 3 characters long' })
|
||||
.max(255, { message: 'Name must be at most 255 characters long' })
|
||||
.regex(/^[A-Za-z][A-Za-z0-9_-]*$/, { message: 'Name must start with a letter and can only contain letters, numbers, underscores, or dashes' }),
|
||||
password: z.string().min(8, {
|
||||
password: z
|
||||
.string()
|
||||
.min(8, {
|
||||
message: 'Password must be at least 8 characters long'
|
||||
}).max(255)
|
||||
});
|
||||
})
|
||||
.max(255)
|
||||
})
|
||||
|
||||
export const registerAccountSchema = z.object({
|
||||
username: z.string()
|
||||
username: z
|
||||
.string()
|
||||
.min(3, { message: 'Name must be at least 3 characters long' })
|
||||
.max(255, { message: 'Name must be at most 255 characters long' })
|
||||
.regex(/^[A-Za-z][A-Za-z0-9_-]*$/, { message: 'Name must start with a letter and can only contain letters, numbers, underscores, or dashes' }),
|
||||
password: z.string().min(8, {
|
||||
password: z
|
||||
.string()
|
||||
.min(8, {
|
||||
message: 'Password must be at least 8 characters long'
|
||||
}).max(255)
|
||||
});
|
||||
})
|
||||
.max(255)
|
||||
})
|
||||
|
||||
export const ZCharacterCreate = z.object({
|
||||
name: z.string()
|
||||
name: z
|
||||
.string()
|
||||
.min(3, { message: 'Name must be at least 3 characters long' })
|
||||
.max(255, { message: 'Name must be at most 255 characters long' })
|
||||
.regex(/^[A-Za-z][A-Za-z0-9_-]*$/, { message: 'Name must start with a letter and can only contain letters, numbers, underscores, or dashes' })
|
||||
});
|
||||
})
|
||||
|
Loading…
x
Reference in New Issue
Block a user