diff --git a/cmds.lua b/cmds.lua new file mode 100644 index 0000000..f140374 --- /dev/null +++ b/cmds.lua @@ -0,0 +1,273 @@ +local tk = require("tracking") +local ch = require("chat") +local cfg = require("cfg") + +local cmds = {} + +local function q(v) + return tostring(v or "??") +end + +cmds.loc = { + alias = { "locate", "location", "l", "where", "whereis", + "whereisplayer", "dox", "doxplayer", "doxplayerlocation", + "doxplayerloc", "doxplrloc", "doxplr", + "addressof", "find", "findplayer", "findplr" }, + desc = "locate a player", + args = { + { match = "player", desc = "target" } + }, + proc = function(unm, tg) + tk:refreshOne(tg) + local p = tk.plrs[tg] + if not p then + ch.send(unm, "couldn't locate target", "loc") + return + end + + ch.send(unm, ("user: %s xyz:[%s, %s, %s] dim=%s"):format(tg, q(p.x), q(p.y), q(p.z), q(p.dimension))) + end, +} + +cmds.rpt = { + alias = { "report", "r", "list", "listall", "whereall", "findall", "doxall" }, + desc = "show coordinate report", + args = {}, + proc = function(unm) + tk:refresh() + + local ins = table.insert + + local mparts = {} + ins(mparts, { text = "finished generating report!\n" }) + + for i, v in pairs(tk.plrs) do + local line = ("user: %s xyz:[%s, %s, %s] dim=%s"):format(i, q(v.x), q(v.y), q(v.z), q(v.dimension)) + + ins(mparts, { text = "\n[" }) + ins(mparts, { text = "s", color = "aqua" }) + ins(mparts, { text = "] " .. line }) + end + + ch.send(unm, mparts, "rpt") + end, +} + +cmds.dims = { + alias = { "dimensions" }, + desc = "show dimension report", + args = {}, + allowLimitedUser = true, + proc = function(unm) + tk:refresh() + + local ins = table.insert + + local mparts = {} + ins(mparts, { text = "finished generating dimension report!" }) + + for i, v in pairs(tk.plrs) do + local line = ("user: %s dim=%s"):format(i, q(v.dimension)) + + ins(mparts, { text = "\n[" }) + ins(mparts, { text = "s", color = "aqua" }) + ins(mparts, { text = "] " .. line }) + end + + ch.send(unm, mparts, "rpt") + end, +} + +cmds.sublog = { + alias = { "subscribelog", "logsub", "logsubscribe", "addlog", "log+" }, + desc = "subscribe to log", + args = {}, + proc = function(unm) + if cfg.users[unm].subscribeLog then + ch.send(unm, "you're already subscribed!", "users") + ch.reportLog("user " .. unm .. " tries log sub, but already there") + else + cfg.users[unm].subscribeLog = true + ch.reportLog("user " .. unm .. " subscribes to log") + end + end +} + +cmds.unsublog = { + alias = { "unsubscribelog", "logunsub", "logunsubscribe", + "dellog", "rmlog", "log-" }, + desc = "unsubscribe from log", + args = {}, + proc = function(unm) + if not cfg.users[unm].subscribeLog then + ch.send(unm, "you're already aren't subscribed!", "users") + ch.reportLog("user " .. unm .. " tries log unsub, but they weren't there") + else + cfg.users[unm].subscribeLog = false + ch.reportLog("user " .. unm .. " unsubscribes from log") + end + end +} + +cmds.allow = { + alias = { "wl" }, + desc = "add someone to skynet", + args = { + { match = "player", desc = "who" } + }, + proc = function(unm, tg) + if cfg.users[tg] ~= nil then + ch.send(unm, "They're already allowed!!", "users") + ch.reportLog("user " .. unm .. " tries to allow " .. tg .. ", but they already are") + else + cfg.users[tg] = {} + ch.reportLog("user " .. unm .. " allows " .. tg) + ch.send(tg, "You were added to skynet, welcome!! // try $help for list of commands", "users") + end + end, +} + +cmds.disallow = { + alias = { "unwl" }, + desc = "remove someone from skynet", + args = { + { match = "player", desc = "who" } + }, + proc = function(unm, tg) + if cfg.users[tg] == nil then + ch.send(unm, "That person is already disallowed", "users") + ch.reportLog("user " .. unm .. " tries to disallow " .. tg .. ", but they already are") + else + cfg.users[tg] = nil + ch.reportLog("user " .. unm .. " disallows " .. tg) + end + end, +} + +cmds.ping = { + alias = { "pong" }, + desc = "alive???", + args = {}, + allowLimitedUser = true, + proc = function(unm) + ch.send(unm, "Alive!!!!") + end, +} + +cmds.shutdown = { + alias = { "meltdown", "sd" }, + desc = "no more sky net turnitoff", + args = {}, + requireAdminPrivilege = true, + proc = function(unm) + ch.reportLog("system shutdown requested by " .. unm) + ch.userBc("Shutting down..") + return true + end, +} + +cmds.say = { + alias = {}, + desc = "send an unlabeled message to chat", + args = { + { match = "rest", desc = "what to say" } + }, + allowLimitedUser = true, + proc = function(unm, msg) + ch.say(msg) + end, +} + +cmds.sayas = { + alias = {}, + desc = "say a message as another person", + args = { + { match = "block", desc = "who says" }, + { match = "rest", desc = "what do they say" } + }, + allowLimitedUser = true, + proc = function(unm, who, what) + ch.sayas(who, what) + end, +} + +cmds.sayserver = { + alias = { "saysrv" }, + desc = "say a message as server", + args = { + { match = "rest", desc = "what it will say" } + }, + allowLimitedUser = true, + proc = function(unm, what) + ch.sayserver(what) + end, +} + +cmds.faketpa = { + alias = { "ftpa" }, + desc = "send a fake teleport request", + args = { + { match = "player", desc = "to who" }, + { match = "block", desc = "from who fake" }, + { match = "block", desc = "from who carrier" }, + { match = "block", desc = "carrier says what" }, + }, + allowLimitedUser = true, + proc = function(unm, tgt, fromwho, carrierwho, carrierwhat) + ch.faketpa(tgt, fromwho, carrierwho, carrierwhat) + end, +} + +cmds.help = { + alias = {}, + desc = "help with how to use", + args = { + { match = "number", desc = "page", optional = true } + }, + allowLimitedUser = true, + proc = function(unm, page) + page = (page or 1) - 1 + + local ins = table.insert + + local cmdnames = {} + for i, _ in next, cmds do + table.insert(cmdnames, i) + end + table.sort(cmdnames) + + local eachpage = 8 + local start = page * eachpage + 1 + local stop = (page + 1) * eachpage + if start > #cmdnames then + start = #cmdnames - eachpage + 1 + end + stop = math.min(stop, #cmdnames) + + cmdnames = { table.unpack(cmdnames, start, stop) } + + local mparts = {} + ins(mparts, { text = ("help for %d commands (%d-%d) //"):format(#cmdnames, start, stop) }) + + for _, name in next, cmdnames do + local cmd = cmds[name] + local line = "$" .. name + for _, arg in next, cmd.args do + local br1, br2 = "<", ">" + if arg.optional then + br1, br2 = "[", "]" + end + line = line .. " " .. br1 .. arg.desc .. br2 + end + line = line .. " - " .. cmd.desc + + ins(mparts, { text = "\n[" }) + ins(mparts, { text = "s", color = "aqua" }) + ins(mparts, { text = "] " .. line }) + end + + ch.send(unm, mparts) + end, +} + +return cmds diff --git a/index.lua b/index.lua index 7b075bb..a9bd31e 100644 --- a/index.lua +++ b/index.lua @@ -6,200 +6,30 @@ local cfg = require("cfg") local ch = require("chat") local tk = require("tracking") +local cmds = require("cmds") --#endregion --#region Machine Preparation settings.set("shell.allow_disk_startup", false) --#endregion -local function q(v) - return tostring(v or "??") +local function nextWord(str) + local first, last + + if str:sub(1, 1) == "[" then + str = str:sub(2) + first, last = str:find("[^]]+") + else + first, last = str:find("%S+") + end + + if not last then + return str, nil + end + + return str:sub(last + 2), str:sub(first, last) end -local cmds = { - loc = function(unm, args) - local tg = tk:resTg(args[1]) - if not tg then - ch.send(unm, "missing target!", "loc") - return - end - - tk:refreshOne(tg) - local p = tk.plrs[tg] - if not p then - ch.send(unm, "couldn't locate target", "loc") - return - end - - ch.send(unm, string.format("user: %s xyz:[%s, %s, %s] dim=%s", tg, q(p.x), q(p.y), q(p.z), q(p.dimension))) - end, - rpt = function(unm, args) - tk:refresh() - - local ins = table.insert - - local mparts = {} - ins(mparts, { text = "finished generating report!\n" }) - - local n, nplrs = 0, 0 - for _, _ in next, tk.plrs do nplrs = nplrs + 1 end - for i, v in pairs(tk.plrs) do - local line = string.format("user: %s xyz:[%s, %s, %s] dim=%s", i, q(v.x), q(v.y), q(v.z), q(v.dimension)) - n = n + 1 - if n ~= nplrs then - line = line .. "\n" - end - - ins(mparts, { text = "[" }) - ins(mparts, { text = "s", color = "aqua" }) - ins(mparts, { text = "] " .. line }) - end - - ch.send(unm, mparts, "rpt") - end, - dims = function(unm, args) - tk:refresh() - - local ins = table.insert - - local mparts = {} - ins(mparts, { text = "finished generating dimension report!\n" }) - - local n, nplrs = 0, 0 - for _, _ in next, tk.plrs do nplrs = nplrs + 1 end - for i, v in pairs(tk.plrs) do - local line = string.format("user: %s dim=%s", i, q(v.dimension)) - n = n + 1 - if n ~= nplrs then - line = line .. "\n" - end - - ins(mparts, { text = "[" }) - ins(mparts, { text = "s", color = "aqua" }) - ins(mparts, { text = "] " .. line }) - end - - ch.send(unm, mparts, "rpt") - end, - unsublog = function(unm, args) - if not cfg.users[unm].subscribeLog then - ch.send(unm, "you're already aren't subscribed!", "users") - ch.reportLog("user " .. unm .. " tries log unsub, but they weren't there") - else - cfg.users[unm].subscribeLog = false - ch.reportLog("user " .. unm .. " unsubscribes from log") - end - end, - sublog = function(unm, args) - if cfg.users[unm].subscribeLog then - ch.send(unm, "you're already subscribed!", "users") - ch.reportLog("user " .. unm .. " tries log sub, but already there") - else - cfg.users[unm].subscribeLog = true - ch.reportLog("user " .. unm .. " subscribes to log") - end - end, - allow = function(unm, args) - local tg = tk:resTg(args[1]) - if not tg then - ch.send(unm, "No user was specified!", "users") - return - end - - if cfg.users[tg] ~= nil then - ch.send(unm, "They're already allowed!!", "users") - ch.reportLog("user " .. unm .. " tries to allow " .. tg .. ", but they already are") - else - cfg.users[tg] = {} - ch.reportLog("user " .. unm .. " allows " .. tg) - ch.send(tg, "You were added to skynet, welcome!! // try $help for list of commands", "users") - end - end, - disallow = function(unm, args) - local tg = tk:resTg(args[1]) - if not tg then - ch.send(unm, "No user was specified!", "users") - return - end - if cfg.users[tg] == nil then - ch.send(unm, "That person is already disallowed", "users") - ch.reportLog("user " .. unm .. " tries to disallow " .. tg .. ", but they already are") - else - cfg.users[tg] = nil - ch.reportLog("user " .. unm .. " disallows " .. tg) - end - end, - ping = function(unm, args) - ch.send(unm, "Alive!!!!") - end, - shutdown = function(unm, args) - if cfg.users[unm].admin then - ch.reportLog("system shutdown requested by " .. unm) - ch.userBc("Shutting down..") - return true - else - ch.reportLog("non-admin user " .. unm .. " attempted to shutdown") - ch.send(unm, "no permission to do that..", "cmd") - end - end, - say = function(unm, args) - local msg = table.concat(args, " ") - - ch.say(msg) - end, - sayas = function(unm, args) - local plr = table.remove(args, 1) - local msg = table.concat(args, " ") - - if not plr or #msg == 0 then - ch.send(unm, "must specify player and message") - return - end - - ch.sayas(plr, msg) - end, - sayserver = function(unm, args) - local msg = table.concat(args, " ") - - if #msg == 0 then - ch.send(unm, "no message was given") - return - end - - ch.sayserver(msg) - end, - faketpa = function(unm, args) - local tgtplr = table.remove(args, 1) - local sender = table.remove(args, 1) - local fakeplr = table.remove(args, 1) - local fakemsg = table.concat(args, " ") - - if not tgtplr then - ch.send(unm, "no target player specified", "cmd") - return - end - if not sender then - ch.send(unm, "no sender name specified", "cmd") - return - end - if not fakeplr then - ch.send(unm, "no fake player specified", "cmd") - return - end - - tgtplr = tk:resTg(tgtplr) - if not tgtplr then - ch.send(unm, "target player specified not found", "cmd") - return - end - - ch.faketpa(tgtplr, sender, fakeplr, fakemsg) - end, - help = function(unm, args) - ch.send(unm, "not added yet sry") - end, -} - local function processMessage(unm, msg, hidden) if not hidden and msg:sub(1, #cfg.prefix) ~= cfg.prefix then return end @@ -207,13 +37,8 @@ local function processMessage(unm, msg, hidden) msg = msg:sub(#cfg.prefix + 1) end - local args = {} - - for arg in msg:gmatch("%S+") do - table.insert(args, arg) - end - - local cmd = table.remove(args, 1) + local cmd + msg, cmd = nextWord(msg) local user = cfg.users[unm] if user == nil then @@ -221,23 +46,86 @@ local function processMessage(unm, msg, hidden) return end - if user.limited and (cmd ~= "dims" and cmd ~= "faketpa" and cmd ~= "help" and cmd ~= "ping") then + local xcmd + for k, v in next, cmds do + if k == cmd then + xcmd = v + break + end + for _, a in next, v.alias do + if a == cmd then + xcmd = v + break + end + end + end + if not xcmd then + ch.reportLog("user " .. unm .. " tries invalid cmd: " .. cmd) + ch.send(unm, "not a valid command", "cmd") + return + end + + if user.limited and not xcmd.allowLimitedUser then ch.reportLog("limited user " .. unm .. " tries: " .. cmd) return end - local handler = cmds[cmd] - if handler then - ch.reportLog("user " .. unm .. " runs: " .. cmd) - local res = handler(unm, args) + if xcmd.requireAdminPrivilege and not user.admin then + ch.reportLog("non-admin user " .. unm .. " attempted to " .. cmd) + ch.send(unm, "no permission to do that..", "cmd") + return + end - if res then - -- command requested shutdown - return true + local args = {} + + for _, x in next, xcmd.args do + local arg + + if x.match == "block" then + msg, arg = nextWord(msg) + if not arg then + ch.send(unm, "missing arg: " .. x.desc, "cmd") + return + end + elseif x.match == "player" then + msg, arg = nextWord(msg) + if not arg then + ch.send(unm, "missing player arg: " .. x.desc, "cmd") + return + end + arg = tk:resTg(arg) + if not arg then + ch.send(unm, "target not found for: " .. x.desc, "cmd") + return + end + elseif x.match == "rest" then + arg = msg + msg = "" + elseif x.match == "number" then + msg, arg = nextWord(msg) + if not arg and x.optional then + arg = nil + else + arg = tonumber(arg) + if not arg then + ch.send(unm, "invalid number for: " .. x.desc, "cmd") + return + end + end + else + -- what?? + return true, error("invalid match type") end - else - ch.reportLog("user " .. unm .. " tries invalid cmd: " .. cmd) - ch.send(unm, "not a valid command", "cmd") + + table.insert(args, arg) + end + + ch.reportLog("user " .. unm .. " runs: " .. cmd) + local res = xcmd.proc(unm, table.unpack(args)) + + if res then + -- command requested shutdown + return true end end