diff options
Diffstat (limited to 'network.lua')
-rw-r--r-- | network.lua | 310 |
1 files changed, 0 insertions, 310 deletions
diff --git a/network.lua b/network.lua deleted file mode 100644 index 84cb712..0000000 --- a/network.lua +++ /dev/null @@ -1,310 +0,0 @@ ---[[ - -Network protocol file for HaxServ. - -Written by: Test_User <hax@andrewyu.org> - -This is free and unencumbered software released into the public -domain. - -Anyone is free to copy, modify, publish, use, compile, sell, or -distribute this software, either in source code form or as a compiled -binary, for any purpose, commercial or non-commercial, and by any -means. - -In jurisdictions that recognize copyright laws, the author or authors -of this software dedicate any and all copyright interest in the -software to the public domain. We make this dedication for the benefit -of the public at large and to the detriment of our heirs and -successors. We intend this dedication to be an overt act of -relinquishment in perpetuity of all present and future rights to this -software under copyright law. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. -]] - -local function mode_snomask(current, mode, dir, arg) - if dir == "+" then - current[mode] = current[mode] or {} - parse_modes(arg, {}, {}, current[mode]) - if not next(current[mode]) then - current[mode] = nil - end - return true - else - current[mode] = nil - end -end - -local function mode_replace(current, mode, dir, arg) - if dir == "+" then - current[mode] = arg - return true - else - current[mode] = nil - end -end - -local function mode_multi(current, mode, dir, arg) - if dir == "+" then - current[mode] = current[mode] or {} - current[mode][arg] = true - else - if current[mode] == nil then - print("Invalid mode change attempt!\n") - current[mode] = {} - end - current[mode][arg] = nil - if next(current[mode]) == nil then - current[mode] = nil - end - end - return true -end - -local usermodes = { - ["s"] = mode_snomask, -} - -local chanmodes = { - ["l"] = mode_replace, - ["L"] = mode_replace, - ["v"] = mode_multi, - ["o"] = mode_multi, - ["h"] = mode_multi, - ["a"] = mode_multi, - ["q"] = mode_multi, - ["Y"] = mode_multi, - ["d"] = mode_replace, - ["f"] = mode_replace, - ["g"] = mode_multi, - ["b"] = mode_multi, - ["e"] = mode_multi, - ["I"] = mode_multi, - ["k"] = mode_replace, - ["w"] = mode_multi, - ["E"] = mode_replace, - ["F"] = mode_replace, - ["H"] = mode_replace, - ["J"] = mode_replace, - ["X"] = mode_multi, -} - -local function parse_modes(modes, args, has_args, current) - local dir = "-" - for i = 1, #modes do - local mode = modes:sub(i, i) - - if mode == "+" or mode == "-" then - dir = mode - elseif has_args[mode] and has_args[mode][dir] then - if not args[1] then return false end - - if dir == "+" then - current[mode] = (type(current[mode]) == "table" and current[mode] or {}) - current[mode][args[1]] = true - else - if current[mode] then - current[mode][args[1]] = nil - end - end - table.remove(args, 1) - else - current[mode] = (dir == "+" and true or nil) - end - end - return true -end - -local function mode_to_string(modes) - local res = "+" - local args = {} - for mode, arg in pairs(modes) do - if arg == true then - res = res..mode - elseif type(arg) == "string" then - res = res..mode - table.insert(args, arg) - elseif type(arg) == "table" then - for _, a in pairs(arg) do - res = res..mode - table.insert(args, a) - end - end - end - - res = res.." "..table.concat(args, " ") - - return res -end - -message_handler = { - ["PING"] = function(con, source, args, original) - con:send(":"..args[2].." PONG "..args[2].." "..source.."\n") - end, - - ["SERVER"] = function(con, source, args, original) - if source then - servlist[args[4]] = {address = args[1], distance = args[3] + 1 + servlist[source].distance, name = args[5], metadata = {}} - else - servlist[args[4]] = {address = args[1], distance = args[3], name = args[5], metadata = {}} - end - end, - - ["METADATA"] = function(con, source, args, original) - if args[1] == "*" then - if servlist[source] then - servlist[source].metadata[args[2]] = args[3] - else - print("Got metadata command from an unknown server!\n") - end - elseif args[1]:sub(1, 1) == "#" then - print(string.format("%q", original)) - print("Channels not yet handled!\n") - else - if userlist[args[1]] then - userlist[args[1]].metadata[args[2]] = args[3] - else - print(("%q"):format(original)) - print("Got metadata for an unknown user!\n") - end - end - end, - - ["UID"] = function(con, source, args, original) - userlist[args[1]] = { - server = source, - nick_ts = args[2], - nick = args[3], - hostname = args[4], - vhost = args[5], - ident = args[6], - ip = args[7], - user_ts = args[8], - modes = {}, - realname = args[-1], -- last one is safer as any extra are arguments to umodes (or protocol violations, but at that point nothing is a safe option) - - metadata = {}, -- controlled by METADATA network commands - } - - if not parse_modes(args[9], {table.unpack(args, 10, #args-1)}, {["s"] = {["+"] = true, ["-"] = false}}, userlist[args[1]].modes) then return true end - end, - - ["OPERTYPE"] = function(con, source, args, original) - if userlist[source] then - userlist[source].opertype = args[1] - else - print("Server "..source.." attempted to set OPERTYPE on a nonexistent user!\n") - end - end, - - ["NICK"] = function(con, source, args, original) - if userlist[source] then - userlist[source].nick = args[1] - userlist[source].nick_ts = args[2] - end - end, - - ["PRIVMSG"] = function(con, source, args, original) - if args[1] == cur_channel then - print(("%q"):format("<"..userlist[source].nick.."> "..args[2])) - end - - local cmd_args = {} - for part in args[2]:gmatch("[^ ]*") do - table.insert(cmd_args, part) - end - cmd = cmd_args[1]:upper() - table.remove(cmd_args, 1) - - local resp - if args[1]:sub(1, 1) == "#" then - resp = args[1] - - if cmd:sub(1, 3) ~= "\x0304" then return end - - cmd = cmd:sub(4) -- remove leading '-' - else - resp = source - end - - if commands[cmd] then - if has_permission(userlist[source], commands[cmd].privs) then - print(("%q"):format(userlist[source].nick.." executed command: "..cmd)) - return commands[cmd].func(con, source, cmd, cmd_args, resp) - else - con:send(":1HC000000 NOTICE "..resp.." :You are not authorized to execute that command.\n") - end - else - con:send(":1HC000000 NOTICE "..resp.." :Unknown command: "..cmd.."\n") - end - end, - - ["MODE"] = function(con, source, args, original) - if args[1]:sub(1, 1) == "#" then - print("Channels not handled yet!\n") - else - if not userlist[args[1]] then - print("Attempted to set mode on an unknown user!\n") - elseif not parse_modes(args[2], {table.unpack(args, 3)}, usermodes, userlist[args[1]].modes) then - return true - elseif not userlist[args[1]].modes.o then - userlist[args[1]].opertype = nil - end - end - end, - - ["QUIT"] = function(con, source, args, original) - userlist[source] = nil - for name, chan in pairs(chanlist) do - chan["users"][source] = nil - if next(chan["users"]) == nil and not chan["modes"]["P"] then - chanlist[name] = nil - end - end - end, - - ["KILL"] = function(con, source, args, original) - if args[1]:sub(1,3) ~= "1HC" then - print("Kill remote", original) - userlist[source] = nil - for name, chan in pairs(chanlist) do - chan["users"][source] = nil - if next(chan["users"]) == nil and not chan["modes"]["P"] then - chanlist[name] = nil - end - end - else - print("Kill local", original) - local user = userlist[args[1]] - if type(user) == "table" then - con:send("UID "..args[1].." "..user.nick_ts.." "..user.nick.." "..user.hostname.." "..user.vhost.." "..user.ident.." "..user.ip.." "..user.user_ts.." "..mode_to_string(user.modes).." :"..user.realname.."\n") - - -- temporary before I handle channels - for channel, _ in pairs(config.channels) do - con:send(":"..args[1].." JOIN "..channel.."\n") - con:send("MODE "..channel.." +o "..args[1].."\n") - end - end - end - end, - - ["KICK"] = function(con, soure, args, original) - if args[2]:sub(1,3) == "1HC" then - con:send(":"..args[2].." JOIN "..args[1].."\n") - con:send("MODE "..args[1].." +o "..args[2].."\n") - else - print("Channels not yet handled: "..("%q"):format(original)) - end - end, - ---[[ ["FJOIN"] = function(con, source, args, original) - - end]] -} |