* create .env file for server configuration * render client version * automate env file * add prestart command * create server-props.json instead of using .env * automate master proto file Co-authored-by: Jeremy Letto <jeremy.letto@datasite.com>
143 lines
3.8 KiB
TypeScript
143 lines
3.8 KiB
TypeScript
import protobuf from 'protobufjs';
|
|
|
|
import { RoomEvents, SessionEvents } from '../events';
|
|
import { SessionPersistence } from '../persistence';
|
|
import { WebClient } from '../WebClient';
|
|
|
|
import ProtoFiles from '../../proto-files.json';
|
|
|
|
export interface ProtobufEvents {
|
|
[event: string]: Function;
|
|
}
|
|
|
|
export class ProtobufService {
|
|
static PB_FILE_DIR = `${process.env.PUBLIC_URL}/pb`;
|
|
|
|
public controller;
|
|
private cmdId = 0;
|
|
private pendingCommands: { [cmdId: string]: Function } = {};
|
|
|
|
private webClient: WebClient;
|
|
|
|
constructor(webClient: WebClient) {
|
|
this.webClient = webClient;
|
|
|
|
this.loadProtobufFiles();
|
|
}
|
|
|
|
public resetCommands() {
|
|
this.cmdId = 0;
|
|
this.pendingCommands = {};
|
|
}
|
|
|
|
public sendRoomCommand(roomId: number, roomCmd: number, callback?: Function) {
|
|
const cmd = this.controller.CommandContainer.create({
|
|
'roomId': roomId,
|
|
'roomCommand': [roomCmd]
|
|
});
|
|
|
|
this.sendCommand(cmd, raw => callback && callback(raw));
|
|
}
|
|
|
|
public sendSessionCommand(sesCmd: number, callback?: Function) {
|
|
const cmd = this.controller.CommandContainer.create({
|
|
'sessionCommand': [sesCmd]
|
|
});
|
|
|
|
this.sendCommand(cmd, (raw) => callback && callback(raw));
|
|
}
|
|
|
|
public sendModeratorCommand(modCmd: number, callback?: Function) {
|
|
const cmd = this.controller.CommandContainer.create({
|
|
'moderatorCommand': [modCmd]
|
|
});
|
|
|
|
this.sendCommand(cmd, (raw) => callback && callback(raw));
|
|
}
|
|
|
|
public sendCommand(cmd: number, callback: Function) {
|
|
this.cmdId++;
|
|
|
|
cmd['cmdId'] = this.cmdId;
|
|
this.pendingCommands[this.cmdId] = callback;
|
|
|
|
if (this.webClient.socket.checkReadyState(WebSocket.OPEN)) {
|
|
this.webClient.socket.send(this.controller.CommandContainer.encode(cmd).finish());
|
|
}
|
|
}
|
|
|
|
public sendKeepAliveCommand(pingReceived: Function) {
|
|
const command = this.controller.SessionCommand.create({
|
|
'.Command_Ping.ext': this.controller.Command_Ping.create()
|
|
});
|
|
|
|
this.sendSessionCommand(command, pingReceived);
|
|
}
|
|
|
|
public handleMessageEvent({ data }: MessageEvent): void {
|
|
try {
|
|
const uint8msg = new Uint8Array(data);
|
|
const msg = this.controller.ServerMessage.decode(uint8msg);
|
|
|
|
if (msg) {
|
|
switch (msg.messageType) {
|
|
case this.controller.ServerMessage.MessageType.RESPONSE:
|
|
this.processServerResponse(msg.response);
|
|
break;
|
|
case this.controller.ServerMessage.MessageType.ROOM_EVENT:
|
|
this.processRoomEvent(msg.roomEvent, msg);
|
|
break;
|
|
case this.controller.ServerMessage.MessageType.SESSION_EVENT:
|
|
this.processSessionEvent(msg.sessionEvent, msg);
|
|
break;
|
|
case this.controller.ServerMessage.MessageType.GAME_EVENT_CONTAINER:
|
|
// @TODO
|
|
break;
|
|
}
|
|
}
|
|
} catch (err) {
|
|
console.error('Processing failed:', err);
|
|
}
|
|
}
|
|
|
|
private processServerResponse(response: any) {
|
|
const { cmdId } = response;
|
|
|
|
if (this.pendingCommands[cmdId]) {
|
|
this.pendingCommands[cmdId](response);
|
|
delete this.pendingCommands[cmdId];
|
|
}
|
|
}
|
|
|
|
private processRoomEvent(response: any, raw: any) {
|
|
this.processEvent(response, RoomEvents, raw);
|
|
}
|
|
|
|
private processSessionEvent(response: any, raw: any) {
|
|
this.processEvent(response, SessionEvents, raw);
|
|
}
|
|
|
|
private processEvent(response: any, events: ProtobufEvents, raw: any) {
|
|
for (const event in events) {
|
|
const payload = response[event];
|
|
|
|
if (payload) {
|
|
events[event](payload, raw);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
private loadProtobufFiles() {
|
|
const files = ProtoFiles.map(file => `${ProtobufService.PB_FILE_DIR}/${file}`);
|
|
|
|
this.controller = new protobuf.Root();
|
|
this.controller.load(files, { keepCase: false }, (err, root) => {
|
|
if (err) {
|
|
throw err;
|
|
}
|
|
|
|
SessionPersistence.initialized();
|
|
});
|
|
}
|
|
}
|