Basic networking #9
3 changed files with 69 additions and 8 deletions
|
@ -1,9 +1,10 @@
|
||||||
import NetworkPeer from "./peer";
|
import NetworkPeer from "./peer";
|
||||||
import { DataConnection } from "peerjs";
|
import { DataConnection } from "peerjs";
|
||||||
|
import { PeerMetadata } from "./types";
|
||||||
|
|
||||||
export default class PeerClient extends NetworkPeer {
|
export default class PeerClient extends NetworkPeer {
|
||||||
private connection: DataConnection;
|
private connection: DataConnection;
|
||||||
public constructor(peerid: string, metadata: Object) {
|
public constructor(peerid: string, metadata: PeerMetadata) {
|
||||||
super();
|
super();
|
||||||
this.connection = this.peer.connect(peerid, {
|
this.connection = this.peer.connect(peerid, {
|
||||||
label: "server",
|
label: "server",
|
||||||
|
|
|
@ -5,11 +5,15 @@ import {
|
||||||
PasswordRequest,
|
PasswordRequest,
|
||||||
Room,
|
Room,
|
||||||
ErrorMessage,
|
ErrorMessage,
|
||||||
PasswordResponse
|
PasswordResponse,
|
||||||
|
PeerMetadata,
|
||||||
|
JoinMessage,
|
||||||
|
RoomInfoMessage
|
||||||
} from "./types";
|
} from "./types";
|
||||||
|
|
||||||
export default class PeerServer extends NetworkPeer {
|
export default class PeerServer extends NetworkPeer {
|
||||||
private room: Room;
|
private room: Room;
|
||||||
|
|
||||||
public constructor(roomInfo: RoomInfo) {
|
public constructor(roomInfo: RoomInfo) {
|
||||||
super();
|
super();
|
||||||
this.room = {
|
this.room = {
|
||||||
|
@ -18,13 +22,17 @@ export default class PeerServer extends NetworkPeer {
|
||||||
};
|
};
|
||||||
this.peer.on("connection", this._connection);
|
this.peer.on("connection", this._connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _connection(conn: DataConnection) {
|
private async _connection(conn: DataConnection) {
|
||||||
// Check if this connection should be allowed
|
// Check if this connection should be allowed
|
||||||
console.info("%s (%s) connected!", conn.metadata.name, conn.label);
|
console.info(
|
||||||
|
"%s (%s) connected!",
|
||||||
|
(conn.metadata as PeerMetadata).name,
|
||||||
|
conn.label
|
||||||
|
);
|
||||||
|
|
||||||
// Check if room is full
|
// Check if room is full
|
||||||
if (this.playerCount >= this.room.info.max_players) {
|
if (this.playerCount >= this.room.info.max_players) {
|
||||||
//TODO Reject
|
|
||||||
this.send<ErrorMessage>(conn, { kind: "error", error: "room is full" });
|
this.send<ErrorMessage>(conn, { kind: "error", error: "room is full" });
|
||||||
conn.close();
|
conn.close();
|
||||||
return;
|
return;
|
||||||
|
@ -33,9 +41,10 @@ export default class PeerServer extends NetworkPeer {
|
||||||
if (this.room.info.password != "") {
|
if (this.room.info.password != "") {
|
||||||
this.send<PasswordRequest>(conn, { kind: "password-req" });
|
this.send<PasswordRequest>(conn, { kind: "password-req" });
|
||||||
conn.on("data", this.checkPasswordResponse.bind(this, conn));
|
conn.on("data", this.checkPasswordResponse.bind(this, conn));
|
||||||
} else {
|
return;
|
||||||
//TODO Add player
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.addPlayer(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
private checkPasswordResponse(conn: DataConnection, data: any) {
|
private checkPasswordResponse(conn: DataConnection, data: any) {
|
||||||
|
@ -48,7 +57,7 @@ export default class PeerServer extends NetworkPeer {
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//TODO Add player
|
this.addPlayer(conn);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.send<ErrorMessage>(conn, {
|
this.send<ErrorMessage>(conn, {
|
||||||
kind: "error",
|
kind: "error",
|
||||||
|
@ -57,7 +66,38 @@ export default class PeerServer extends NetworkPeer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private addPlayer(conn: DataConnection) {
|
||||||
|
const playerName = conn.metadata.name;
|
||||||
|
this.room.players[playerName] = {
|
||||||
|
name: conn.metadata.name,
|
||||||
|
conn: conn
|
||||||
|
};
|
||||||
|
|
||||||
|
// Send the player info about the room
|
||||||
|
this.send<RoomInfoMessage>(conn, {
|
||||||
|
kind: "room-info",
|
||||||
|
room: {
|
||||||
|
...this.room.info,
|
||||||
|
password: ""
|
||||||
|
},
|
||||||
|
players: Object.keys(this.room.players)
|
||||||
|
});
|
||||||
|
|
||||||
|
// Notify other players
|
||||||
|
this.broadcast<JoinMessage>({
|
||||||
|
kind: "player-joined",
|
||||||
|
name: conn.metadata.name
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private get playerCount(): number {
|
private get playerCount(): number {
|
||||||
return Object.keys(this.room.players).length;
|
return Object.keys(this.room.players).length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private broadcast<T>(message: T) {
|
||||||
|
for (const playerName in this.room.players) {
|
||||||
|
const player = this.room.players[playerName];
|
||||||
|
this.send<T>(player.conn, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,10 @@ export interface NetworkPlayer {
|
||||||
conn: DataConnection;
|
conn: DataConnection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface PeerMetadata {
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface Room {
|
export interface Room {
|
||||||
info: RoomInfo;
|
info: RoomInfo;
|
||||||
players: Record<string, NetworkPlayer>;
|
players: Record<string, NetworkPlayer>;
|
||||||
|
@ -46,7 +50,12 @@ type DraftInfo = {
|
||||||
|
|
||||||
// Message schemas
|
// Message schemas
|
||||||
|
|
||||||
export type NetworkMessage = PasswordRequest | PasswordResponse | ErrorMessage;
|
export type NetworkMessage =
|
||||||
|
| PasswordRequest
|
||||||
|
| PasswordResponse
|
||||||
|
| ErrorMessage
|
||||||
|
| RoomInfoMessage
|
||||||
|
| JoinMessage;
|
||||||
|
|
||||||
export interface PasswordRequest {
|
export interface PasswordRequest {
|
||||||
kind: "password-req";
|
kind: "password-req";
|
||||||
|
@ -57,6 +66,17 @@ export interface PasswordResponse {
|
||||||
password: string;
|
password: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface RoomInfoMessage {
|
||||||
|
kind: "room-info";
|
||||||
|
room: RoomInfo;
|
||||||
|
players: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface JoinMessage {
|
||||||
|
kind: "player-joined";
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface ErrorMessage {
|
export interface ErrorMessage {
|
||||||
kind: "error";
|
kind: "error";
|
||||||
error: string;
|
error: string;
|
||||||
|
|
Loading…
Reference in a new issue