From 60335b238ad75bbea7e088d16e1717556dbb182a Mon Sep 17 00:00:00 2001 From: Test_User Date: Sun, 12 Jun 2022 12:42:18 -0400 Subject: nukes --- network.lua | 175 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 network.lua (limited to 'network.lua') diff --git a/network.lua b/network.lua new file mode 100644 index 0000000..fbeb168 --- /dev/null +++ b/network.lua @@ -0,0 +1,175 @@ +--[[ + +Network protocol file for HaxServ. + +Written by: Test_User + +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 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 + +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("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) + print(string.format("%q", original)) + if userlist[source] then + userlist[source].nick = args[1] + userlist[source].nick_ts = args[2] + end + end, + + ["PRIVMSG"] = function(con, source, args, original) + print(string.format("%q", original)) + 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, 1) ~= "-" then return end + + cmd = cmd:sub(2) -- remove leading '-' + else + resp = source + end + + if commands[cmd] then + if has_permission(userlist[source], commands[cmd].privs) then + 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) + print(string.format("%q", 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)}, {["s"] = {["+"] = true, ["-"] = false}}, 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) + print(string.format("%q", original)) + userlist[source] = nil + end, +} -- cgit v1.2.3