BillyOrIsIt

Untitled

Dec 2nd, 2021 (edited)
329
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 17.08 KB | None | 0 0
  1. local type = type
  2. local next = next
  3. local error = error
  4. local tonumber = tonumber
  5. local tostring = tostring
  6. local utf8_char = string.char
  7. local table_concat = table.concat
  8. local table_sort = table.sort
  9. local string_char = string.char
  10. local string_byte = string.byte
  11. local string_find = string.find
  12. local string_match = string.match
  13. local string_gsub = string.gsub
  14. local string_sub = string.sub
  15. local string_format = string.format
  16. local setmetatable = setmetatable
  17. local getmetatable = getmetatable
  18. local huge = math.huge
  19. local tiny = -huge
  20.  
  21. local json = {}
  22. json.object = {}
  23.  
  24. function math_type(number)
  25.     if math.floor(number) == number then
  26.         return "integer"
  27.     else
  28.         return "float"
  29.     end
  30. end
  31. -- json.encode --
  32. local statusVisited
  33. local statusBuilder
  34.  
  35. local encode_map = {}
  36.  
  37. local encode_escape_map = {
  38.     [ "\"" ] = "\\\"",
  39.     [ "\\" ] = "\\\\",
  40.     [ "/" ]  = "\\/",
  41.     [ "\b" ] = "\\b",
  42.     [ "\f" ] = "\\f",
  43.     [ "\n" ] = "\\n",
  44.     [ "\r" ] = "\\r",
  45.     [ "\t" ] = "\\t",
  46. }
  47.  
  48. local decode_escape_set = {}
  49. local decode_escape_map = {}
  50. for k, v in next, encode_escape_map do
  51.     decode_escape_map[v] = k
  52.     decode_escape_set[string_byte(v, 2)] = true
  53. end
  54.  
  55. for i = 0, 31 do
  56.     local c = string_char(i)
  57.     if not encode_escape_map[c] then
  58.         encode_escape_map[c] = string_format("\\u%04x", i)
  59.     end
  60. end
  61.  
  62. local function encode(v)
  63.     local res = encode_map[type(v)](v)
  64.     statusBuilder[#statusBuilder+1] = res
  65. end
  66.  
  67. encode_map["nil"] = function ()
  68.     return "null"
  69. end
  70.  
  71. local function encode_string(v)
  72.     return string_gsub(v, '[\0-\31\\"]', encode_escape_map)
  73. end
  74.  
  75. function encode_map.string(v)
  76.     statusBuilder[#statusBuilder+1] = '"'
  77.     statusBuilder[#statusBuilder+1] = encode_string(v)
  78.     return '"'
  79. end
  80.  
  81. local function convertreal(v)
  82.     local g = string_format('%.16g', v)
  83.     if tonumber(g) == v then
  84.         return g
  85.     end
  86.     return string_format('%.17g', v)
  87. end
  88.  
  89. if string_match(tostring(1/2), "%p") == "," then
  90.     local _convertreal = convertreal
  91.     function convertreal(v)
  92.         return string_gsub(_convertreal(v), ',', '.')
  93.     end
  94. end
  95.  
  96. function encode_map.number(v)
  97.     if v ~= v or v <= tiny or v >= huge then
  98.         error("unexpected number value '" .. tostring(v) .. "'")
  99.     end
  100.     return convertreal(v)
  101. end
  102.  
  103. function encode_map.boolean(v)
  104.     if v then
  105.         return "true"
  106.     else
  107.         return "false"
  108.     end
  109. end
  110.  
  111. function encode_map.table(t)
  112.     local first_val = next(t)
  113.     if first_val == nil then
  114.         if getmetatable(t) == json.object then
  115.             return "{}"
  116.         else
  117.             return "[]"
  118.         end
  119.     end
  120.     if statusVisited[t] then
  121.         error("circular reference")
  122.     end
  123.     statusVisited[t] = true
  124.     if type(first_val) == 'string' then
  125.         local key = {}
  126.         for k in next, t do
  127.             if type(k) ~= "string" then
  128.                 error("invalid table: mixed or invalid key types")
  129.             end
  130.             key[#key+1] = k
  131.         end
  132.         table_sort(key)
  133.         local k = key[1]
  134.         statusBuilder[#statusBuilder+1] = '{"'
  135.         statusBuilder[#statusBuilder+1] = encode_string(k)
  136.         statusBuilder[#statusBuilder+1] = '":'
  137.         encode(t[k])
  138.         for i = 2, #key do
  139.             local k = key[i]
  140.             statusBuilder[#statusBuilder+1] = ',"'
  141.             statusBuilder[#statusBuilder+1] = encode_string(k)
  142.             statusBuilder[#statusBuilder+1] = '":'
  143.             encode(t[k])
  144.         end
  145.         statusVisited[t] = nil
  146.         return "}"
  147.     else
  148.         local max = 0
  149.         for k in next, t do
  150.             if math_type(k) ~= "integer" or k <= 0 then
  151.                 error("invalid table: mixed or invalid key types")
  152.             end
  153.             if max < k then
  154.                 max = k
  155.             end
  156.         end
  157.         statusBuilder[#statusBuilder+1] = "["
  158.         encode(t[1])
  159.         for i = 2, max do
  160.             statusBuilder[#statusBuilder+1] = ","
  161.             encode(t[i])
  162.         end
  163.         statusVisited[t] = nil
  164.         return "]"
  165.     end
  166. end
  167.  
  168. local function encode_unexpected(v)
  169.     if v == json.null then
  170.         return "null"
  171.     else
  172.         error("unexpected type '"..type(v).."'")
  173.     end
  174. end
  175. encode_map[ "function" ] = encode_unexpected
  176. encode_map[ "userdata" ] = encode_unexpected
  177. encode_map[ "thread"   ] = encode_unexpected
  178.  
  179. function json.encode(v)
  180.     statusVisited = {}
  181.     statusBuilder = {}
  182.     encode(v)
  183.     return table_concat(statusBuilder)
  184. end
  185.  
  186. json._encode_map = encode_map
  187. json._encode_string = encode_string
  188.  
  189. -- json.decode --
  190.  
  191. local statusBuf
  192. local statusPos
  193. local statusTop
  194. local statusAry = {}
  195. local statusRef = {}
  196.  
  197. local function find_line()
  198.     local line = 1
  199.     local pos = 1
  200.     while true do
  201.         local f, _, nl1, nl2 = string_find(statusBuf, '([\n\r])([\n\r]?)', pos)
  202.         if not f then
  203.             return line, statusPos - pos + 1
  204.         end
  205.         local newpos = f + ((nl1 == nl2 or nl2 == '') and 1 or 2)
  206.         if newpos > statusPos then
  207.             return line, statusPos - pos + 1
  208.         end
  209.         pos = newpos
  210.         line = line + 1
  211.     end
  212. end
  213.  
  214. local function decode_error(msg)
  215.     error(string_format("ERROR: %s at line %d col %d", msg, find_line()))
  216. end
  217.  
  218. local function get_word()
  219.     return string_match(statusBuf, "^[^ \t\r\n%]},]*", statusPos)
  220. end
  221.  
  222. local function next_byte()
  223.     local pos = string_find(statusBuf, "[^ \t\r\n]", statusPos)
  224.     if pos then
  225.         statusPos = pos
  226.         return string_byte(statusBuf, pos)
  227.     end
  228.     return -1
  229. end
  230.  
  231. local function consume_byte(c)
  232.     local _, pos = string_find(statusBuf, c, statusPos)
  233.     if pos then
  234.         statusPos = pos + 1
  235.         return true
  236.     end
  237. end
  238.  
  239. local function expect_byte(c)
  240.     local _, pos = string_find(statusBuf, c, statusPos)
  241.     if not pos then
  242.         decode_error(string_format("expected '%s'", string_sub(c, #c)))
  243.     end
  244.     statusPos = pos
  245. end
  246.  
  247. local function decode_unicode_surrogate(s1, s2)
  248.     return utf8_char(0x10000 + (tonumber(s1, 16) - 0xd800) * 0x400 + (tonumber(s2, 16) - 0xdc00))
  249. end
  250.  
  251. local function decode_unicode_escape(s)
  252.     return utf8_char(tonumber(s, 16))
  253. end
  254.  
  255. local function decode_string()
  256.     local has_unicode_escape = false
  257.     local has_escape = false
  258.     local i = statusPos + 1
  259.     while true do
  260.         i = string_find(statusBuf, '["\\\0-\31]', i)
  261.         if not i then
  262.             decode_error "expected closing quote for string"
  263.         end
  264.         local x = string_byte(statusBuf, i)
  265.         if x < 32 then
  266.             statusPos = i
  267.             decode_error "control character in string"
  268.         end
  269.         if x == 34 --[[ '"' ]] then
  270.             local s = string_sub(statusBuf, statusPos + 1, i - 1)
  271.             if has_unicode_escape then
  272.                 s = string_gsub(string_gsub(s
  273.                     , "\\u([dD][89aAbB]%x%x)\\u([dD][c-fC-F]%x%x)", decode_unicode_surrogate)
  274.                     , "\\u(%x%x%x%x)", decode_unicode_escape)
  275.             end
  276.             if has_escape then
  277.                 s = string_gsub(s, "\\.", decode_escape_map)
  278.             end
  279.             statusPos = i + 1
  280.             return s
  281.         end
  282.         --assert(x == 92 --[[ "\\" ]])
  283.         local nx = string_byte(statusBuf, i+1)
  284.         if nx == 117 --[[ "u" ]] then
  285.             if not string_match(statusBuf, "^%x%x%x%x", i+2) then
  286.                 statusPos = i
  287.                 decode_error "invalid unicode escape in string"
  288.             end
  289.             has_unicode_escape = true
  290.             i = i + 6
  291.         else
  292.             if not decode_escape_set[nx] then
  293.                 statusPos = i
  294.                 decode_error("invalid escape char '" .. (nx and string_char(nx) or "<eol>") .. "' in string")
  295.             end
  296.             has_escape = true
  297.             i = i + 2
  298.         end
  299.     end
  300. end
  301.  
  302. local function decode_number()
  303.     local num, c = string_match(statusBuf, '^([0-9]+%.?[0-9]*)([eE]?)', statusPos)
  304.     if not num or string_byte(num, -1) == 0x2E --[[ "." ]] then
  305.         decode_error("invalid number '" .. get_word() .. "'")
  306.     end
  307.     if c ~= '' then
  308.         num = string_match(statusBuf, '^([^eE]*[eE][-+]?[0-9]+)[ \t\r\n%]},]', statusPos)
  309.         if not num then
  310.             decode_error("invalid number '" .. get_word() .. "'")
  311.         end
  312.     end
  313.     statusPos = statusPos + #num
  314.     return tonumber(num)
  315. end
  316.  
  317. local function decode_number_zero()
  318.     local num, c = string_match(statusBuf, '^(.%.?[0-9]*)([eE]?)', statusPos)
  319.     if not num or string_byte(num, -1) == 0x2E --[[ "." ]] or string_match(statusBuf, '^.[0-9]+', statusPos) then
  320.         decode_error("invalid number '" .. get_word() .. "'")
  321.     end
  322.     if c ~= '' then
  323.         num = string_match(statusBuf, '^([^eE]*[eE][-+]?[0-9]+)[ \t\r\n%]},]', statusPos)
  324.         if not num then
  325.             decode_error("invalid number '" .. get_word() .. "'")
  326.         end
  327.     end
  328.     statusPos = statusPos + #num
  329.     return tonumber(num)
  330. end
  331.  
  332. local function decode_number_negative()
  333.     statusPos = statusPos + 1
  334.     local c = string_byte(statusBuf, statusPos)
  335.     if c then
  336.         if c == 0x30 then
  337.             return -decode_number_zero()
  338.         elseif c > 0x30 and c < 0x3A then
  339.             return -decode_number()
  340.         end
  341.     end
  342.     decode_error("invalid number '" .. get_word() .. "'")
  343. end
  344.  
  345. local function decode_true()
  346.     if string_sub(statusBuf, statusPos, statusPos+3) ~= "true" then
  347.         decode_error("invalid literal '" .. get_word() .. "'")
  348.     end
  349.     statusPos = statusPos + 4
  350.     return true
  351. end
  352.  
  353. local function decode_false()
  354.     if string_sub(statusBuf, statusPos, statusPos+4) ~= "false" then
  355.         decode_error("invalid literal '" .. get_word() .. "'")
  356.     end
  357.     statusPos = statusPos + 5
  358.     return false
  359. end
  360.  
  361. local function decode_null()
  362.     if string_sub(statusBuf, statusPos, statusPos+3) ~= "null" then
  363.         decode_error("invalid literal '" .. get_word() .. "'")
  364.     end
  365.     statusPos = statusPos + 4
  366.     return json.null
  367. end
  368.  
  369. local function decode_array()
  370.     statusPos = statusPos + 1
  371.     local res = {}
  372.     if consume_byte "^[ \t\r\n]*%]" then
  373.         return res
  374.     end
  375.     statusTop = statusTop + 1
  376.     statusAry[statusTop] = true
  377.     statusRef[statusTop] = res
  378.     return res
  379. end
  380.  
  381. local function decode_object()
  382.     statusPos = statusPos + 1
  383.     local res = {}
  384.     if consume_byte "^[ \t\r\n]*}" then
  385.         return setmetatable(res, json.object)
  386.     end
  387.     statusTop = statusTop + 1
  388.     statusAry[statusTop] = false
  389.     statusRef[statusTop] = res
  390.     return res
  391. end
  392.  
  393. local decode_uncompleted_map = {
  394.     [ string_byte '"' ] = decode_string,
  395.     [ string_byte "0" ] = decode_number_zero,
  396.     [ string_byte "1" ] = decode_number,
  397.     [ string_byte "2" ] = decode_number,
  398.     [ string_byte "3" ] = decode_number,
  399.     [ string_byte "4" ] = decode_number,
  400.     [ string_byte "5" ] = decode_number,
  401.     [ string_byte "6" ] = decode_number,
  402.     [ string_byte "7" ] = decode_number,
  403.     [ string_byte "8" ] = decode_number,
  404.     [ string_byte "9" ] = decode_number,
  405.     [ string_byte "-" ] = decode_number_negative,
  406.     [ string_byte "t" ] = decode_true,
  407.     [ string_byte "f" ] = decode_false,
  408.     [ string_byte "n" ] = decode_null,
  409.     [ string_byte "[" ] = decode_array,
  410.     [ string_byte "{" ] = decode_object,
  411. }
  412. local function unexpected_character()
  413.     decode_error("unexpected character '" .. string_sub(statusBuf, statusPos, statusPos) .. "'")
  414. end
  415. local function unexpected_eol()
  416.     decode_error("unexpected character '<eol>'")
  417. end
  418.  
  419. local decode_map = {}
  420. for i = 0, 255 do
  421.     decode_map[i] = decode_uncompleted_map[i] or unexpected_character
  422. end
  423. decode_map[-1] = unexpected_eol
  424.  
  425. local function decode()
  426.     return decode_map[next_byte()]()
  427. end
  428.  
  429. local function decode_item()
  430.     local top = statusTop
  431.     local ref = statusRef[top]
  432.     if statusAry[top] then
  433.         ref[#ref+1] = decode()
  434.     else
  435.         expect_byte '^[ \t\r\n]*"'
  436.         local key = decode_string()
  437.         expect_byte '^[ \t\r\n]*:'
  438.         statusPos = statusPos + 1
  439.         ref[key] = decode()
  440.     end
  441.     if top == statusTop then
  442.         repeat
  443.             local chr = next_byte(); statusPos = statusPos + 1
  444.             if chr == 44 --[[ "," ]] then
  445.                 return
  446.             end
  447.             if statusAry[statusTop] then
  448.                 if chr ~= 93 --[[ "]" ]] then decode_error "expected ']' or ','" end
  449.             else
  450.                 if chr ~= 125 --[[ "}" ]] then decode_error "expected '}' or ','" end
  451.             end
  452.             statusTop = statusTop - 1
  453.         until statusTop == 0
  454.     end
  455. end
  456.  
  457. function json.decode(str)
  458.     if type(str) ~= "string" then
  459.         error("expected argument of type string, got " .. type(str))
  460.     end
  461.     statusBuf = str
  462.     statusPos = 1
  463.     statusTop = 0
  464.     local res = decode()
  465.     while statusTop > 0 do
  466.         decode_item()
  467.     end
  468.     if string_find(statusBuf, "[^ \t\r\n]", statusPos) then
  469.         decode_error "trailing garbage"
  470.     end
  471.     return res
  472. end
  473.  
  474. -- Generate a lightuserdata
  475. json.null = 12897345879
  476.  
  477. -- I stole this from you :)
  478. function getItemIndex(itemName)
  479.     for slot = 1, 16, 1 do
  480.         local item = turtle.getItemDetail(slot)
  481.         if(item ~= nil) then
  482.             if(item["name"] == itemName) then
  483.                 return slot
  484.             end
  485.         end
  486.     end
  487. end
  488.  
  489. -- BEGIN MAIN CODE --
  490.  
  491. function undergoMitosis()
  492.     turtle.select(getItemIndex("computercraft:peripheral"))
  493.     if not turtle.place() then
  494.         return nil
  495.     end
  496.     turtle.select(getItemIndex("computercraft:disk_expanded"))
  497.     turtle.drop()  
  498.     if not turtle.up() then
  499.         return nil
  500.     end
  501.     turtle.select(getItemIndex("computercraft:turtle_expanded"))
  502.     if not turtle.place() then
  503.         return nil
  504.     end
  505.     peripheral.call("front", "turnOn")
  506.     turtle.select(1)
  507.     turtle.drop(math.floor(turtle.getItemCount() / 2))
  508.     os.sleep(1)
  509.     peripheral.call("front", "reboot")
  510.     local cloneId = peripheral.call("front", "getID")
  511.     if not turtle.down() then
  512.         return nil
  513.     end
  514.     if not turtle.suck() then
  515.         return nil
  516.     end
  517.     if not turtle.dig() then
  518.         return nil
  519.     end
  520.     return cloneId
  521. end
  522.  
  523. function mineTunnel(obj, ws)
  524.     local file
  525.     local blocks = {}
  526.     for i=1,obj.length,1 do
  527.         if obj.direction == 'forward' then
  528.             turtle.dig()
  529.             local success = turtle.forward()
  530.             if not success then
  531.                 return res
  532.             end
  533.             ws.send(json.encode({move="f", nonce=obj.nonce}))
  534.             blocks[i] = {}
  535.             blocks[i][1] = select(2,turtle.inspectDown())
  536.             blocks[i][2] = select(2,turtle.inspectUp())
  537.             turtle.turnLeft()
  538.             ws.send(json.encode({move="l", nonce=obj.nonce}))
  539.             blocks[i][3] = select(2,turtle.inspect())
  540.             turtle.turnRight()
  541.             ws.send(json.encode({move="r", nonce=obj.nonce}))
  542.             turtle.turnRight()
  543.             ws.send(json.encode({move="r", nonce=obj.nonce}))
  544.             blocks[i][4] = select(2,turtle.inspect())
  545.             turtle.turnLeft()
  546.             ws.send(json.encode({move="l", blocks=blocks[i], nonce=obj.nonce}))
  547.         else
  548.             if obj.direction == 'up' then
  549.                 turtle.digUp()
  550.                 local success = turtle.up()
  551.                 if not success then
  552.                     return res
  553.                 end
  554.                 ws.send(json.encode({move="u", nonce=obj.nonce}))
  555.             else
  556.                 turtle.digDown()
  557.                 local success = turtle.down()
  558.                 if not success then
  559.                     return res
  560.                 end
  561.                 ws.send(json.encode({move="d", nonce=obj.nonce}))
  562.             end
  563.  
  564.             blocks[i] = {}
  565.             blocks[i][1] = select(2,turtle.inspect())
  566.             turtle.turnLeft()
  567.             ws.send(json.encode({move="l", nonce=obj.nonce}))
  568.  
  569.             blocks[i][2] = select(2,turtle.inspect())
  570.             turtle.turnLeft()
  571.             ws.send(json.encode({move="l", nonce=obj.nonce}))
  572.  
  573.             blocks[i][3] = select(2,turtle.inspect())
  574.             turtle.turnLeft()
  575.             ws.send(json.encode({move="l", nonce=obj.nonce}))
  576.  
  577.             blocks[i][4] = select(2,turtle.inspect())
  578.             ws.send(json.encode({blocks=blocks[i], nonce=obj.nonce}))
  579.         end
  580.     end
  581.     return blocks
  582. end
  583.  
  584. function websocketLoop()
  585.    
  586.     local ws, err = http.websocket("ws://50e1-141-153-128-101.ngrok.io")
  587.  
  588.     if err then
  589.         print(err)
  590.     elseif ws then
  591.         while true do
  592.             term.clear()
  593.             term.setCursorPos(1,1)
  594.             print("      .i.\n")
  595.             print("penis OS booting")
  596.             local message = ws.receive()
  597.             if message == nil then
  598.                 break
  599.             end
  600.             local obj = json.decode(message)
  601.             print(obj.type)
  602.             if obj.type == 'eval' then
  603.                 local func = loadstring(obj['function'])
  604.                 local result = func()
  605.                 ws.send(json.encode({data=result, nonce=obj.nonce}))
  606.             elseif obj.type == 'mitosis' then
  607.                 local status, res = pcall(undergoMitosis)
  608.                 if not status then
  609.                     ws.send(json.encode({data="null", nonce=obj.nonce}))
  610.                 elseif res == nil then
  611.                     ws.send(json.encode({data="null", nonce=obj.nonce}))
  612.                 else
  613.                     ws.send(json.encode({data=res, nonce=obj.nonce}))
  614.                 end
  615.             elseif obj.type == 'mine' then
  616.                 local status, res = pcall(mineTunnel, obj, ws)
  617.                 ws.send(json.encode({data="end", nonce=obj.nonce}))
  618.             end
  619.         end
  620.     end
  621.     if ws then
  622.         ws.close()
  623.     end
  624. end
  625.  
  626. while true do
  627.     local status, res = pcall(websocketLoop)
  628.     term.clear()
  629.     term.setCursorPos(1,1)
  630.     if res == 'Terminated' then
  631.         print("You can't use straws to kill this turtle...")
  632.         break
  633.     end
  634.     print(".i. I'm sleeping... please don't mine me :)")
  635.     os.sleep(5)
  636. end
Add Comment
Please, Sign In to add comment