2022-01-16 21:31:07 +01:00
local secretToken = " $TOKEN "
2022-01-16 22:29:50 +01:00
local connectionUri = " $HOST "
2022-01-16 21:31:07 +01:00
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 = { }
2022-01-17 15:24:04 +01:00
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
2022-01-16 21:31:07 +01:00
end
return total , chunks
end
local function sendJson ( socket , message )
return socket.send ( textutils.serializeJSON ( message ) )
end
local function sendResponse ( socket , id , result , success )
2022-01-17 15:24:04 +01:00
if success == nil then success = 0 end
2022-01-16 21:31:07 +01:00
local total , chunks = chunkString ( result )
for i , chunk in pairs ( chunks ) do
2022-01-17 16:22:15 +01:00
sendJson ( socket , { type = " reply " , id = id , result = chunk , chunk = i , total = total , success = success } )
2022-01-16 21:31:07 +01:00
end
end
-- error: no rs system
-- return rssystem rs
local function getPeripheral ( name )
local dev = peripheral.find ( name )
2022-01-17 15:24:04 +01:00
if not dev then error ( { message = " No peripheral ' " .. name .. " ' attached to the computer! " } ) end
2022-01-16 21:31:07 +01:00
return dev
end
2022-01-17 15:24:04 +01:00
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
2022-01-16 21:31:07 +01:00
-- 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 ) )
2022-01-16 21:51:37 +01:00
elseif parsed.method == " getitem " then
2022-01-17 15:24:04 +01:00
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 )
2022-01-16 21:31:07 +01:00
end
2022-01-17 15:24:04 +01:00
error ( { message = " No message handler for method: " .. parsed.method .. " ! " } )
2022-01-16 21:31:07 +01:00
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 )
2022-01-17 15:24:04 +01:00
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
2022-01-16 21:31:07 +01:00
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