Refactor state to share player info
This commit is contained in:
parent
9969561af1
commit
3414fbe46b
7 changed files with 60 additions and 30 deletions
|
@ -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(
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in a new issue