9fd50ee01e
Fixed cli help texts Added administrator options for critical methods Added result state for client and server specific errors Redirect root to help text Fixed fingerprint error, fingerprint must be case sensitive Re-Added online messages Added typing trigger for discord bot messages client: fixed chunkString for empty results preemtive wrap error objects for server messages both: added raw lua RS Bridge command entry
164 lines
4.7 KiB
Lua
164 lines
4.7 KiB
Lua
local secretToken = "$TOKEN"
|
|
local connectionUri = "$HOST"
|
|
local waitSeconds = 5
|
|
|
|
local function chunkString(value, chunkSize)
|
|
if not chunkSize then chunkSize = 10000 end
|
|
local length = value:len()
|
|
local total = math.ceil(length / chunkSize)
|
|
local chunks = {}
|
|
if length == 0 then
|
|
total = 1
|
|
chunks[1] = ""
|
|
else
|
|
local i = 1
|
|
for i=1,total do
|
|
local pos = 1 + ((i - 1) * chunkSize)
|
|
chunks[i] = value:sub(pos, pos + chunkSize - 1)
|
|
end
|
|
end
|
|
return total, chunks
|
|
end
|
|
|
|
local function sendJson(socket, message)
|
|
return socket.send(textutils.serializeJSON(message))
|
|
end
|
|
|
|
local function sendResponse(socket, id, result, success)
|
|
if success == nil then success = 0 end
|
|
|
|
local total, chunks = chunkString(result)
|
|
for i, chunk in pairs(chunks) do
|
|
sendJson(socket, { id = id, result = chunk, chunk = i, total = total, success = success })
|
|
end
|
|
end
|
|
|
|
-- error: no rs system
|
|
-- return rssystem rs
|
|
local function getPeripheral(name)
|
|
local dev = peripheral.find(name)
|
|
if not dev then error({message = "No peripheral '"..name.."' attached to the computer!"}) end
|
|
return dev
|
|
end
|
|
|
|
local function runRsCommand(params)
|
|
local script, reason = loadstring("local rs = peripheral.find(\"rsBridge\") if not rs then error({message = \"RS Bridge is not attached!\"}) end return rs."..params.command)
|
|
if not script then error({message = "Invalid command: "..reason.."!"}) end
|
|
local result = table.pack(pcall(script))
|
|
local success = result[1]
|
|
if not success then error({message = "Command execution failed: "..result[2].."!"}) end
|
|
|
|
local retvals = {}
|
|
retvals.n = result.n - 1
|
|
for i=1,retvals.n do retvals[tostring(i)] = result[i + 1] end
|
|
return textutils.serializeJSON(retvals)
|
|
end
|
|
|
|
-- error: any error during execution
|
|
-- return string result
|
|
local function getResponse(parsed)
|
|
if parsed.method == "energyusage" then
|
|
return tostring(getPeripheral("rsBridge").getEnergyUsage())
|
|
elseif parsed.method == "energystorage" then
|
|
return tostring(getPeripheral("rsBridge").getEnergyStorage())
|
|
elseif parsed.method == "listitems" then
|
|
return textutils.serializeJSON(getPeripheral("rsBridge").listItems())
|
|
elseif parsed.method == "listfluids" then
|
|
return textutils.serializeJSON(getPeripheral("rsBridge").listFluids())
|
|
elseif parsed.method == "craft" then
|
|
return tostring(getPeripheral("rsBridge").craftItem(parsed.params))
|
|
elseif parsed.method == "getitem" then
|
|
local item = getPeripheral("rsBridge").getItem(parsed.params)
|
|
if not item then error({message = "Requested item not found!"}) end
|
|
return textutils.serializeJSON(item)
|
|
elseif parsed.method == "command" then
|
|
return runRsCommand(parsed.params)
|
|
end
|
|
|
|
error({message = "No message handler for method: "..parsed.method.."!"})
|
|
end
|
|
|
|
local function logJSON(json, prefix)
|
|
if not prefix then prefix = "" end
|
|
for k,v in pairs(json) do
|
|
local key = prefix..k
|
|
if type(v) == "table" then
|
|
logJSON(v, key..".")
|
|
else
|
|
print(key, "=", textutils.serializeJSON(v))
|
|
end
|
|
end
|
|
end
|
|
|
|
-- return bool success
|
|
local function handleMessage(socket, message)
|
|
local parsed, reason = textutils.unserializeJSON(message)
|
|
if not parsed then
|
|
print("Received message:", message)
|
|
printError("Message could not be parsed:", reason)
|
|
return false
|
|
end
|
|
|
|
pcall(function() print("Received JSON:") logJSON(parsed) end)
|
|
|
|
if parsed.type == "request" then
|
|
local success, result = pcall(function() return getResponse(parsed) end)
|
|
if not success then
|
|
if not result.message then
|
|
sendResponse(socket, parsed.id, result, 2)
|
|
else
|
|
sendResponse(socket, parsed.id, result.message, 1)
|
|
end
|
|
else
|
|
sendResponse(socket, parsed.id, result, 0)
|
|
end
|
|
return true
|
|
end
|
|
|
|
printError("Invalid message type:", parsed.type)
|
|
return false
|
|
end
|
|
|
|
local function socketClient()
|
|
print("Connecting to the socket server at "..connectionUri.."...")
|
|
local socket, reason = http.websocket(connectionUri)
|
|
if not socket then error("Socket server could not be reached: "..reason) end
|
|
print("Connection successful!")
|
|
|
|
socket.send("login="..secretToken)
|
|
while true do
|
|
local message, binary = socket.receive()
|
|
if not not message and not binary then
|
|
if message == "outdated" then
|
|
printError("Current script is outdated! Please update from the host!")
|
|
return
|
|
end
|
|
handleMessage(socket, message)
|
|
end
|
|
end
|
|
end
|
|
|
|
local function termWaiter()
|
|
os.pullEvent("terminate")
|
|
end
|
|
|
|
local function services()
|
|
parallel.waitForAny(termWaiter, function()
|
|
parallel.waitForAll(socketClient)
|
|
end)
|
|
end
|
|
|
|
local function main()
|
|
while true do
|
|
local status, error = pcall(services)
|
|
if status then break end
|
|
printError("An uncaught exception was raised:", error)
|
|
printError("Restarting in", waitSeconds, "seconds...")
|
|
sleep(waitSeconds)
|
|
end
|
|
end
|
|
|
|
local oldPullEvent = os.pullEvent
|
|
os.pullEvent = os.pullEventRaw
|
|
pcall(main)
|
|
os.pullEvent = oldPullEvent |