diff --git a/src/network/PeerClient.ts b/src/network/PeerClient.ts index f15a3dd..efa36c2 100644 --- a/src/network/PeerClient.ts +++ b/src/network/PeerClient.ts @@ -5,10 +5,12 @@ import { PeerMetadata, NetworkMessage } from "./types"; export class PeerClient extends NetworkPeer { private connection?: DataConnection; private metadata: PeerMetadata; + public players: string[]; public constructor(metadata: PeerMetadata, customPeer?: Peer) { super(customPeer); this.metadata = metadata; + this.players = []; } public connect(peerid: string) { @@ -29,6 +31,39 @@ export class PeerClient extends NetworkPeer { private _received(data: NetworkMessage) { this.emit("data", data); + switch (data.kind) { + // Someone changed name (or was forced to) + case "rename": + if (data.oldname == this.metadata.name) { + // We got a name change! + this.metadata.name = data.newname; + } else { + let idx = this.players.indexOf(data.oldname); + if (idx < 0) { + // Weird + console.warn( + `Someone (${data.oldname}) changed name but wasn't on the player list` + ); + this.players.push(data.newname); + break; + } + this.players[idx] = data.newname; + } + this.emit("rename", data.oldname, data.newname); + break; + // A new player joined the room (this includes us) + case "player-joined": + this.players.push(data.name); + this.emit("player-joined", data.name); + break; + default: + // For most cases, we can just use the kind as event type + this.emit(data.kind, data); + } + } + + public get name(): string { + return this.metadata.name; } } diff --git a/src/tests/unit/network.spec.ts b/src/tests/unit/network.spec.ts index 743e757..3c6ab1f 100644 --- a/src/tests/unit/network.spec.ts +++ b/src/tests/unit/network.spec.ts @@ -56,7 +56,7 @@ describe("network/PeerServer", () => { await hook.expect("client-data", 1000, messageKind("player-joined")); }); - test("Test multiple clients", async () => { + test("Test multiple clients (w/ name collision)", async () => { const mox = mockSource(); const hook = new EventHook(); createServer(mox); @@ -76,5 +76,17 @@ describe("network/PeerServer", () => { }); describe("network/PeerClient", () => { - //TODO Client tests + test("Client handles forced name change", async () => { + const mox = mockSource(); + const hook = new EventHook(); + createServer(mox); + const client1 = createClient(mox); + const client2 = createClient(mox); + hook.hookEmitter(client2, "rename", "client-rename"); + client1.connect("test-server"); + client2.connect("test-server"); + await hook.expect("client-rename", 1000); + // Client must have changed its internal data to match the new name + expect(client1.name).not.toEqual(client2.name); + }); });