From 6510a493a08216395ba7d05804191213b7ffb32a Mon Sep 17 00:00:00 2001 From: Evert Prants Date: Sun, 25 Jun 2023 18:15:04 +0300 Subject: [PATCH] more progress --- src/events/events.gateway.ts | 4 ++-- src/game/player.ts | 15 --------------- src/net/packet.ts | 2 +- src/net/ws-adapter.ts | 4 ++++ src/player/player-store.service.ts | 30 ++++++++++++++++++++++++++++++ src/types/packet-type.enum.ts | 4 ++-- src/world/physics.service.ts | 10 +++++----- src/world/world.service.ts | 29 ++++++++++++++++++++++++++++- 8 files changed, 72 insertions(+), 26 deletions(-) diff --git a/src/events/events.gateway.ts b/src/events/events.gateway.ts index b8ff8e3..23b121d 100644 --- a/src/events/events.gateway.ts +++ b/src/events/events.gateway.ts @@ -62,7 +62,7 @@ export class EventsGateway await this.world.initializePlayer(player); } - if (player.handlePlayerPacket(data)) return false; + if (this.players.handlePlayerPacket(data, player)) return false; return false; } @@ -76,6 +76,6 @@ export class EventsGateway } handleDisconnect(client: PlayerSocket) { - this.players.disconnect(client); + this.world.playerQuit(client); } } diff --git a/src/game/player.ts b/src/game/player.ts index 8708288..81f7d0b 100644 --- a/src/game/player.ts +++ b/src/game/player.ts @@ -3,7 +3,6 @@ import { PlayerSocket } from 'src/types/data-socket'; import { Humanoid } from './humanoid.object'; import { Group } from './group.object'; import { Vector3 } from 'three'; -import { PacketType } from 'src/types/packet-type.enum'; export class Player { public character: Group; @@ -39,18 +38,4 @@ export class Player { return group; } - - public handlePlayerPacket(packet: Packet) { - if (packet.packet === PacketType.PLAYER_MOVEMENT) { - const velocity = packet.read('vec3'); - const lookAt = packet.read('vec3'); - if (this.controller) { - this.controller.setVelocity(velocity); - this.controller.setLook(lookAt); - return true; - } - } - - return false; - } } diff --git a/src/net/packet.ts b/src/net/packet.ts index 70f47bf..dd192d1 100644 --- a/src/net/packet.ts +++ b/src/net/packet.ts @@ -52,7 +52,7 @@ export class Packet { return this.buffer.readStringNT() as T; case 'bool': case Boolean: - return this.buffer.readUInt8() as T; + return (this.buffer.readUInt8() === 1) as T; case 'float': case Number: return this.buffer.readFloatLE() as T; diff --git a/src/net/ws-adapter.ts b/src/net/ws-adapter.ts index f4336cf..bf7c900 100644 --- a/src/net/ws-adapter.ts +++ b/src/net/ws-adapter.ts @@ -19,6 +19,10 @@ export class WsAdapter implements WebSocketAdapter { server.on('connection', callback); } + bindClientDisconnect(client: any, callback: (...args: any[]) => void) { + client.on('close', callback); + } + bindMessageHandlers( client: WebSocket, handlers: MessageMappingProperties[], diff --git a/src/player/player-store.service.ts b/src/player/player-store.service.ts index 9d3ae32..88aad30 100644 --- a/src/player/player-store.service.ts +++ b/src/player/player-store.service.ts @@ -5,6 +5,7 @@ import { PlayerAuthService } from './player-auth.service'; import { Packet } from 'src/net/packet'; import { getRandomName } from 'src/utils/random'; import { PacketType } from 'src/types/packet-type.enum'; +import { Vector3 } from 'three'; @Injectable() export class PlayerStoreService { @@ -73,7 +74,36 @@ export class PlayerStoreService { .write(player.name, String) .write(player.character.position, 'vec3') .write(player.character.quaternion, 'quat') + .write(player.character.uuid, String) .toBuffer(); }); } + + public handlePlayerPacket(packet: Packet, player: Player) { + if (packet.packet === PacketType.PLAYER_MOVEMENT) { + const playerId = packet.read(String); + const velocity = packet.read('vec3'); + const lookAt = packet.read('vec3'); + const jump = packet.read('bool'); + + this.broadcastExcept( + new Packet(PacketType.PLAYER_MOVEMENT) + .write(playerId, String) + .write(velocity, 'vec3') + .write(lookAt, 'vec3') + .write(jump, 'bool') + .toBuffer(), + [player.id], + ); + + if (player.controller) { + player.controller.setVelocity(velocity); + player.controller.setLook(lookAt); + if (jump) player.controller.jump(); + return true; + } + } + + return false; + } } diff --git a/src/types/packet-type.enum.ts b/src/types/packet-type.enum.ts index cbbdf2c..b983936 100644 --- a/src/types/packet-type.enum.ts +++ b/src/types/packet-type.enum.ts @@ -49,11 +49,11 @@ export enum PacketType { */ PLAYER_QUIT, /** - * [][Player ID][Player Name][x y z Position][Data...] + * [][Player ID][Player Name][x y z Position][x y z w quaternion][Object UUID][Data...] */ PLAYER_CHARACTER, /** - * [][Velocity][LookAt][AnimState] + * [][Player ID][Velocity][LookAt][Jump][AnimState] */ PLAYER_MOVEMENT, /** diff --git a/src/world/physics.service.ts b/src/world/physics.service.ts index 784e9b4..73d6300 100644 --- a/src/world/physics.service.ts +++ b/src/world/physics.service.ts @@ -3,7 +3,7 @@ import { Humanoid, PhysicsObject, World } from 'src/game'; import RAPIER from '@dimforge/rapier3d-compat'; import { Packet } from 'src/net/packet'; import { PacketType } from 'src/types/packet-type.enum'; -import { Object3D, Quaternion, SkinnedMesh, Vector3 } from 'three'; +import { Object3D, Vector3 } from 'three'; import { GameObject } from 'src/game/game-object'; import { PhysicsTicking } from 'src/physics'; @@ -20,9 +20,9 @@ export class PhysicsService { loop() { if (!this.running) return; - this.physicsTicker = setTimeout(() => this.loop(), 20); + this.physicsTicker = setTimeout(() => this.loop(), 25); this.physicsWorld.step(); - for (const object of this.trackedObjects) object.tick(0.02); // TODO: DT + for (const object of this.trackedObjects) object.tick(0.025); // TODO: DT } async start(world: World) { @@ -91,8 +91,8 @@ export class PhysicsService { } }); - this.trackedObjects = this.trackedObjects.filter((object) => - physicsLeaveUUIDs.includes(object.uuid), + this.trackedObjects = this.trackedObjects.filter( + (object) => !physicsLeaveUUIDs.includes(object.uuid), ); } diff --git a/src/world/world.service.ts b/src/world/world.service.ts index f146283..bcf3c49 100644 --- a/src/world/world.service.ts +++ b/src/world/world.service.ts @@ -12,6 +12,7 @@ import { PacketType } from 'src/types/packet-type.enum'; import { Player } from 'src/game/player'; import { GameObject } from 'src/game/game-object'; import { PhysicsService } from './physics.service'; +import { PlayerSocket } from 'src/types/data-socket'; @Injectable() export class WorldService implements OnModuleInit { @@ -101,20 +102,31 @@ export class WorldService implements OnModuleInit { const character = player.createPlayerCharacter(); this.world.add(character); this.physics.applyPhysics(character); - // TODO: position this.players.broadcast( new Packet(PacketType.PLAYER_CHARACTER) .write(player.id, String) .write(player.name, String) .write(character.position, 'vec3') .write(character.quaternion, 'quat') + .write(character.uuid, String) .toBuffer(), ); + this.players .getPlayerCharacterPackets(player) .forEach((packet) => player.send(packet)); } + public removeObject(object: Object3D) { + object.removeFromParent(); + this.physics.removePhysics(object); + this.players.broadcast( + new Packet(PacketType.STREAM_DESTROY) + .write(object.uuid, String) + .toBuffer(), + ); + } + public createObject(object: string, setParent?: Object3D, skipEvent = false) { const parent = setParent || this.world; const ObjectType = instancableGameObjects[object]; @@ -166,6 +178,21 @@ export class WorldService implements OnModuleInit { this.world.deserialize(save.world); } + public playerQuit(client: PlayerSocket) { + const player = this.players.getByClient(client); + this.players.disconnect(client); + if (!player) return; + this.players.broadcast( + new Packet(PacketType.PLAYER_QUIT) + .write(player.id, String) + .write(player.name, String) + .write('', String) + .toBuffer(), + ); + this.removeObject(player.controller); + this.removeObject(player.character); + } + private recursiveCreate(entry: SerializedObject, setParent?: Object3D) { const parent = setParent || this.world; const newObject = this.createObject(entry.objectType, parent, true);