shoehive
Version:
WebSocket-based multiplayer game framework for real-time, event-driven gameplay
191 lines (190 loc) • 7.4 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MessageRouter = void 0;
const index_1 = require("../core/commands/index");
class MessageRouter {
constructor(eventBus) {
this.eventBus = eventBus;
this.commandHandlers = new Map();
// Register built-in command handlers
this.registerStateCommandHandlers();
this.registerLobbyCommandHandlers();
this.registerTableCommandHandlers();
}
/**
* Register a command handler for a specific action. For example, if you
* want a user to be able to make a choice, you could register `game:choice:make`
* and then handle it in your game logic.
* @param action - The action to register the handler for
* @param handler - The handler function to be called when the action is received
*/
registerCommandHandler(action, handler) {
this.commandHandlers.set(action, handler);
}
/**
* Register handlers for state request commands
*/
registerStateCommandHandlers() {
// Player state
this.registerCommandHandler(index_1.CLIENT_COMMAND_TYPES.PLAYER.GET_STATE, (player, data) => {
player.sendMessage({
type: index_1.CLIENT_MESSAGE_TYPES.PLAYER.STATE,
data: {
id: player.id,
attributes: player.getAttributes()
}
});
});
// Table state
this.registerCommandHandler(index_1.CLIENT_COMMAND_TYPES.TABLE.GET_STATE, (player, data) => {
const table = player.getTable();
if (table) {
player.sendMessage({
type: index_1.CLIENT_MESSAGE_TYPES.TABLE.STATE,
data: table.getTableState()
});
}
else {
player.sendMessage({
type: index_1.CLIENT_MESSAGE_TYPES.ERROR,
message: "You are not at a table"
});
}
});
// Lobby state
this.registerCommandHandler(index_1.CLIENT_COMMAND_TYPES.LOBBY.GET_STATE, (player, data) => {
this.eventBus.emit('request:lobby:state', player);
});
}
/**
* Register handlers for lobby commands
*/
registerLobbyCommandHandlers() {
// Join table
this.registerCommandHandler(index_1.CLIENT_COMMAND_TYPES.LOBBY.JOIN_TABLE, (player, data) => {
if (!data.tableId) {
player.sendMessage({
type: index_1.CLIENT_MESSAGE_TYPES.ERROR,
message: "Missing tableId parameter"
});
return;
}
this.eventBus.emit('request:table:join', player, data.tableId);
});
// Create table
this.registerCommandHandler(index_1.CLIENT_COMMAND_TYPES.LOBBY.CREATE_TABLE, (player, data) => {
if (!data.gameId) {
player.sendMessage({
type: index_1.CLIENT_MESSAGE_TYPES.ERROR,
message: "Missing gameId parameter"
});
return;
}
this.eventBus.emit('request:table:create', player, data.gameId, data.options);
});
}
/**
* Register handlers for table commands
*/
registerTableCommandHandlers() {
// Join table
this.registerCommandHandler(index_1.CLIENT_COMMAND_TYPES.TABLE.JOIN, (player, data) => {
if (!data.tableId) {
player.sendMessage({
type: index_1.CLIENT_MESSAGE_TYPES.ERROR,
message: "Missing tableId parameter"
});
return;
}
this.eventBus.emit('request:table:join', player, data.tableId);
});
// Leave table
this.registerCommandHandler(index_1.CLIENT_COMMAND_TYPES.TABLE.LEAVE, (player, data) => {
const table = player.getTable();
if (!table) {
player.sendMessage({
type: index_1.CLIENT_MESSAGE_TYPES.ERROR,
message: "You are not at a table"
});
return;
}
this.eventBus.emit('request:table:leave', player, table.id);
});
// Create table
this.registerCommandHandler(index_1.CLIENT_COMMAND_TYPES.TABLE.CREATE, (player, data) => {
if (!data.gameId) {
player.sendMessage({
type: index_1.CLIENT_MESSAGE_TYPES.ERROR,
message: "Missing gameId parameter"
});
return;
}
this.eventBus.emit('request:table:create', player, data.gameId, data.options);
});
// Sit at seat
this.registerCommandHandler(index_1.CLIENT_COMMAND_TYPES.TABLE.SEAT_SIT, (player, data) => {
const table = player.getTable();
if (!table) {
player.sendMessage({
type: index_1.CLIENT_MESSAGE_TYPES.ERROR,
message: "You are not at a table"
});
return;
}
if (data.seatIndex === undefined || data.seatIndex === null) {
player.sendMessage({
type: index_1.CLIENT_MESSAGE_TYPES.ERROR,
message: "Missing seatIndex parameter"
});
return;
}
this.eventBus.emit('request:table:seat:sit', player, table.id, data.seatIndex);
});
// Stand from seat
this.registerCommandHandler(index_1.CLIENT_COMMAND_TYPES.TABLE.SEAT_STAND, (player, data) => {
const table = player.getTable();
if (!table) {
player.sendMessage({
type: index_1.CLIENT_MESSAGE_TYPES.ERROR,
message: "You are not at a table"
});
return;
}
this.eventBus.emit('request:table:seat:stand', player, table.id);
});
}
/**
* Process a message from the client.
* @param player - The player object
* @param messageStr - The message string to process
*/
processMessage(player, messageStr) {
try {
const message = JSON.parse(messageStr);
// Validate message format
if (!message.action || typeof message.action !== "string") {
player.sendMessage({
type: index_1.CLIENT_MESSAGE_TYPES.ERROR,
message: "Invalid message format: missing or invalid action"
});
return;
}
// First check if we have a registered command handler for this action
const handler = this.commandHandlers.get(message.action);
if (handler) {
handler(player, message);
return;
}
// Otherwise, treat it as an event
this.eventBus.emit(message.action, player, message);
}
catch (error) {
console.error("Error processing message:", error);
player.sendMessage({
type: index_1.CLIENT_MESSAGE_TYPES.ERROR,
message: "Failed to process message"
});
}
}
}
exports.MessageRouter = MessageRouter;