2Peti

Untitled

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