skynet/index.lua

211 lines
5.4 KiB
Lua

-- Skynet v1.2 // server
-- orig. written by minish - 2023-10
-- revived 2025-01
--#region Imports
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 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 function processMessage(unm, msg, hidden)
if not hidden and msg:sub(1, #cfg.prefix) ~= cfg.prefix then return end
if not hidden then
msg = msg:sub(#cfg.prefix + 1)
end
local cmd
msg, cmd = nextWord(msg)
local user = cfg.users[unm]
if user == nil then
ch.reportLog("foreign user " .. unm .. " tries: " .. cmd)
return
end
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
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
local args = {}
for _, x in next, xcmd.args do
local arg
if x.match == "block" then
msg, arg = nextWord(msg)
if not arg and not x.optional then
ch.send(unm, "missing arg: " .. x.desc, "cmd")
return
end
elseif x.match == "player" then
msg, arg = nextWord(msg)
if not arg and not x.optional then
ch.send(unm, "missing player arg: " .. x.desc, "cmd")
return
else
arg = tk:resTg(arg)
if not arg then
ch.send(unm, "target not found for: " .. x.desc, "cmd")
return
end
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
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
-- local function scheduleScan()
-- os.startTimer(2)
-- end
local termStreak = 0
local termStreakAt = 0
-- local lastPlrList
local listeners = {
["chat"] = function(username, message, uuid, isHidden)
return processMessage(username, message, isHidden)
end,
["playerChangedDimension"] = function(username, fromDim, toDim)
ch.reportLog(username .. " goes from " .. fromDim .. " to " .. toDim, "dims")
end,
["playerJoin"] = function(username, dimension)
tk.plrs[username] = { dimension = dimension }
end,
["playerLeave"] = function(username, dimension)
tk.plrs[username] = nil
end,
-- ["timer"] = function()
-- scheduleScan()
-- local plrs = tk:scanRange(16)
-- table.sort(plrs)
-- local plrList = table.concat(plrs, ", ")
-- if plrList ~= lastPlrList then
-- if #plrs > 0 then
-- ch.reportLog("players in range: " .. plrList, "scan")
-- elseif lastPlrList ~= nil then
-- ch.reportLog("players left range", "scan")
-- end
-- lastPlrList = plrList
-- end
-- end,
["peripheral_detach"] = function()
end,
["terminate"] = function()
-- should we reset term streak
if os.clock() - termStreakAt > 1 then
-- yes
termStreak = 1
termStreakAt = os.clock()
else
-- no so increase streak
termStreak = termStreak + 1
end
-- check if streak is too much
if termStreak >= 2 then
ch.reportLog("restarting to prevent sys access..")
os.reboot()
end
print("?")
ch.reportLog("ALERT!! somebody tried to terminate skynet runner")
end,
}
local function evDispatcher()
while true do
local params = { os.pullEventRaw() }
local event = table.remove(params, 1)
local listener = listeners[event]
if listener and listener(table.unpack(params)) then
break
end
end
end
ch.userBc("Loaded!")
ch.reportLog("you are auto subbed to log, welcome!")
tk:refresh()
evDispatcher()