more progress

This commit is contained in:
Evert Prants 2023-06-25 18:15:04 +03:00
parent 84309feb0c
commit 6510a493a0
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
8 changed files with 72 additions and 26 deletions

View File

@ -62,7 +62,7 @@ export class EventsGateway
await this.world.initializePlayer(player); await this.world.initializePlayer(player);
} }
if (player.handlePlayerPacket(data)) return false; if (this.players.handlePlayerPacket(data, player)) return false;
return false; return false;
} }
@ -76,6 +76,6 @@ export class EventsGateway
} }
handleDisconnect(client: PlayerSocket) { handleDisconnect(client: PlayerSocket) {
this.players.disconnect(client); this.world.playerQuit(client);
} }
} }

View File

@ -3,7 +3,6 @@ import { PlayerSocket } from 'src/types/data-socket';
import { Humanoid } from './humanoid.object'; import { Humanoid } from './humanoid.object';
import { Group } from './group.object'; import { Group } from './group.object';
import { Vector3 } from 'three'; import { Vector3 } from 'three';
import { PacketType } from 'src/types/packet-type.enum';
export class Player { export class Player {
public character: Group; public character: Group;
@ -39,18 +38,4 @@ export class Player {
return group; return group;
} }
public handlePlayerPacket(packet: Packet) {
if (packet.packet === PacketType.PLAYER_MOVEMENT) {
const velocity = packet.read<Vector3>('vec3');
const lookAt = packet.read<Vector3>('vec3');
if (this.controller) {
this.controller.setVelocity(velocity);
this.controller.setLook(lookAt);
return true;
}
}
return false;
}
} }

View File

@ -52,7 +52,7 @@ export class Packet {
return this.buffer.readStringNT() as T; return this.buffer.readStringNT() as T;
case 'bool': case 'bool':
case Boolean: case Boolean:
return this.buffer.readUInt8() as T; return (this.buffer.readUInt8() === 1) as T;
case 'float': case 'float':
case Number: case Number:
return this.buffer.readFloatLE() as T; return this.buffer.readFloatLE() as T;

View File

@ -19,6 +19,10 @@ export class WsAdapter implements WebSocketAdapter {
server.on('connection', callback); server.on('connection', callback);
} }
bindClientDisconnect(client: any, callback: (...args: any[]) => void) {
client.on('close', callback);
}
bindMessageHandlers( bindMessageHandlers(
client: WebSocket, client: WebSocket,
handlers: MessageMappingProperties[], handlers: MessageMappingProperties[],

View File

@ -5,6 +5,7 @@ import { PlayerAuthService } from './player-auth.service';
import { Packet } from 'src/net/packet'; import { Packet } from 'src/net/packet';
import { getRandomName } from 'src/utils/random'; import { getRandomName } from 'src/utils/random';
import { PacketType } from 'src/types/packet-type.enum'; import { PacketType } from 'src/types/packet-type.enum';
import { Vector3 } from 'three';
@Injectable() @Injectable()
export class PlayerStoreService { export class PlayerStoreService {
@ -73,7 +74,36 @@ export class PlayerStoreService {
.write(player.name, String) .write(player.name, String)
.write(player.character.position, 'vec3') .write(player.character.position, 'vec3')
.write(player.character.quaternion, 'quat') .write(player.character.quaternion, 'quat')
.write(player.character.uuid, String)
.toBuffer(); .toBuffer();
}); });
} }
public handlePlayerPacket(packet: Packet, player: Player) {
if (packet.packet === PacketType.PLAYER_MOVEMENT) {
const playerId = packet.read(String);
const velocity = packet.read<Vector3>('vec3');
const lookAt = packet.read<Vector3>('vec3');
const jump = packet.read<boolean>('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;
}
} }

View File

@ -49,11 +49,11 @@ export enum PacketType {
*/ */
PLAYER_QUIT, 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, PLAYER_CHARACTER,
/** /**
* [][Velocity][LookAt][AnimState] * [][Player ID][Velocity][LookAt][Jump][AnimState]
*/ */
PLAYER_MOVEMENT, PLAYER_MOVEMENT,
/** /**

View File

@ -3,7 +3,7 @@ import { Humanoid, PhysicsObject, World } from 'src/game';
import RAPIER from '@dimforge/rapier3d-compat'; import RAPIER from '@dimforge/rapier3d-compat';
import { Packet } from 'src/net/packet'; import { Packet } from 'src/net/packet';
import { PacketType } from 'src/types/packet-type.enum'; 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 { GameObject } from 'src/game/game-object';
import { PhysicsTicking } from 'src/physics'; import { PhysicsTicking } from 'src/physics';
@ -20,9 +20,9 @@ export class PhysicsService {
loop() { loop() {
if (!this.running) return; if (!this.running) return;
this.physicsTicker = setTimeout(() => this.loop(), 20); this.physicsTicker = setTimeout(() => this.loop(), 25);
this.physicsWorld.step(); 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) { async start(world: World) {
@ -91,8 +91,8 @@ export class PhysicsService {
} }
}); });
this.trackedObjects = this.trackedObjects.filter((object) => this.trackedObjects = this.trackedObjects.filter(
physicsLeaveUUIDs.includes(object.uuid), (object) => !physicsLeaveUUIDs.includes(object.uuid),
); );
} }

View File

@ -12,6 +12,7 @@ import { PacketType } from 'src/types/packet-type.enum';
import { Player } from 'src/game/player'; import { Player } from 'src/game/player';
import { GameObject } from 'src/game/game-object'; import { GameObject } from 'src/game/game-object';
import { PhysicsService } from './physics.service'; import { PhysicsService } from './physics.service';
import { PlayerSocket } from 'src/types/data-socket';
@Injectable() @Injectable()
export class WorldService implements OnModuleInit { export class WorldService implements OnModuleInit {
@ -101,20 +102,31 @@ export class WorldService implements OnModuleInit {
const character = player.createPlayerCharacter(); const character = player.createPlayerCharacter();
this.world.add(character); this.world.add(character);
this.physics.applyPhysics(character); this.physics.applyPhysics(character);
// TODO: position
this.players.broadcast( this.players.broadcast(
new Packet(PacketType.PLAYER_CHARACTER) new Packet(PacketType.PLAYER_CHARACTER)
.write(player.id, String) .write(player.id, String)
.write(player.name, String) .write(player.name, String)
.write(character.position, 'vec3') .write(character.position, 'vec3')
.write(character.quaternion, 'quat') .write(character.quaternion, 'quat')
.write(character.uuid, String)
.toBuffer(), .toBuffer(),
); );
this.players this.players
.getPlayerCharacterPackets(player) .getPlayerCharacterPackets(player)
.forEach((packet) => player.send(packet)); .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) { public createObject(object: string, setParent?: Object3D, skipEvent = false) {
const parent = setParent || this.world; const parent = setParent || this.world;
const ObjectType = instancableGameObjects[object]; const ObjectType = instancableGameObjects[object];
@ -166,6 +178,21 @@ export class WorldService implements OnModuleInit {
this.world.deserialize(save.world); 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) { private recursiveCreate(entry: SerializedObject, setParent?: Object3D) {
const parent = setParent || this.world; const parent = setParent || this.world;
const newObject = this.createObject(entry.objectType, parent, true); const newObject = this.createObject(entry.objectType, parent, true);