Refactor state to share player info

This commit is contained in:
Hamcha 2019-10-22 20:11:32 +02:00
parent 9969561af1
commit 3414fbe46b
Signed by: hamcha
GPG Key ID: 44AD3571EB09A39E
7 changed files with 60 additions and 30 deletions

View File

@ -1,11 +1,11 @@
import EventEmitter from "eventemitter3"; import EventEmitter from "eventemitter3";
import Vue from "vue"; import Vue from "vue";
import { NetworkMessage, PasswordResponse, PeerMetadata, RoomInfo } from "./types"; import { NetworkMessage, PasswordResponse, PeerMetadata, RoomInfo, RoomPlayer } from "./types";
export abstract class Client extends EventEmitter { export abstract class Client extends EventEmitter {
public metadata: PeerMetadata; public metadata: PeerMetadata;
public players!: string[]; public players!: RoomPlayer[];
public roomInfo!: RoomInfo; public roomInfo!: RoomInfo;
public constructor(metadata: PeerMetadata) { public constructor(metadata: PeerMetadata) {
@ -15,6 +15,7 @@ export abstract class Client extends EventEmitter {
protected _received(data: NetworkMessage) { protected _received(data: NetworkMessage) {
this.emit("data", data); this.emit("data", data);
console.log(data);
switch (data.kind) { switch (data.kind) {
// Server is sending over player list and room info // Server is sending over player list and room info
case "room-info": case "room-info":
@ -33,13 +34,12 @@ export abstract class Client extends EventEmitter {
// This is because rename messages can be received during the initial // This is because rename messages can be received during the initial
// handshake, to signal a forced name change before joining. // handshake, to signal a forced name change before joining.
if (this.players) { if (this.players) {
let idx = this.players.indexOf(data.oldname); let idx = this.players.findIndex(player => player.name == data.oldname);
if (idx < 0) { if (idx < 0) {
// Weird // Weird
console.warn( console.error(
`Someone (${data.oldname}) changed name but wasn't on the player list` `Someone (${data.oldname}) changed name but wasn't on the player list`
); );
this.players.push(data.newname);
break; break;
} }
Vue.set(this.players, idx, data.newname); Vue.set(this.players, idx, data.newname);
@ -48,11 +48,11 @@ export abstract class Client extends EventEmitter {
break; break;
// A new player joined the room (this includes us) // A new player joined the room (this includes us)
case "player-joined": case "player-joined":
this.players.push(data.name); this.players.push(data.player);
this.emit("player-joined", data.name); this.emit("player-joined", data.player);
break; break;
case "player-left": { case "player-left": {
let idx = this.players.indexOf(data.name); let idx = this.players.findIndex(player => player.name == data.name);
if (idx < 0) { if (idx < 0) {
// Weird // Weird
console.warn( console.warn(

View File

@ -18,6 +18,7 @@ import {
Room, Room,
RoomInfo, RoomInfo,
RoomInfoMessage, RoomInfoMessage,
RoomPlayer,
} from "./types"; } from "./types";
// Increment name, add number at the end if not present // Increment name, add number at the end if not present
@ -56,6 +57,7 @@ export class PeerServer extends EventEmitter {
// Add local player to server // Add local player to server
players[local.name] = { players[local.name] = {
kind: "local", kind: "local",
ready: false,
name: local.name, name: local.name,
client: local client: local
}; };
@ -66,7 +68,7 @@ export class PeerServer extends EventEmitter {
players players
}; };
local.players = Object.keys(this.players); local.players = this.playerList;
local.roomInfo = this.room.info; local.roomInfo = this.room.info;
// Setup peer // Setup peer
@ -89,6 +91,7 @@ export class PeerServer extends EventEmitter {
let player: NetworkPlayer = { let player: NetworkPlayer = {
kind: "remote", kind: "remote",
name: metadata.name, name: metadata.name,
ready: false,
conn: conn conn: conn
}; };
@ -154,7 +157,7 @@ export class PeerServer extends EventEmitter {
// Hacky: Give player list before this player was added, so join // Hacky: Give player list before this player was added, so join
// message doesn't mess things up later // message doesn't mess things up later
const players = Object.keys(this.room.players); const players = this.playerList;
// Add player to room // Add player to room
this.room.players[playerName] = player; this.room.players[playerName] = player;
@ -182,7 +185,10 @@ export class PeerServer extends EventEmitter {
// Notify other players // Notify other players
this.broadcast<JoinMessage>({ this.broadcast<JoinMessage>({
kind: "player-joined", kind: "player-joined",
name: playerName player: {
name: player.name,
ready: player.ready
}
}); });
} }
@ -276,6 +282,13 @@ export class PeerServer extends EventEmitter {
public get id(): string { public get id(): string {
return this.peer.id; return this.peer.id;
} }
public get playerList(): RoomPlayer[] {
return Object.keys(this.room.players).map(playerName => ({
name: playerName,
ready: this.room.players[playerName].ready
}));
}
} }
export default PeerServer; export default PeerServer;

View File

@ -1,15 +1,19 @@
import { DataConnection } from "peerjs"; import { DataConnection } from "peerjs";
import LocalClient from "./LocalClient"; import LocalClient from "./LocalClient";
export interface LocalPlayer { export interface RoomPlayer {
kind: "local";
name: string; name: string;
ready: boolean;
}
export interface LocalPlayer extends RoomPlayer {
kind: "local";
client: LocalClient; client: LocalClient;
} }
export interface NetworkPlayer { export interface NetworkPlayer extends RoomPlayer {
kind: "remote"; kind: "remote";
name: string;
conn: DataConnection; conn: DataConnection;
} }
@ -70,7 +74,8 @@ export type NetworkMessage =
| LeaveMessage | LeaveMessage
| RenameMessage | RenameMessage
| ChatMessage | ChatMessage
| AckMessage; | AckMessage
| ReadyMessage;
export interface PasswordRequest { export interface PasswordRequest {
kind: "password-req"; kind: "password-req";
@ -84,7 +89,7 @@ export interface PasswordResponse {
export interface RoomInfoMessage { export interface RoomInfoMessage {
kind: "room-info"; kind: "room-info";
room: RoomInfo; room: RoomInfo;
players: string[]; players: RoomPlayer[];
} }
export interface LeaveRequest { export interface LeaveRequest {
@ -93,7 +98,7 @@ export interface LeaveRequest {
export interface JoinMessage { export interface JoinMessage {
kind: "player-joined"; kind: "player-joined";
name: string; player: RoomPlayer;
} }
export interface LeaveMessage { export interface LeaveMessage {
@ -123,3 +128,8 @@ export interface ErrorMessage {
kind: "error"; kind: "error";
error: string; error: string;
} }
export interface ReadyMessage {
kind: "ready";
ready: boolean;
}

View File

@ -1,4 +1,4 @@
import { Client } from "@/network"; import { Client, RoomPlayer } from "@/network";
import { GetterTree } from "vuex"; import { GetterTree } from "vuex";
import { AppState } from "../types"; import { AppState } from "../types";
@ -52,7 +52,7 @@ const getters: GetterTree<NetworkState, AppState> = {
return false; return false;
}, },
players(state): string[] { players(state): RoomPlayer[] {
return state.players; return state.players;
} }
}; };

View File

@ -1,4 +1,4 @@
import { ChatMessage, LocalClient, PeerClient, PeerServer } from "@/network"; import { ChatMessage, LocalClient, PeerClient, PeerServer, RoomPlayer } from "@/network";
import Vue from "vue"; import Vue from "vue";
import { MutationTree } from "vuex"; import { MutationTree } from "vuex";
@ -7,7 +7,7 @@ import { ClientNetworkState, ConnectionStatus, NetworkState, ServerNetworkState
const mutations: MutationTree<NetworkState> = { const mutations: MutationTree<NetworkState> = {
becomeServer(state, payload: { local: LocalClient; server: PeerServer }) { becomeServer(state, payload: { local: LocalClient; server: PeerServer }) {
state.peerType = "server"; state.peerType = "server";
state.players = [payload.local.name]; state.players = [{ name: payload.local.name, ready: true }];
(state as ServerNetworkState).local = payload.local; (state as ServerNetworkState).local = payload.local;
(state as ServerNetworkState).server = payload.server; (state as ServerNetworkState).server = payload.server;
}, },
@ -36,7 +36,7 @@ const mutations: MutationTree<NetworkState> = {
state.serverID = id; state.serverID = id;
}, },
playerListChanged(state, players: string[]) { playerListChanged(state, players: RoomPlayer[]) {
Vue.set(state, "players", players); Vue.set(state, "players", players);
} }
}; };

View File

@ -1,4 +1,4 @@
import { ChatMessage, LocalClient, PeerClient, PeerMetadata, PeerServer, RoomInfo } from "@/network"; import { ChatMessage, LocalClient, PeerClient, PeerMetadata, PeerServer, RoomInfo, RoomPlayer } from "@/network";
import Peer from "peerjs"; import Peer from "peerjs";
export type ConnectionStatus = export type ConnectionStatus =
@ -10,7 +10,7 @@ export type ConnectionStatus =
export interface SharedNetworkState { export interface SharedNetworkState {
chatLog: ChatMessage[]; chatLog: ChatMessage[];
serverID: string | null; serverID: string | null;
players: string[]; players: RoomPlayer[];
} }
export interface NoNetworkState extends SharedNetworkState { export interface NoNetworkState extends SharedNetworkState {

View File

@ -89,8 +89,8 @@
<section class="players"> <section class="players">
<header>Players</header> <header>Players</header>
<ul> <ul>
<li class="selectable" v-for="player in players" :key="player"> <li class="selectable" v-for="player in players" :key="player.name">
{{ player }} {{ player.name }}
</li> </li>
</ul> </ul>
</section> </section>
@ -258,7 +258,11 @@
<script lang="ts"> <script lang="ts">
import { Component, Vue } from "vue-property-decorator"; 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,
PlayerEntry
} from "@/store/network/types";
import { Action, Getter } from "vuex-class"; import { Action, Getter } from "vuex-class";
import { Client, NetworkMessage } from "@/network"; import { Client, NetworkMessage } from "@/network";
@ -295,7 +299,7 @@ export default class Lobby extends Vue {
private sessionID!: string | null; private sessionID!: string | null;
@Getter("players", networkNS) @Getter("players", networkNS)
private players!: string[]; private players!: PlayerEntry[];
private data() { private data() {
const playerName = const playerName =
@ -368,7 +372,10 @@ export default class Lobby extends Vue {
} }
private get nameAvailable(): boolean { private get nameAvailable(): boolean {
return this.wantedName != "" && !this.players.includes(this.wantedName); return (
this.wantedName != "" &&
!this.players.find(p => p.name == this.wantedName)
);
} }
} }
</script> </script>