diff options
Diffstat (limited to 'client.js')
-rwxr-xr-x | client.js | 210 |
1 files changed, 178 insertions, 32 deletions
@@ -21,47 +21,193 @@ function fatalError(err) { process.exit(1); } -function showMenu(title, options) { - return new Promise(async (resolve, reject) => { - console.log(title); - for (let i = 0; i < options.length; i++) { - console.log(" " + (i + 1) + ") " + options[i]); - } - while (true) { - const line = await keyboard.prompt("> "); - const num = parseInt(line.trim(), 10); - if (num >= 1 && num <= options.length) { - resolve(num - 1); - break; - } - console.log( - "That's an invalid choice. " + - "Please enter a number between 1 and " + options.length + "."); +function playerToString(player) { + return player.nick; +} + +function roomToString(room) { + let res = ` '${room.name}' (${room.id})`; + if (room.hidden) res += " (HIDDEN)"; + res += "\n"; + res += " Players:"; + for (const player of room.players) { + if (player.nick == room.admin) res += "\x1B[4m"; + res += " " + playerToString(player); + if (player.nick == room.admin) res += "\x1B[0m"; + } + return res; +} + +async function showMenu(title, options) { + console.log(title); + for (let i = 0; i < options.length; i++) { + console.log(" " + (i + 1) + ") " + options[i]); + } + while (true) { + const line = await keyboard.prompt("> "); + const num = parseInt(line.trim(), 10); + if (num >= 1 && num <= options.length) { + return num - 1; + break; } - }); + console.log( + "That's an invalid choice. " + + "Please enter a number between 1 and " + options.length + "."); + } } function messageHandler(msg) { + console.log("ATTENTION: UNHANDLED INCOMING MESSAGE"); console.log("Message: " + util.inspect(msg)); } + +let currentRoom = null; +let currentGame = null; + + +// Returns: 0 for re-loop, 1 for quit, 2 for roomMenu +async function mainMenu() { + const title = "Main Menu"; + const options = [ + "Create a room", + "Join an existing room", + "Search for rooms", + ]; + + switch (await showMenu(title, options)) { + case 0: { + const roomName = await keyboard.prompt("Room name to make: "); + const shown = await showMenu("Should the room be shown in searches?", ["Yes", "No"]) == 0; + const reply = await conn.send(new protocol.Message("make-room", roomName, !shown, {})); + if (reply.err) { + console.log("Error: " + reply.err); + } else { + currentRoom = reply.res; + return 2; + } + break; + } + + case 1: { + const roomName = await keyboard.prompt("Room id to join: "); + const reply = await conn.send(new protocol.Message("join-room", roomName)); + if (reply.err) { + console.log("Error: " + reply.err); + } else { + currentRoom = reply.res; + return 2; + } + break; + } + + case 2: { + const query = await keyboard.prompt("String to search for: "); + const reply = await conn.send(new protocol.Message("search-rooms", query)); + if (reply.err) { + console.log("Error: " + reply.err); + } else { + console.log(reply.res.length + " results:"); + for (const room of reply.res) { + console.log(roomToString(room)); + } + } + break; + } + } + return 0; +} + +// Returns: 0 for re-loop, 1 for quit, 2 for mainMenu, 3 for gameMenu +async function roomMenu() { + const title = + "Room " + currentRoom.name + + " (" + currentRoom.players.map(p => p.nick).join(", ") + ")"; + const options = [ + "Start a game", + "Send room chat message", + "Invite a player into this room", + "Kick a player from the room", + "Leave the room", + ]; + + switch (await showMenu(title, options)) { + case 0: { + break; + } + + case 1: { + const line = await keyboard.prompt("Message to send: "); + const reply = await conn.send(new protocol.Message("send-room-chat", line)); + if (reply.err) fatalError(reply.err); + break; + } + + case 2: { + break; + } + + case 3: { + const name = await keyboard.prompt("Player name: "); + const reply = await conn.send(new protocol.Message("kick-player", name)); + if (reply.err) { + console.log(err); + } else { + console.log("Player successfully kicked."); + } + break; + } + + case 4: { + const reply = await conn.send(new protocol.Message("leave-room")); + if (reply.err) fatalError(reply.err); + return 2; + } + } +} + const conn = new protocol.Connection(net.createConnection(+process.argv[3], process.argv[2]), messageHandler); conn.conn.on("connect", async () => { - console.log("Connected to Doomrooms."); - let choice = await showMenu("Register or log in?", ["Register new account", "Log in to existing account"]) - const username = await keyboard.prompt("Username: "); - const password = await keyboard.prompt("Password: "); - let msg; - if (choice == 0) { - msg = await conn.send(new protocol.Message("make-player", username, password)); - } else { - msg = await conn.send(new protocol.Message("login", username, password)); - } - if (msg.err) fatalError(msg.err); - console.log(msg); + try { + console.log("Connected to Doomrooms."); + let choice = await showMenu("Register or log in?", [ + "Register new account", + "Log in to existing account", + "Quit", + ]); + if (choice == 2) process.exit(0); - msg = await conn.send(new protocol.Message("set-game", GAME_ID)); - if (msg.err) fatalError(msg.err); + const username = await keyboard.prompt("Username: "); + const password = await keyboard.promptPassword("Password: "); + let msg; + if (choice == 0) { + msg = await conn.send(new protocol.Message("make-player", username, password)); + } else { + msg = await conn.send(new protocol.Message("login", username, password)); + } + if (msg.err) fatalError(msg.err); + + msg = await conn.send(new protocol.Message("set-game", GAME_ID)); + if (msg.err) fatalError(msg.err); - setTimeout(() => {process.exit(0);}, 2000); + let inGame = false; + let doQuit = false; + while (!doQuit) { + if (inGame) { + switch (await roomMenu()) { + case 0: break; + case 1: doQuit = true; break; + case 2: inGame = false; break; + } + } else { + switch (await mainMenu()) { + case 0: break; + case 1: doQuit = true; break; + case 2: inGame = true; break; + } + } + } + } catch(e) { + console.log(e); + } }); |