From 3a5989ea0d1c5861befd65d8a13ea2319f8176f7 Mon Sep 17 00:00:00 2001 From: Hamcha Date: Fri, 11 Oct 2019 16:21:46 +0200 Subject: [PATCH] Add rename --- src/network/Client.ts | 31 ++++++++--------- src/network/PeerServer.ts | 45 ++++++++++++++++--------- src/store/network/actions.ts | 12 ++----- src/store/network/getters.ts | 12 ++++++- src/store/network/mutations.ts | 3 +- src/store/network/types.ts | 9 +---- src/views/Lobby.vue | 61 +++++++++++++++++++++++++--------- 7 files changed, 106 insertions(+), 67 deletions(-) diff --git a/src/network/Client.ts b/src/network/Client.ts index 4ac0305..6f290e8 100644 --- a/src/network/Client.ts +++ b/src/network/Client.ts @@ -1,10 +1,7 @@ -import { - PeerMetadata, - NetworkMessage, - PasswordResponse, - RoomInfo -} from "./types"; import EventEmitter from "eventemitter3"; +import Vue from "vue"; + +import { NetworkMessage, PasswordResponse, PeerMetadata, RoomInfo } from "./types"; export abstract class Client extends EventEmitter { public metadata: PeerMetadata; @@ -30,18 +27,18 @@ export abstract class Client extends EventEmitter { 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; } + + 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; + } + Vue.set(this.players, idx, data.newname); this.emit("rename", data.oldname, data.newname); break; // A new player joined the room (this includes us) diff --git a/src/network/PeerServer.ts b/src/network/PeerServer.ts index 67e3226..099d614 100644 --- a/src/network/PeerServer.ts +++ b/src/network/PeerServer.ts @@ -1,23 +1,24 @@ +import EventEmitter from "eventemitter3"; import Peer, { DataConnection } from "peerjs"; + +import { LocalClient } from "."; import { - RoomInfo, - PasswordRequest, - Room, + AckMessage, + ChatMessage, ErrorMessage, + JoinMessage, + LeaveMessage, + NetworkMessage, + NetworkPlayer, + PasswordRequest, PasswordResponse, PeerMetadata, - JoinMessage, - RoomInfoMessage, Player, - NetworkMessage, RenameMessage, - LeaveMessage, - NetworkPlayer, - AckMessage, - ChatMessage + Room, + RoomInfo, + RoomInfoMessage, } from "./types"; -import { LocalClient } from "."; -import EventEmitter from "eventemitter3"; // Increment name, add number at the end if not present // Examples: @@ -212,16 +213,30 @@ export class PeerServer extends EventEmitter { this.broadcast(data); } else { // Player is telling someone specifically - if (data.to in this.players) { - this.send(this.players[data.to], data); - } else { + if (!(data.to in this.players)) { this.send(player, { kind: "error", error: `player not found: ${data.to}` }); + return; } + this.send(this.players[data.to], data); } break; + // Player wants to change name + case "rename": + // Make sure new name is valid + data.oldname = player.name; + if (data.newname in this.players) { + this.send(player, { + kind: "error", + error: "name not available" + }); + return; + } + player.name = data.newname; + this.broadcast(data); + break; // Player is leaving! case "leave-req": // If we're leaving, end the server diff --git a/src/store/network/actions.ts b/src/store/network/actions.ts index 4afbaed..ac38a3d 100644 --- a/src/store/network/actions.ts +++ b/src/store/network/actions.ts @@ -1,14 +1,8 @@ +import { ChatMessage, Client, LocalClient, NetworkMessage, PeerClient, PeerServer } from "@/network"; import { ActionTree, Commit } from "vuex"; + import { AppState } from "../types"; -import { NetworkState, StartServerOptions, ConnectOptions } from "./types"; -import { - PeerServer, - LocalClient, - PeerClient, - NetworkMessage, - Client, - ChatMessage -} from "@/network"; +import { ConnectOptions, NetworkState, StartServerOptions } from "./types"; function bindClientEvents(commit: Commit, client: Client) { client.on("handshake", () => { diff --git a/src/store/network/getters.ts b/src/store/network/getters.ts index d73da9a..76f509c 100644 --- a/src/store/network/getters.ts +++ b/src/store/network/getters.ts @@ -1,7 +1,8 @@ +import { Client } from "@/network"; import { GetterTree } from "vuex"; + import { AppState } from "../types"; import { NetworkState } from "./types"; -import { Client } from "@/network"; const getters: GetterTree = { peerID(state): string | null { @@ -32,6 +33,15 @@ const getters: GetterTree = { return state.peerType; }, + busy(state): boolean { + if (state.peerType == "client") { + if (state.connectionStatus == "connecting") { + return true; + } + } + return false; + }, + inRoom(state): boolean { if (state.peerType == "client") { return state.connectionStatus == "connected"; diff --git a/src/store/network/mutations.ts b/src/store/network/mutations.ts index 6feaaa5..6832f2c 100644 --- a/src/store/network/mutations.ts +++ b/src/store/network/mutations.ts @@ -1,4 +1,5 @@ import { ChatMessage, LocalClient, PeerClient, PeerServer } from "@/network"; +import Vue from "vue"; import { MutationTree } from "vuex"; import { ClientNetworkState, ConnectionStatus, NetworkState, ServerNetworkState } from "./types"; @@ -36,7 +37,7 @@ const mutations: MutationTree = { }, playerListChanged(state, players: string[]) { - state.players = players; + Vue.set(state, "players", players); } }; diff --git a/src/store/network/types.ts b/src/store/network/types.ts index 532518b..e810edf 100644 --- a/src/store/network/types.ts +++ b/src/store/network/types.ts @@ -1,11 +1,4 @@ -import { - PeerClient, - PeerServer, - LocalClient, - RoomInfo, - PeerMetadata, - ChatMessage -} from "@/network"; +import { ChatMessage, LocalClient, PeerClient, PeerMetadata, PeerServer, RoomInfo } from "@/network"; import Peer from "peerjs"; export type ConnectionStatus = diff --git a/src/views/Lobby.vue b/src/views/Lobby.vue index dbabd6c..5adeb62 100644 --- a/src/views/Lobby.vue +++ b/src/views/Lobby.vue @@ -93,6 +93,14 @@ +
+ + + + Change name +
@@ -211,7 +219,9 @@ import { Component, Vue } from "vue-property-decorator"; import TopNav from "@/components/Navigation/TopNav.vue"; import { StartServerOptions, ConnectOptions } from "@/store/network/types"; import { Action, Getter } from "vuex-class"; -import { Client } from "@/network"; +import { Client, NetworkMessage } from "@/network"; + +const networkNS = { namespace: "network" }; @Component({ components: { @@ -223,34 +233,41 @@ export default class Lobby extends Vue { private hostMaxPlayers!: number; private hostPassword!: string; private joinSessionID!: string; - private busy!: boolean; + private wantedName!: string; - @Action("startServer", { namespace: "network" }) + @Action("startServer", networkNS) private startServer!: (options: StartServerOptions) => void; - @Action("connect", { namespace: "network" }) + @Action("sendMessage", networkNS) + private sendMessage!: (message: NetworkMessage) => void; + + @Action("connect", networkNS) private connect!: (options: ConnectOptions) => void; - @Getter("inRoom", { namespace: "network" }) + @Getter("inRoom", networkNS) private inRoom!: boolean; - @Getter("sessionID", { namespace: "network" }) + @Getter("busy", networkNS) + private busy!: boolean; + + @Getter("sessionID", networkNS) private sessionID!: string | null; - @Getter("players", { namespace: "network" }) + @Getter("players", networkNS) private players!: string[]; private data() { + const playerName = + "Guest-" + + Math.random() + .toString() + .slice(2, 8); return { - playerName: - "Guest-" + - Math.random() - .toString() - .slice(2, 8), - busy: false, + playerName, hostMaxPlayers: 8, hostPassword: "", - joinSessionID: "" + joinSessionID: "", + wantedName: playerName }; } @@ -262,7 +279,7 @@ export default class Lobby extends Vue { } private async create() { - this.busy = true; + this.wantedName = this.playerName; this.startServer({ playerInfo: { name: this.playerName @@ -275,7 +292,7 @@ export default class Lobby extends Vue { } private async join() { - this.busy = true; + this.wantedName = this.playerName; this.connect({ serverID: this.joinSessionID, playerInfo: { @@ -284,6 +301,14 @@ export default class Lobby extends Vue { }); } + private async changeName() { + this.sendMessage({ + kind: "rename", + oldname: this.playerName, + newname: this.wantedName + }); + } + private get canJoin(): boolean { return this.joinSessionID != ""; } @@ -300,5 +325,9 @@ export default class Lobby extends Vue { } return `${location.origin}${subpath}/join/${this.sessionID}`; } + + private get nameAvailable(): boolean { + return this.wantedName != "" && !this.players.includes(this.wantedName); + } }