Add rename
This commit is contained in:
parent
ef3e10a6c4
commit
3a5989ea0d
7 changed files with 106 additions and 67 deletions
|
@ -1,10 +1,7 @@
|
||||||
import {
|
|
||||||
PeerMetadata,
|
|
||||||
NetworkMessage,
|
|
||||||
PasswordResponse,
|
|
||||||
RoomInfo
|
|
||||||
} from "./types";
|
|
||||||
import EventEmitter from "eventemitter3";
|
import EventEmitter from "eventemitter3";
|
||||||
|
import Vue from "vue";
|
||||||
|
|
||||||
|
import { NetworkMessage, PasswordResponse, PeerMetadata, RoomInfo } from "./types";
|
||||||
|
|
||||||
export abstract class Client extends EventEmitter {
|
export abstract class Client extends EventEmitter {
|
||||||
public metadata: PeerMetadata;
|
public metadata: PeerMetadata;
|
||||||
|
@ -30,18 +27,18 @@ export abstract class Client extends EventEmitter {
|
||||||
if (data.oldname == this.metadata.name) {
|
if (data.oldname == this.metadata.name) {
|
||||||
// We got a name change!
|
// We got a name change!
|
||||||
this.metadata.name = data.newname;
|
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);
|
this.emit("rename", data.oldname, data.newname);
|
||||||
break;
|
break;
|
||||||
// A new player joined the room (this includes us)
|
// A new player joined the room (this includes us)
|
||||||
|
|
|
@ -1,23 +1,24 @@
|
||||||
|
import EventEmitter from "eventemitter3";
|
||||||
import Peer, { DataConnection } from "peerjs";
|
import Peer, { DataConnection } from "peerjs";
|
||||||
|
|
||||||
|
import { LocalClient } from ".";
|
||||||
import {
|
import {
|
||||||
RoomInfo,
|
AckMessage,
|
||||||
PasswordRequest,
|
ChatMessage,
|
||||||
Room,
|
|
||||||
ErrorMessage,
|
ErrorMessage,
|
||||||
|
JoinMessage,
|
||||||
|
LeaveMessage,
|
||||||
|
NetworkMessage,
|
||||||
|
NetworkPlayer,
|
||||||
|
PasswordRequest,
|
||||||
PasswordResponse,
|
PasswordResponse,
|
||||||
PeerMetadata,
|
PeerMetadata,
|
||||||
JoinMessage,
|
|
||||||
RoomInfoMessage,
|
|
||||||
Player,
|
Player,
|
||||||
NetworkMessage,
|
|
||||||
RenameMessage,
|
RenameMessage,
|
||||||
LeaveMessage,
|
Room,
|
||||||
NetworkPlayer,
|
RoomInfo,
|
||||||
AckMessage,
|
RoomInfoMessage,
|
||||||
ChatMessage
|
|
||||||
} from "./types";
|
} from "./types";
|
||||||
import { LocalClient } from ".";
|
|
||||||
import EventEmitter from "eventemitter3";
|
|
||||||
|
|
||||||
// Increment name, add number at the end if not present
|
// Increment name, add number at the end if not present
|
||||||
// Examples:
|
// Examples:
|
||||||
|
@ -212,16 +213,30 @@ export class PeerServer extends EventEmitter {
|
||||||
this.broadcast(data);
|
this.broadcast(data);
|
||||||
} else {
|
} else {
|
||||||
// Player is telling someone specifically
|
// Player is telling someone specifically
|
||||||
if (data.to in this.players) {
|
if (!(data.to in this.players)) {
|
||||||
this.send<ChatMessage>(this.players[data.to], data);
|
|
||||||
} else {
|
|
||||||
this.send<ErrorMessage>(player, {
|
this.send<ErrorMessage>(player, {
|
||||||
kind: "error",
|
kind: "error",
|
||||||
error: `player not found: ${data.to}`
|
error: `player not found: ${data.to}`
|
||||||
});
|
});
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
this.send<ChatMessage>(this.players[data.to], data);
|
||||||
}
|
}
|
||||||
break;
|
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<ErrorMessage>(player, {
|
||||||
|
kind: "error",
|
||||||
|
error: "name not available"
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
player.name = data.newname;
|
||||||
|
this.broadcast<RenameMessage>(data);
|
||||||
|
break;
|
||||||
// Player is leaving!
|
// Player is leaving!
|
||||||
case "leave-req":
|
case "leave-req":
|
||||||
// If we're leaving, end the server
|
// If we're leaving, end the server
|
||||||
|
|
|
@ -1,14 +1,8 @@
|
||||||
|
import { ChatMessage, Client, LocalClient, NetworkMessage, PeerClient, PeerServer } from "@/network";
|
||||||
import { ActionTree, Commit } from "vuex";
|
import { ActionTree, Commit } from "vuex";
|
||||||
|
|
||||||
import { AppState } from "../types";
|
import { AppState } from "../types";
|
||||||
import { NetworkState, StartServerOptions, ConnectOptions } from "./types";
|
import { ConnectOptions, NetworkState, StartServerOptions } from "./types";
|
||||||
import {
|
|
||||||
PeerServer,
|
|
||||||
LocalClient,
|
|
||||||
PeerClient,
|
|
||||||
NetworkMessage,
|
|
||||||
Client,
|
|
||||||
ChatMessage
|
|
||||||
} from "@/network";
|
|
||||||
|
|
||||||
function bindClientEvents(commit: Commit, client: Client) {
|
function bindClientEvents(commit: Commit, client: Client) {
|
||||||
client.on("handshake", () => {
|
client.on("handshake", () => {
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
|
import { Client } from "@/network";
|
||||||
import { GetterTree } from "vuex";
|
import { GetterTree } from "vuex";
|
||||||
|
|
||||||
import { AppState } from "../types";
|
import { AppState } from "../types";
|
||||||
import { NetworkState } from "./types";
|
import { NetworkState } from "./types";
|
||||||
import { Client } from "@/network";
|
|
||||||
|
|
||||||
const getters: GetterTree<NetworkState, AppState> = {
|
const getters: GetterTree<NetworkState, AppState> = {
|
||||||
peerID(state): string | null {
|
peerID(state): string | null {
|
||||||
|
@ -32,6 +33,15 @@ const getters: GetterTree<NetworkState, AppState> = {
|
||||||
return state.peerType;
|
return state.peerType;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
busy(state): boolean {
|
||||||
|
if (state.peerType == "client") {
|
||||||
|
if (state.connectionStatus == "connecting") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
inRoom(state): boolean {
|
inRoom(state): boolean {
|
||||||
if (state.peerType == "client") {
|
if (state.peerType == "client") {
|
||||||
return state.connectionStatus == "connected";
|
return state.connectionStatus == "connected";
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { ChatMessage, LocalClient, PeerClient, PeerServer } from "@/network";
|
import { ChatMessage, LocalClient, PeerClient, PeerServer } from "@/network";
|
||||||
|
import Vue from "vue";
|
||||||
import { MutationTree } from "vuex";
|
import { MutationTree } from "vuex";
|
||||||
|
|
||||||
import { ClientNetworkState, ConnectionStatus, NetworkState, ServerNetworkState } from "./types";
|
import { ClientNetworkState, ConnectionStatus, NetworkState, ServerNetworkState } from "./types";
|
||||||
|
@ -36,7 +37,7 @@ const mutations: MutationTree<NetworkState> = {
|
||||||
},
|
},
|
||||||
|
|
||||||
playerListChanged(state, players: string[]) {
|
playerListChanged(state, players: string[]) {
|
||||||
state.players = players;
|
Vue.set(state, "players", players);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,4 @@
|
||||||
import {
|
import { ChatMessage, LocalClient, PeerClient, PeerMetadata, PeerServer, RoomInfo } from "@/network";
|
||||||
PeerClient,
|
|
||||||
PeerServer,
|
|
||||||
LocalClient,
|
|
||||||
RoomInfo,
|
|
||||||
PeerMetadata,
|
|
||||||
ChatMessage
|
|
||||||
} from "@/network";
|
|
||||||
import Peer from "peerjs";
|
import Peer from "peerjs";
|
||||||
|
|
||||||
export type ConnectionStatus =
|
export type ConnectionStatus =
|
||||||
|
|
|
@ -93,6 +93,14 @@
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</section>
|
</section>
|
||||||
|
<section class="player-options">
|
||||||
|
<b-field label="Change name">
|
||||||
|
<b-input :disabled="busy" v-model="wantedName"></b-input>
|
||||||
|
</b-field>
|
||||||
|
<b-button @click="changeName" :disabled="!nameAvailable"
|
||||||
|
>Change name</b-button
|
||||||
|
>
|
||||||
|
</section>
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
@ -211,7 +219,9 @@ import { Component, Vue } from "vue-property-decorator";
|
||||||
import TopNav from "@/components/Navigation/TopNav.vue";
|
import TopNav from "@/components/Navigation/TopNav.vue";
|
||||||
import { StartServerOptions, ConnectOptions } from "@/store/network/types";
|
import { StartServerOptions, ConnectOptions } from "@/store/network/types";
|
||||||
import { Action, Getter } from "vuex-class";
|
import { Action, Getter } from "vuex-class";
|
||||||
import { Client } from "@/network";
|
import { Client, NetworkMessage } from "@/network";
|
||||||
|
|
||||||
|
const networkNS = { namespace: "network" };
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
components: {
|
components: {
|
||||||
|
@ -223,34 +233,41 @@ export default class Lobby extends Vue {
|
||||||
private hostMaxPlayers!: number;
|
private hostMaxPlayers!: number;
|
||||||
private hostPassword!: string;
|
private hostPassword!: string;
|
||||||
private joinSessionID!: string;
|
private joinSessionID!: string;
|
||||||
private busy!: boolean;
|
private wantedName!: string;
|
||||||
|
|
||||||
@Action("startServer", { namespace: "network" })
|
@Action("startServer", networkNS)
|
||||||
private startServer!: (options: StartServerOptions) => void;
|
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;
|
private connect!: (options: ConnectOptions) => void;
|
||||||
|
|
||||||
@Getter("inRoom", { namespace: "network" })
|
@Getter("inRoom", networkNS)
|
||||||
private inRoom!: boolean;
|
private inRoom!: boolean;
|
||||||
|
|
||||||
@Getter("sessionID", { namespace: "network" })
|
@Getter("busy", networkNS)
|
||||||
|
private busy!: boolean;
|
||||||
|
|
||||||
|
@Getter("sessionID", networkNS)
|
||||||
private sessionID!: string | null;
|
private sessionID!: string | null;
|
||||||
|
|
||||||
@Getter("players", { namespace: "network" })
|
@Getter("players", networkNS)
|
||||||
private players!: string[];
|
private players!: string[];
|
||||||
|
|
||||||
private data() {
|
private data() {
|
||||||
|
const playerName =
|
||||||
|
"Guest-" +
|
||||||
|
Math.random()
|
||||||
|
.toString()
|
||||||
|
.slice(2, 8);
|
||||||
return {
|
return {
|
||||||
playerName:
|
playerName,
|
||||||
"Guest-" +
|
|
||||||
Math.random()
|
|
||||||
.toString()
|
|
||||||
.slice(2, 8),
|
|
||||||
busy: false,
|
|
||||||
hostMaxPlayers: 8,
|
hostMaxPlayers: 8,
|
||||||
hostPassword: "",
|
hostPassword: "",
|
||||||
joinSessionID: ""
|
joinSessionID: "",
|
||||||
|
wantedName: playerName
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,7 +279,7 @@ export default class Lobby extends Vue {
|
||||||
}
|
}
|
||||||
|
|
||||||
private async create() {
|
private async create() {
|
||||||
this.busy = true;
|
this.wantedName = this.playerName;
|
||||||
this.startServer({
|
this.startServer({
|
||||||
playerInfo: {
|
playerInfo: {
|
||||||
name: this.playerName
|
name: this.playerName
|
||||||
|
@ -275,7 +292,7 @@ export default class Lobby extends Vue {
|
||||||
}
|
}
|
||||||
|
|
||||||
private async join() {
|
private async join() {
|
||||||
this.busy = true;
|
this.wantedName = this.playerName;
|
||||||
this.connect({
|
this.connect({
|
||||||
serverID: this.joinSessionID,
|
serverID: this.joinSessionID,
|
||||||
playerInfo: {
|
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 {
|
private get canJoin(): boolean {
|
||||||
return this.joinSessionID != "";
|
return this.joinSessionID != "";
|
||||||
}
|
}
|
||||||
|
@ -300,5 +325,9 @@ export default class Lobby extends Vue {
|
||||||
}
|
}
|
||||||
return `${location.origin}${subpath}/join/${this.sessionID}`;
|
return `${location.origin}${subpath}/join/${this.sessionID}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private get nameAvailable(): boolean {
|
||||||
|
return this.wantedName != "" && !this.players.includes(this.wantedName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
Loading…
Reference in a new issue