Advertisement
TheRockettek

Untitled

Apr 7th, 2017
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. local nick = "rockettek"
  2. local password = "oauth:c306b08cc06j7foa7uzxez63fyiff4"
  3.  
  4. local base = _G
  5. local decode_scanArray
  6. local decode_scanComment
  7. local decode_scanConstant
  8. local decode_scanNumber
  9. local decode_scanObject
  10. local decode_scanString
  11. local decode_scanWhitespace
  12. local encodeString
  13. local isArray
  14. local isEncodable
  15. local counter = 0
  16. local sessionID = ""
  17.  
  18. local function encode (v)
  19.   -- Handle nil values
  20.   if v==nil then
  21.     return "null"
  22.   end
  23.  
  24.   local vtype = base.type(v)  
  25.  
  26.   -- Handle strings
  27.   if vtype=='string' then    
  28.     return '"' .. encodeString(v) .. '"'            -- Need to handle encoding in string
  29.   end
  30.  
  31.   -- Handle booleans
  32.   if vtype=='number' or vtype=='boolean' then
  33.     return base.tostring(v)
  34.   end
  35.  
  36.   -- Handle tables
  37.   if vtype=='table' then
  38.     local rval = {}
  39.     -- Consider arrays separately
  40.     local bArray, maxCount = isArray(v)
  41.     if bArray then
  42.       for i = 1,maxCount do
  43.         table.insert(rval, encode(v[i]))
  44.       end
  45.     else        -- An object, not an array
  46.       for i,j in base.pairs(v) do
  47.         if isEncodable(i) and isEncodable(j) then
  48.           table.insert(rval, '"' .. encodeString(i) .. '":' .. encode(j))
  49.         end
  50.       end
  51.     end
  52.     if bArray then
  53.       return '[' .. table.concat(rval,',') ..']'
  54.     else
  55.       return '{' .. table.concat(rval,',') .. '}'
  56.     end
  57.   end
  58.  
  59.   -- Handle null values
  60.   if vtype=='function' and v==null then
  61.     return 'null'
  62.   end
  63.  
  64.   base.assert(false,'encode attempt to encode unsupported type ' .. vtype .. ':' .. base.tostring(v))
  65. end
  66.  
  67. local function decode(s, startPos)
  68.   startPos = startPos and startPos or 1
  69.   startPos = decode_scanWhitespace(s,startPos)
  70.   base.assert(startPos<=string.len(s), 'Unterminated JSON encoded object found at position in [' .. s .. ']')
  71.   local curChar = string.sub(s,startPos,startPos)
  72.   -- Object
  73.   if curChar=='{' then
  74.     return decode_scanObject(s,startPos)
  75.   end
  76.   -- Array
  77.   if curChar=='[' then
  78.     return decode_scanArray(s,startPos)
  79.   end
  80.   -- Number
  81.   if string.find("+-0123456789.e", curChar, 1, true) then
  82.     return decode_scanNumber(s,startPos)
  83.   end
  84.   -- String
  85.   if curChar==[["]] or curChar==[[']] then
  86.    return decode_scanString(s,startPos)
  87.  end
  88.  if string.sub(s,startPos,startPos+1)=='/*' then
  89.    return decode(s, decode_scanComment(s,startPos))
  90.  end
  91.  -- Otherwise, it must be a constant
  92.  return decode_scanConstant(s,startPos)
  93. end
  94. local function null()
  95.  return null -- so json.null() will also return null ;-)
  96. end
  97. function decode_scanArray(s,startPos)
  98.  local array = {}      -- The return value
  99.  local stringLen = string.len(s)
  100.  base.assert(string.sub(s,startPos,startPos)=='[','decode_scanArray called but array does not start at position ' .. startPos .. ' in string:\n'..s )
  101.  startPos = startPos + 1
  102.  -- Infinite loop for array elements
  103.  repeat
  104.    startPos = decode_scanWhitespace(s,startPos)
  105.    base.assert(startPos<=stringLen,'JSON String ended unexpectedly scanning array.')
  106.    local curChar = string.sub(s,startPos,startPos)
  107.    if (curChar==']') then
  108.      return array, startPos+1
  109.    end
  110.    if (curChar==',') then
  111.      startPos = decode_scanWhitespace(s,startPos+1)
  112.    end
  113.    base.assert(startPos<=stringLen, 'JSON String ended unexpectedly scanning array.')
  114.    object, startPos = decode(s,startPos)
  115.    table.insert(array,object)
  116.  until false
  117. end
  118. function decode_scanComment(s, startPos)
  119.  base.assert( string.sub(s,startPos,startPos+1)=='/*', "decode_scanComment called but comment does not start at position " .. startPos)
  120.  local endPos = string.find(s,'*/',startPos+2)
  121.  base.assert(endPos~=nil, "Unterminated comment in string at " .. startPos)
  122.  return endPos+2  
  123. end
  124.  
  125. function decode_scanConstant(s, startPos)
  126.  local consts = { ["true"] = true, ["false"] = false, ["null"] = nil }
  127.  local constNames = {"true","false","null"}
  128.  
  129.  for i,k in base.pairs(constNames) do
  130.    --print ("[" .. string.sub(s,startPos, startPos + string.len(k) -1) .."]", k)
  131.    if string.sub(s,startPos, startPos + string.len(k) -1 )==k then
  132.      return consts[k], startPos + string.len(k)
  133.    end
  134.  end
  135.  base.assert(nil, 'Failed to scan constant from string ' .. s .. ' at starting position ' .. startPos)
  136. end
  137. function decode_scanNumber(s,startPos)
  138.  local endPos = startPos+1
  139.  local stringLen = string.len(s)
  140.  local acceptableChars = "+-0123456789.e"
  141.  while (string.find(acceptableChars, string.sub(s,endPos,endPos), 1, true)
  142.        and endPos<=stringLen
  143.        ) do
  144.    endPos = endPos + 1
  145.  end
  146.  local stringValue = 'return ' .. string.sub(s,startPos, endPos-1)
  147.  local stringEval = base.loadstring(stringValue)
  148.  base.assert(stringEval, 'Failed to scan number [ ' .. stringValue .. '] in JSON string at position ' .. startPos .. ' : ' .. endPos)
  149.  return stringEval(), endPos
  150. end
  151. function decode_scanObject(s,startPos)
  152.  local object = {}
  153.  local stringLen = string.len(s)
  154.  local key, value
  155.  base.assert(string.sub(s,startPos,startPos)=='{','decode_scanObject called but object does not start at position ' .. startPos .. ' in string:\n' .. s)
  156.  startPos = startPos + 1
  157.  repeat
  158.    startPos = decode_scanWhitespace(s,startPos)
  159.    base.assert(startPos<=stringLen, 'JSON string ended unexpectedly while scanning object.')
  160.    local curChar = string.sub(s,startPos,startPos)
  161.    if (curChar=='}') then
  162.      return object,startPos+1
  163.    end
  164.    if (curChar==',') then
  165.      startPos = decode_scanWhitespace(s,startPos+1)
  166.    end
  167.    base.assert(startPos<=stringLen, 'JSON string ended unexpectedly scanning object.')
  168.    -- Scan the key
  169.    key, startPos = decode(s,startPos)
  170.    base.assert(startPos<=stringLen, 'JSON string ended unexpectedly searching for value of key ' .. key)
  171.    startPos = decode_scanWhitespace(s,startPos)
  172.    base.assert(startPos<=stringLen, 'JSON string ended unexpectedly searching for value of key ' .. key)
  173.    base.assert(string.sub(s,startPos,startPos)==':','JSON object key-value assignment mal-formed at ' .. startPos)
  174.    startPos = decode_scanWhitespace(s,startPos+1)
  175.    base.assert(startPos<=stringLen, 'JSON string ended unexpectedly searching for value of key ' .. key)
  176.    value, startPos = decode(s,startPos)
  177.    object[key]=value
  178.  until false   -- infinite loop while key-value pairs are found
  179. end
  180. function decode_scanString(s,startPos)
  181.  base.assert(startPos, 'decode_scanString(..) called without start position')
  182.  local startChar = string.sub(s,startPos,startPos)
  183.  base.assert(startChar==[[']] or startChar==[["]],'decode_scanString called for a non-string')
  184.   local escaped = false
  185.   local endPos = startPos + 1
  186.   local bEnded = false
  187.   local stringLen = string.len(s)
  188.   repeat
  189.     local curChar = string.sub(s,endPos,endPos)
  190.     -- Character escaping is only used to escape the string delimiters
  191.     if not escaped then
  192.       if curChar==[[\]] then
  193.         escaped = true
  194.       else
  195.         bEnded = curChar==startChar
  196.       end
  197.     else
  198.       -- If we're escaped, we accept the current character come what may
  199.       escaped = false
  200.     end
  201.     endPos = endPos + 1
  202.     base.assert(endPos <= stringLen+1, "String decoding failed: unterminated string at position " .. endPos)
  203.   until bEnded
  204.   local stringValue = 'return ' .. string.sub(s, startPos, endPos-1)
  205.   local stringEval = base.loadstring(stringValue)
  206.   base.assert(stringEval, 'Failed to load string [ ' .. stringValue .. '] in JSON4Lua.decode_scanString at position ' .. startPos .. ' : ' .. endPos)
  207.   return stringEval(), endPos  
  208. end
  209. function decode_scanWhitespace(s,startPos)
  210.   local whitespace=" \n\r\t"
  211.   local stringLen = string.len(s)
  212.   while ( string.find(whitespace, string.sub(s,startPos,startPos), 1, true)  and startPos <= stringLen) do
  213.     startPos = startPos + 1
  214.   end
  215.   return startPos
  216. end
  217. function encodeString(s)
  218.   s = string.gsub(s,'\\','\\\\')
  219.   s = string.gsub(s,'"','\\"')
  220.   s = string.gsub(s,'\n','\\n')
  221.   s = string.gsub(s,'\t','\\t')
  222.   return s
  223. end
  224. function isArray(t)
  225.   -- Next we count all the elements, ensuring that any non-indexed elements are not-encodable
  226.   -- (with the possible exception of 'n')
  227.   local maxIndex = 0
  228.   for k,v in base.pairs(t) do
  229.     if (base.type(k)=='number' and math.floor(k)==k and 1<=k) then      -- k,v is an indexed pair
  230.       if (not isEncodable(v)) then return false end     -- All array elements must be encodable
  231.       maxIndex = math.max(maxIndex,k)
  232.     else
  233.       if (k=='n') then
  234.         if v ~= table.getn(t) then return false end  -- False if n does not hold the number of elements
  235.       else -- Else of (k=='n')
  236.         if isEncodable(v) then return false end
  237.       end  -- End of (k~='n')
  238.     end -- End of k,v not an indexed pair
  239.   end  -- End of loop across all pairs
  240.   return true, maxIndex
  241. end
  242. function isEncodable(o)
  243.   local t = base.type(o)
  244.   return (t=='string' or t=='boolean' or t=='number' or t=='nil' or t=='table') or (t=='function' and o==null)
  245. end
  246.  
  247. local post = function(url,data)
  248.     local cacheAvoidance = "abc"..tostring(math.random(0,10000)) -- not sure if this is needed...
  249.     local resp = http.post("http://86.11.11.101:9090/e/"..url,"r="..cacheAvoidance.."&t="..tostring(counter)..data)
  250.     counter = counter + 1
  251.     return resp
  252. end
  253.  
  254. -- better responsiveness with asynchronous methods as we usually let the recv couroutine handle the responses
  255. local request = function(url,data)
  256.     local cacheAvoidance = "abc"..tostring(math.random(0,10000)) -- not sure if this is needed...
  257.     http.request("http://86.11.11.101:9090/e/"..url,"r="..cacheAvoidance.."&t="..tostring(counter)..data)
  258.     counter = counter + 1
  259. end
  260.  
  261. -- these special URLs are used by the webchat server for different methods
  262. local send = function(data)
  263.     return request("p","&s="..sessionID.."&c="..textutils.urlEncode(data))
  264. end
  265.  
  266. local recv = function()
  267.     return post("s","&s="..sessionID)
  268. end
  269.  
  270. local connect = function(password)
  271.   if password ~= nil then
  272.     return post("n","&nick="..nick.."&password="..password)
  273.   else
  274.     return post("n","&nick="..nick)
  275.   end
  276. end
  277.  
  278. local pong = function(data)
  279.     return send("PONG :"..data)
  280. end
  281.  
  282. local quit = function(_reason)
  283.     local reason = _reason or ""
  284.     return send("QUIT :"..reason)
  285. end
  286.  
  287. -- lua default string methods suck :/
  288. local split = function(str,sep)
  289.         local sep, fields = sep or ":", {}
  290.         local pattern = string.format("([^%s]+)", sep)
  291.         str:gsub(pattern, function(c) fields[#fields+1] = c end)
  292.         return fields
  293. end
  294.  
  295. --[[
  296. local handleResponse = function(data)
  297.     for i = 1, #data do
  298.         local id = data[i][2]
  299.         if id == "PING" then
  300.             pong(data[i][4][1])
  301.         elseif id == "PRIVMSG" then
  302.             local senderDetails = data[i][3]
  303.             local sender = senderDetails:sub(1,senderDetails:find("!")-1)
  304.             local channel = data[i][4][1]:lower()
  305.             if channel == nick then
  306.                 channel = sender
  307.             end
  308.             local msg = data[i][4][2]
  309.             --exec
  310.             print("<"..sender.."> "..msg)
  311.         end
  312.         print("<"..sender.."> "..msg)
  313.     end
  314. end
  315. ]]
  316.  
  317. local handleResponse = function(data)
  318.         print(textutils.serialize(data))
  319.         for i = 1, #data do
  320.                 local id = data[i][2]
  321.                 if id == "PING" then
  322.                         pong(data[i][4][1])
  323.                 elseif id == "PRIVMSG" then
  324.                         local senderDetails = data[i][3]
  325.                         local sender = senderDetails:sub(1,senderDetails:find("!")-1)
  326.                         local channel = data[i][4][1]:lower()
  327.                         print(textutils.serialize(data[i]))
  328.                         print(channel)
  329.                         local msg = data[i][4][2]
  330.                         print("<"..sender.."> "..msg)
  331.                 else
  332.                         print(data[i])
  333.                 end
  334.         end
  335. end
  336.  
  337.  
  338. print("Connecting...")
  339. resp = connect(password)
  340. --if not resp then term.clear() term.setCursorPos(1,1) term.write("Unable to connect to IRC bridge!") os.pullEvent() os.reboot() end
  341. _data = resp.readAll()
  342. data = decode(_data)
  343. sessionID = data[2]
  344. print("Got sessionID: "..sessionID)
  345.  
  346. send("JOIN #rockettek")
  347.  
  348. local receive = function()
  349.     resp = recv()
  350.     while resp do
  351.         _data = resp.readAll()
  352.         if #_data > 0 then
  353.             data = decode(_data)
  354.             handleResponse(data)
  355.         end
  356.         resp = recv()
  357.     end
  358. end
  359.  
  360. receive()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement