summaryrefslogtreecommitdiff
path: root/CoupServ.lua
diff options
context:
space:
mode:
authorTest_User <hax@andrewyu.org>2022-06-12 12:42:18 -0400
committerTest_User <hax@andrewyu.org>2022-06-12 12:42:18 -0400
commit60335b238ad75bbea7e088d16e1717556dbb182a (patch)
tree83e15f1a1231d82768c5ce99d2abaebb33aa9fa2 /CoupServ.lua
parent1b60aa9b97c9aea9aa842da3f8dea8816721ad3d (diff)
downloadcoupserv-60335b238ad75bbea7e088d16e1717556dbb182a.tar.gz
coupserv-60335b238ad75bbea7e088d16e1717556dbb182a.zip
nukes
Diffstat (limited to 'CoupServ.lua')
-rwxr-xr-xCoupServ.lua170
1 files changed, 170 insertions, 0 deletions
diff --git a/CoupServ.lua b/CoupServ.lua
new file mode 100755
index 0000000..1da6281
--- /dev/null
+++ b/CoupServ.lua
@@ -0,0 +1,170 @@
+#!/usr/bin/env lua
+--[[
+
+Main program for HaxServ, a pseudoserver for inspircd3.
+
+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.
+]]
+
+path = arg[0]:sub(1, -arg[0]:reverse():find('/'))
+
+socket = require("socket")
+json = require("json")
+ssl = require("ssl")
+
+servlist = {}
+userlist = {}
+chanlist = {}
+
+function has_permission(user, privs)
+ privs = privs or {}
+ for _, v in pairs(privs) do
+ if v == "Admin" then
+ if user.opertype ~= "Admin" then
+ return false
+ end
+ elseif v == "Owner" then -- not dealing with this yet, so just always return false for now
+ return false
+ else -- unknown priv, naturally no one has it
+ return false
+ end
+ end
+ return true
+end
+
+config_file = io.open(path.."CoupServConfig.json", "r+")
+config = json.decode(config_file:read("*a"))
+
+for file, _ in pairs(config.files) do
+ dofile(path..file)
+end
+
+stdin = socket.tcp()
+stdin:close()
+stdin:setfd(0) --clearly a hack but it works
+
+while true do
+ servlist = {}
+ userlist = {}
+ chanlist = {}
+
+ local s = socket.tcp()
+ s:connect("irc.andrewyu.org", 7005)
+ local con = ssl.wrap(s, {mode = "client", protocol = "tlsv1_3"})
+
+ print(con:dohandshake())
+
+ con:send("SERVER hax.irc.andrewyu.org "..config.send_password.." 0 1HC :HaxServ\n")
+ con:send("BURST "..tostring(os.time()).."\n")
+ con:send("UID 1HC000000 "..tostring(os.time()).." "..config.nick.." hax.irc.andrewyu.org "..config.hostmask.." HaxServ 192.168.1.1 "..tostring(os.time()).." +k :HaxServ\n")
+ con:send(":1HC000000 OPERTYPE Admin\n")
+ for channel, _ in pairs(config.channels) do
+ con:send("FJOIN "..channel.." "..tostring(os.time()).." + :,1HC000000\n")
+ con:send("MODE "..channel.." +o 1HC000000\n")
+ end
+ con:send("ENDBURST\n")
+
+ local proceed = true
+ while proceed do
+ ready, _, err = socket.select({con, stdin}, {}, 300)
+ if err then
+ con:send("") -- hack to make it properly timeout due to annoying bugs
+ end
+
+ for _, sock in ipairs(ready) do
+ if sock == con then
+ local msg, err = con:receive()
+
+ local original = msg
+
+ if err then
+ proceed = false
+ break
+ end
+
+ local source = nil
+ if msg:sub(1, 1) == ":" then
+ source = msg:sub(2):match("^[^ ]*")
+ msg = msg:sub(string.len(source) + 3) -- 1 for the leading ':', 1 for the trailing ' ', and 1 for the offset
+ end
+
+ local lastarg = msg:match(" :.*")
+ if lastarg ~= nil then
+ msg = msg:sub(1, -string.len(lastarg) - 1) -- only offset
+ lastarg = lastarg:sub(3)
+ end
+
+ local args = {}
+ for arg in msg:gmatch("[^ ]*") do
+ table.insert(args, arg)
+ end
+
+ local command = args[1]
+ table.remove(args, 1)
+
+ if lastarg ~= nil then
+ table.insert(args, lastarg)
+ end
+
+ if message_handler[command] then
+ local success, stop = pcall(message_handler[command], con, source, args, original)
+ if success and stop then
+ proceed = false
+ break
+ elseif not success then
+ print(stop)
+ end
+ else
+ print("Unhandled command:", ("%q"):format(original))
+ end
+ elseif sock == stdin then
+ msg = io.stdin:read()
+ local args = {}
+ for arg in msg:gmatch("[^ ]*") do
+ table.insert(args, arg)
+ end
+ local command = args[1]:upper()
+ table.remove(args, 1)
+
+ if stdin_commands[command] then
+ local success, err = pcall(stdin_commands[command], con, msg, args)
+ if not success then
+ print(err)
+ elseif err then
+ proceed = false
+ break
+ end
+ else
+ print("Unknown command.")
+ end
+ end
+ end
+ if err then break end
+ end
+
+ con:close()
+end