From f77d4db6dccba311a9fbcf61256993a640a61f13 Mon Sep 17 00:00:00 2001 From: szdytom Date: Thu, 25 Mar 2021 14:31:54 +0800 Subject: [PATCH] [feature] new commands --- public/script.js | 7 +--- src/command.ts | 101 ++++++++++++++++++++++++++++++++++++----------- src/user.ts | 3 ++ 3 files changed, 83 insertions(+), 28 deletions(-) diff --git a/public/script.js b/public/script.js index 989ea6b..8635f3f 100644 --- a/public/script.js +++ b/public/script.js @@ -100,12 +100,7 @@ function init() { ws.emit('set-name', username); }); - ws.on('system-message', evt => { - let msg; - if (evt.type === 'join-room') { - msg = `${evt.data.user} joined room ${evt.data.room}.`; - } - + ws.on('system-message', msg => { write_message({ type: 'system-message', msg: msg, diff --git a/src/command.ts b/src/command.ts index 70f4228..2ffb141 100644 --- a/src/command.ts +++ b/src/command.ts @@ -6,10 +6,6 @@ export function is_command(cmd: string) { return cmd.startsWith('/'); }; -function command_reply(msg: string, socket: Socket) { - socket.emit('command-block-reply', msg); -} - function mask_room_name(name: string) { if (name === 'global') { return name; @@ -29,7 +25,9 @@ function unmask_room_name(name: string) { return null; } -export function run_command(cmd: string, uid: string, users: Map, io: SocketServer, silent: boolean = false) { +export function run_command(cmd_raw: string, uid: string, users: Map, io: SocketServer, silent: boolean = false) { + const cmd = cmd_raw.replace(/(^\s*)|(\s*$)/, ''); + if (!is_command(cmd)) { return; } const user = users.get(uid); @@ -39,6 +37,28 @@ export function run_command(cmd: string, uid: string, users: Map, socket.emit('command-block-reply', msg); }; + const system_reply = (msg: string, socket: Socket) => { + socket.emit('system-message', msg); + }; + + const request_administrator_access = () => { + if (user.is_administrator) { return true; } + + command_reply('You must be an administrator to run this command.'); + return false; + }; + + const safe_find_user = (filter_string: string) => { + let res: string[]; + try { + res = find_user(filter_string, users, uid); + } catch (err) { + res = []; + } + + return res; + }; + const cmd_set = cmd.split(/\s+/); if (cmd.startsWith('/disconnect')) { @@ -57,17 +77,25 @@ export function run_command(cmd: string, uid: string, users: Map, } if (cmd.startsWith('/ls')) { - if (cmd_set[1] === 'own') { - command_reply(JSON.stringify( - Array - .from(socket.rooms) - .map(x => unmask_room_name(x)) - .filter(x => x !== null) - )); + if (cmd === '/ls') { + command_reply(JSON.stringify(all_rooms())); + return; + } + + const filter_string = cmd.substring('/ls'.length); + const target = safe_find_user(filter_string)[0]; + + if (target === undefined) { + command_reply('Target user not found.'); return; } - command_reply(JSON.stringify(all_rooms())); + command_reply(JSON.stringify( + Array + .from(users.get(target).socket.rooms) + .map(x => unmask_room_name(x)) + .filter(x => x !== null) + )); return; } @@ -94,19 +122,28 @@ export function run_command(cmd: string, uid: string, users: Map, } if (cmd.startsWith('/ps')) { - let result = '['; - users.forEach(user => { - result += `"${user.name}",`; - }); - result = result.substring(0, result.length - 1) + ']'; - command_reply(result); + if (cmd === '/ps') { + command_reply(JSON.stringify(Array + .from(users) + .map(x => x[1].name) + )); + return; + } + + const filter_string = cmd.substring('/ps'.length); + const checked_user = safe_find_user(filter_string); + command_reply(JSON.stringify(Array + .from(users) + .filter(([id,]) => checked_user.includes(id)) + .map(x => x[1].name) + )); return; } if (cmd.startsWith('/su')) { const code = cmd_set[1]; - grant_access(user, code); - command_reply('You are administartor now.'); + if (grant_access(user, code)) { command_reply('You are administartor now.'); } + else { command_reply('Code incorrect.'); } return; } @@ -118,7 +155,27 @@ export function run_command(cmd: string, uid: string, users: Map, if (cmd.startsWith('/filter')) { const filter_string = cmd.substring('/filter'.length); - command_reply(JSON.stringify(find_user(filter_string, users, uid))); + command_reply(JSON.stringify(safe_find_user(filter_string))); return; } + + if (cmd.startsWith('/whois')) { + const id = cmd_set[1]; + command_reply(users.get(id).name); + return; + } + + if (cmd.startsWith('/kill')) { + if (!request_administrator_access()) { return; } + + const filter_string = cmd.substring('/kill'.length); + const checked_user = safe_find_user(filter_string); + for (let id of checked_user) { + const target = users.get(id).socket; + system_reply('Your are killed.', target); + target.disconnect(); + } + + command_reply(JSON.stringify(checked_user)); + } }; diff --git a/src/user.ts b/src/user.ts index 10fdcee..5425e9b 100644 --- a/src/user.ts +++ b/src/user.ts @@ -114,6 +114,7 @@ export function find_user(filter_string_raw: string, users: Map, o if (/^\@R\([^\&]*\)\&\(.*\)$/.test(filter_string)) { const [, regex_filter, sub_filter] = filter_string.match(/^\@R\(([^\&]*)\)\&\((.*)\)$/); const target_regex = new RegExp(regex_filter); + const sub_res = parse_lower(sub_filter); return sub_res .map(id => [users.get(id).name, id]) @@ -157,6 +158,8 @@ refreash_admin_passcode(); export function grant_access(user: User, code: string) { if (admin_passcode === code) { user.is_administrator = true; + return true; } + return false; };