Advertisement
Guest User

Untitled

a guest
Feb 13th, 2019
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 28.15 KB | None | 0 0
  1. -- This code is licensed under the MIT Open Source License.
  2.  
  3. -- Copyright (c) 2015 Ruairidh Carmichael - ruairidhcarmichael@live.co.uk
  4.  
  5. -- Permission is hereby granted, free of charge, to any person obtaining a copy
  6. -- of this software and associated documentation files (the "Software"), to deal
  7. -- in the Software without restriction, including without limitation the rights
  8. -- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. -- copies of the Software, and to permit persons to whom the Software is
  10. -- furnished to do so, subject to the following conditions:
  11.  
  12. -- The above copyright notice and this permission notice shall be included in
  13. -- all copies or substantial portions of the Software.
  14.  
  15. -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. -- THE SOFTWARE.
  22.  
  23. --local path = (...):match('(.-)[^%.]+$')
  24.  
  25. _VERSION = '0.0.1'
  26. _DESCRIPTION = 'Lua API Wrapper for Discord'
  27.  
  28.  
  29. --if type(client) ~= "table" then os.loadAPI('/discord/client') end
  30. --if type(message) ~= "table" then os.loadAPI('/discord/message') end
  31.  
  32. --Client = client.Client
  33. --Message = message.Message
  34.  
  35. -- Amalgamated source below
  36.  
  37. -- class.lua
  38.  
  39. middleclass = {
  40. _VERSION = 'middleclass v3.1.0',
  41. _DESCRIPTION = 'Object Orientation for Lua',
  42. _URL = 'https://github.com/kikito/middleclass',
  43. _LICENSE = [[
  44. MIT LICENSE
  45.  
  46. Copyright (c) 2011 Enrique García Cota
  47.  
  48. Permission is hereby granted, free of charge, to any person obtaining a
  49. copy of this software and associated documentation files (the
  50. "Software"), to deal in the Software without restriction, including
  51. without limitation the rights to use, copy, modify, merge, publish,
  52. distribute, sublicense, and/or sell copies of the Software, and to
  53. permit persons to whom the Software is furnished to do so, subject to
  54. the following conditions:
  55.  
  56. The above copyright notice and this permission notice shall be included
  57. in all copies or substantial portions of the Software.
  58.  
  59. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  60. OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  61. MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  62. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  63. CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  64. TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  65. SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  66. ]]
  67. }
  68.  
  69. local function _setClassDictionariesMetatables(aClass)
  70. local dict = aClass.__instanceDict
  71. dict.__index = dict
  72.  
  73. local super = aClass.super
  74. if super then
  75. local superStatic = super.static
  76. setmetatable(dict, super.__instanceDict)
  77. setmetatable(aClass.static, { __index = function(_,k) return rawget(dict,k) or superStatic[k] end })
  78. else
  79. setmetatable(aClass.static, { __index = function(_,k) return dict[k] end })
  80. end
  81. end
  82.  
  83. local function _setClassMetatable(aClass)
  84. setmetatable(aClass, {
  85. __tostring = function() return "class " .. aClass.name end,
  86. __index = aClass.static,
  87. __newindex = aClass.__instanceDict,
  88. __call = function(self, ...) return self:new(...) end
  89. })
  90. end
  91.  
  92. local function _createClass(name, super)
  93. local aClass = { name = name, super = super, static = {}, __mixins = {}, __instanceDict={} }
  94. aClass.subclasses = setmetatable({}, {__mode = "k"})
  95.  
  96. _setClassDictionariesMetatables(aClass)
  97. _setClassMetatable(aClass)
  98.  
  99. return aClass
  100. end
  101.  
  102. local function _createLookupMetamethod(aClass, name)
  103. return function(...)
  104. local method = aClass.super[name]
  105. assert( type(method)=='function', tostring(aClass) .. " doesn't implement metamethod '" .. name .. "'" )
  106. return method(...)
  107. end
  108. end
  109.  
  110. local function _setClassMetamethods(aClass)
  111. for _,m in ipairs(aClass.__metamethods) do
  112. aClass[m]= _createLookupMetamethod(aClass, m)
  113. end
  114. end
  115.  
  116. local function _setDefaultInitializeMethod(aClass, super)
  117. aClass.initialize = function(instance, ...)
  118. return super.initialize(instance, ...)
  119. end
  120. end
  121.  
  122. local function _includeMixin(aClass, mixin)
  123. assert(type(mixin)=='table', "mixin must be a table")
  124. for name,method in pairs(mixin) do
  125. if name ~= "included" and name ~= "static" then aClass[name] = method end
  126. end
  127. if mixin.static then
  128. for name,method in pairs(mixin.static) do
  129. aClass.static[name] = method
  130. end
  131. end
  132. if type(mixin.included)=="function" then mixin:included(aClass) end
  133. aClass.__mixins[mixin] = true
  134. end
  135.  
  136. local Object = _createClass("Object", nil)
  137.  
  138. Object.static.__metamethods = { '__add', '__band', '__bor', '__bxor', '__bnot', '__call', '__concat',
  139. '__div', '__eq', '__ipairs', '__idiv', '__le', '__len', '__lt', '__mod',
  140. '__mul', '__pairs', '__pow', '__shl', '__shr', '__sub', '__tostring', '__unm' }
  141.  
  142. function Object.static:allocate()
  143. assert(type(self) == 'table', "Make sure that you are using 'Class:allocate' instead of 'Class.allocate'")
  144. return setmetatable({ class = self }, self.__instanceDict)
  145. end
  146.  
  147. function Object.static:new(...)
  148. local instance = self:allocate()
  149. instance:initialize(...)
  150. return instance
  151. end
  152.  
  153. function Object.static:subclass(name)
  154. assert(type(self) == 'table', "Make sure that you are using 'Class:subclass' instead of 'Class.subclass'")
  155. assert(type(name) == "string", "You must provide a name(string) for your class")
  156.  
  157. local subclass = _createClass(name, self)
  158. _setClassMetamethods(subclass)
  159. _setDefaultInitializeMethod(subclass, self)
  160. self.subclasses[subclass] = true
  161. self:subclassed(subclass)
  162.  
  163. return subclass
  164. end
  165.  
  166. function Object.static:subclassed(other) end
  167.  
  168. function Object.static:isSubclassOf(other)
  169. return type(other) == 'table' and
  170. type(self) == 'table' and
  171. type(self.super) == 'table' and
  172. ( self.super == other or
  173. type(self.super.isSubclassOf) == 'function' and
  174. self.super:isSubclassOf(other)
  175. )
  176. end
  177.  
  178. function Object.static:include( ... )
  179. assert(type(self) == 'table', "Make sure you that you are using 'Class:include' instead of 'Class.include'")
  180. for _,mixin in ipairs({...}) do _includeMixin(self, mixin) end
  181. return self
  182. end
  183.  
  184. function Object.static:includes(mixin)
  185. return type(mixin) == 'table' and
  186. type(self) == 'table' and
  187. type(self.__mixins) == 'table' and
  188. ( self.__mixins[mixin] or
  189. type(self.super) == 'table' and
  190. type(self.super.includes) == 'function' and
  191. self.super:includes(mixin)
  192. )
  193. end
  194.  
  195. function Object:initialize() end
  196.  
  197. function Object:__tostring() return "instance of " .. tostring(self.class) end
  198.  
  199. function Object:isInstanceOf(aClass)
  200. return type(self) == 'table' and
  201. type(self.class) == 'table' and
  202. type(aClass) == 'table' and
  203. ( aClass == self.class or
  204. type(aClass.isSubclassOf) == 'function' and
  205. self.class:isSubclassOf(aClass)
  206. )
  207. end
  208.  
  209.  
  210.  
  211. local function class(name, super, ...)
  212. super = super or Object
  213. return super:subclass(name, ...)
  214. end
  215.  
  216. middleclass.Object = Object
  217.  
  218. setmetatable(middleclass, { __call = function(_, ...) return middleclass.class(...) end })
  219.  
  220.  
  221. -- util.lua
  222.  
  223. function responseIsSuccessful(response)
  224. return response.code ~= nil and response.code >= 200 and response.code < 300
  225. end
  226.  
  227. -- endpoints.lua
  228.  
  229. local endpoints = {}
  230. endpoints.base = 'https://discordapp.com'
  231. endpoints.apiBase = endpoints.base .. '/api'
  232. endpoints.gateway = endpoints.apiBase .. '/gateway'
  233. endpoints.users = endpoints.apiBase .. '/users'
  234. endpoints.register = endpoints.apiBase .. '/auth/register'
  235. endpoints.login = endpoints.apiBase .. '/auth/login'
  236. endpoints.logout = endpoints.apiBase .. '/auth/logout'
  237. endpoints.servers = endpoints.apiBase .. '/guilds'
  238. endpoints.channels = endpoints.apiBase .. '/channels'
  239.  
  240. -- json.lua
  241.  
  242. --
  243. -- json.lua
  244. --
  245. -- Copyright (c) 2015 rxi
  246. --
  247. -- This library is free software; you can redistribute it and/or modify it
  248. -- under the terms of the MIT license. See LICENSE for details.
  249. --
  250.  
  251. _version = "0.1.0"
  252.  
  253. -- Encode
  254.  
  255. local encode
  256.  
  257. local escape_char_map = {
  258. [ "\\" ] = "\\\\",
  259. [ "\"" ] = "\\\"",
  260. [ "\b" ] = "\\b",
  261. [ "\f" ] = "\\f",
  262. [ "\n" ] = "\\n",
  263. [ "\r" ] = "\\r",
  264. [ "\t" ] = "\\t",
  265. }
  266.  
  267. local escape_char_map_inv = { [ "\\/" ] = "/" }
  268. for k, v in pairs(escape_char_map) do
  269. escape_char_map_inv[v] = k
  270. end
  271.  
  272.  
  273. local function escape_char(c)
  274. return escape_char_map[c] or string.format("\\u%04x", c:byte())
  275. end
  276.  
  277.  
  278. local function encode_nil(val)
  279. return "null"
  280. end
  281.  
  282.  
  283. local function encode_table(val, stack)
  284. local res = {}
  285. stack = stack or {}
  286.  
  287. -- Circular reference?
  288. if stack[val] then error("circular reference") end
  289.  
  290. stack[val] = true
  291.  
  292. if val[1] ~= nil or next(val) == nil then
  293. -- Treat as array -- check keys are valid and it is not sparse
  294. local n = 0
  295. for k in pairs(val) do
  296. if type(k) ~= "number" then
  297. error("invalid table: mixed or invalid key types")
  298. end
  299. n = n + 1
  300. end
  301. if n ~= #val then
  302. error("invalid table: sparse array")
  303. end
  304. -- Encode
  305. for i, v in ipairs(val) do
  306. table.insert(res, encode(v, stack))
  307. end
  308. stack[val] = nil
  309. return "[" .. table.concat(res, ",") .. "]"
  310.  
  311. else
  312. -- Treat as an object
  313. for k, v in pairs(val) do
  314. if type(k) ~= "string" then
  315. error("invalid table: mixed or invalid key types")
  316. end
  317. table.insert(res, encode(k, stack) .. ":" .. encode(v, stack))
  318. end
  319. stack[val] = nil
  320. return "{" .. table.concat(res, ",") .. "}"
  321. end
  322. end
  323.  
  324.  
  325. local function encode_string(val)
  326. return '"' .. val:gsub('[%z\1-\31\\"]', escape_char) .. '"'
  327. end
  328.  
  329.  
  330. local function encode_number(val)
  331. -- Check for NaN, -inf and inf
  332. if val ~= val or val <= -math.huge or val >= math.huge then
  333. error("unexpected number value '" .. tostring(val) .. "'")
  334. end
  335. return string.format("%.14g", val)
  336. end
  337.  
  338.  
  339. local type_func_map = {
  340. [ "nil" ] = encode_nil,
  341. [ "table" ] = encode_table,
  342. [ "string" ] = encode_string,
  343. [ "number" ] = encode_number,
  344. [ "boolean" ] = tostring,
  345. }
  346.  
  347.  
  348. local encode = function(val, stack)
  349. local t = type(val)
  350. local f = type_func_map[t]
  351. if f then
  352. return f(val, stack)
  353. end
  354. error("unexpected type '" .. t .. "'")
  355. end
  356.  
  357.  
  358. local function encode(val)
  359. return ( encode(val) )
  360. end
  361.  
  362. -- Decode
  363.  
  364. local parse
  365.  
  366. local function create_set(...)
  367. local res = {}
  368. for i = 1, select("#", ...) do
  369. res[ select(i, ...) ] = true
  370. end
  371. return res
  372. end
  373.  
  374. local space_chars = create_set(" ", "\t", "\r", "\n")
  375. local delim_chars = create_set(" ", "\t", "\r", "\n", "]", "}", ",")
  376. local escape_chars = create_set("\\", "/", '"', "b", "f", "n", "r", "t", "u")
  377. local literals = create_set("true", "false", "null")
  378.  
  379. local literal_map = {
  380. [ "true" ] = true,
  381. [ "false" ] = false,
  382. [ "null" ] = nil,
  383. }
  384.  
  385.  
  386. local function next_char(str, idx, set, negate)
  387. for i = idx, #str do
  388. if set[str:sub(i, i)] ~= negate then
  389. return i
  390. end
  391. end
  392. return #str + 1
  393. end
  394.  
  395.  
  396. local function decode_error(str, idx, msg)
  397. local line_count = 1
  398. local col_count = 1
  399. for i = 1, idx - 1 do
  400. col_count = col_count + 1
  401. if str:sub(i, i) == "\n" then
  402. line_count = line_count + 1
  403. col_count = 1
  404. end
  405. end
  406. error( string.format("%s at line %d col %d", msg, line_count, col_count) )
  407. end
  408.  
  409.  
  410. local function codepoint_to_utf8(n)
  411. -- http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=iws-appendixa
  412. local f = math.floor
  413. if n <= 0x7f then
  414. return string.char(n)
  415. elseif n <= 0x7ff then
  416. return string.char(f(n / 64) + 192, n % 64 + 128)
  417. elseif n <= 0xffff then
  418. return string.char(f(n / 4096) + 224, f(n % 4096 / 64) + 128, n % 64 + 128)
  419. elseif n <= 0x10ffff then
  420. return string.char(f(n / 262144) + 240, f(n % 262144 / 4096) + 128,
  421. f(n % 4096 / 64) + 128, n % 64 + 128)
  422. end
  423. error( string.format("invalid unicode codepoint '%x'", n) )
  424. end
  425.  
  426.  
  427. local function parse_unicode_escape(s)
  428. local n1 = tonumber( s:sub(3, 6), 16 )
  429. local n2 = tonumber( s:sub(9, 12), 16 )
  430. -- Surrogate pair?
  431. if n2 then
  432. return codepoint_to_utf8((n1 - 0xd800) * 0x400 + (n2 - 0xdc00) + 0x10000)
  433. else
  434. return codepoint_to_utf8(n1)
  435. end
  436. end
  437.  
  438.  
  439. local function parse_string(str, i)
  440. local has_unicode_escape = false
  441. local has_surrogate_escape = false
  442. local has_escape = false
  443. local last
  444. for j = i + 1, #str do
  445. local x = str:byte(j)
  446.  
  447. if x < 32 then
  448. decode_error(str, j, "control character in string")
  449. end
  450.  
  451. if last == 92 then -- "\\" (escape char)
  452. if x == 117 then -- "u" (unicode escape sequence)
  453. local hex = str:sub(j + 1, j + 5)
  454. if not hex:find("%x%x%x%x") then
  455. decode_error(str, j, "invalid unicode escape in string")
  456. end
  457. if hex:find("^[dD][89aAbB]") then
  458. has_surrogate_escape = true
  459. else
  460. has_unicode_escape = true
  461. end
  462. else
  463. local c = string.char(x)
  464. if not escape_chars[c] then
  465. decode_error(str, j, "invalid escape char '" .. c .. "' in string")
  466. end
  467. has_escape = true
  468. end
  469. last = nil
  470.  
  471. elseif x == 34 then -- '"' (end of string)
  472. local s = str:sub(i + 1, j - 1)
  473. if has_surrogate_escape then
  474. s = s:gsub("\\u[dD][89aAbB]..\\u....", parse_unicode_escape)
  475. end
  476. if has_unicode_escape then
  477. s = s:gsub("\\u....", parse_unicode_escape)
  478. end
  479. if has_escape then
  480. s = s:gsub("\\.", escape_char_map_inv)
  481. end
  482. return s, j + 1
  483.  
  484. else
  485. last = x
  486. end
  487. end
  488. decode_error(str, i, "expected closing quote for string")
  489. end
  490.  
  491.  
  492. local function parse_number(str, i)
  493. local x = next_char(str, i, delim_chars)
  494. local s = str:sub(i, x - 1)
  495. local n = tonumber(s)
  496. if not n then
  497. decode_error(str, i, "invalid number '" .. s .. "'")
  498. end
  499. return n, x
  500. end
  501.  
  502.  
  503. local function parse_literal(str, i)
  504. local x = next_char(str, i, delim_chars)
  505. local word = str:sub(i, x - 1)
  506. if not literals[word] then
  507. decode_error(str, i, "invalid literal '" .. word .. "'")
  508. end
  509. return literal_map[word], x
  510. end
  511.  
  512.  
  513. local function parse_array(str, i)
  514. local res = {}
  515. local n = 1
  516. i = i + 1
  517. while 1 do
  518. local x
  519. i = next_char(str, i, space_chars, true)
  520. -- Empty / end of array?
  521. if str:sub(i, i) == "]" then
  522. i = i + 1
  523. break
  524. end
  525. -- Read token
  526. x, i = parse(str, i)
  527. res[n] = x
  528. n = n + 1
  529. -- Next token
  530. i = next_char(str, i, space_chars, true)
  531. local chr = str:sub(i, i)
  532. i = i + 1
  533. if chr == "]" then break end
  534. if chr ~= "," then decode_error(str, i, "expected ']' or ','") end
  535. end
  536. return res, i
  537. end
  538.  
  539.  
  540. local function parse_object(str, i)
  541. local res = {}
  542. i = i + 1
  543. while 1 do
  544. local key, val
  545. i = next_char(str, i, space_chars, true)
  546. -- Empty / end of object?
  547. if str:sub(i, i) == "}" then
  548. i = i + 1
  549. break
  550. end
  551. -- Read key
  552. if str:sub(i, i) ~= '"' then
  553. decode_error(str, i, "expected string for key")
  554. end
  555. key, i = parse(str, i)
  556. -- Read ':' delimiter
  557. i = next_char(str, i, space_chars, true)
  558. if str:sub(i, i) ~= ":" then
  559. decode_error(str, i, "expected ':' after key")
  560. end
  561. i = next_char(str, i + 1, space_chars, true)
  562. -- Read value
  563. val, i = parse(str, i)
  564. -- Set
  565. res[key] = val
  566. -- Next token
  567. i = next_char(str, i, space_chars, true)
  568. local chr = str:sub(i, i)
  569. i = i + 1
  570. if chr == "}" then break end
  571. if chr ~= "," then decode_error(str, i, "expected '}' or ','") end
  572. end
  573. return res, i
  574. end
  575.  
  576.  
  577. local char_func_map = {
  578. [ '"' ] = parse_string,
  579. [ "0" ] = parse_number,
  580. [ "1" ] = parse_number,
  581. [ "2" ] = parse_number,
  582. [ "3" ] = parse_number,
  583. [ "4" ] = parse_number,
  584. [ "5" ] = parse_number,
  585. [ "6" ] = parse_number,
  586. [ "7" ] = parse_number,
  587. [ "8" ] = parse_number,
  588. [ "9" ] = parse_number,
  589. [ "-" ] = parse_number,
  590. [ "t" ] = parse_literal,
  591. [ "f" ] = parse_literal,
  592. [ "n" ] = parse_literal,
  593. [ "[" ] = parse_array,
  594. [ "{" ] = parse_object,
  595. }
  596.  
  597.  
  598. parse = function(str, idx)
  599. local chr = str:sub(idx, idx)
  600. local f = char_func_map[chr]
  601. if f then
  602. return f(str, idx)
  603. end
  604. decode_error(str, idx, "unexpected character '" .. chr .. "'")
  605. end
  606.  
  607.  
  608. local function decode(str)
  609. if type(str) ~= "string" then
  610. error("expected argument of type string, got " .. type(str))
  611. end
  612. return ( parse(str, next_char(str, 1, space_chars, true)) )
  613. end
  614.  
  615.  
  616. -- wrapper.lua
  617.  
  618. local function send(endpoint, method, data, headers)
  619.  
  620. local retval = {}
  621. headers["User-Agent"] = "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1)"
  622. if method == "GET" then
  623. local handle = http.get(endpoint, headers)
  624. if handle == nil then
  625. print("Error in GET request to " .. endpoint)
  626. return {}
  627. end
  628. retval.body = handle.readAll()
  629. retval.headers = headers
  630. retval.set_cookies = {}
  631. retval.code = handle.getResponseCode()
  632. retval.raw_headers = headers
  633. --handle.close()
  634. handle = nil
  635. return retval
  636. elseif method == "POST" then
  637. local handle = http.post(endpoint, textutils.serializeJSON(data), headers)
  638. if handle == nil then
  639. print("Error in POST request to " .. endpoint)
  640. return {}
  641. end
  642. local status, newdata = pcall(handle.readAll)
  643. if not status then
  644. print(newdata)
  645. return
  646. end
  647. retval.body = newdata
  648. retval.headers = headers
  649. retval.set_cookies = {}
  650. retval.code = handle.getResponseCode()
  651. retval.raw_headers = headers
  652. --handle.close()
  653. handle = nil
  654. return retval
  655. else
  656. print("Incorrect method " .. method .. " given")
  657. return {}
  658. end
  659. end
  660.  
  661. -- message.lua
  662.  
  663. -------------------------------------
  664. -- Discord Message Class
  665. -- @module Message
  666.  
  667. -- local path = (...):match('(.-)[^%.]+$')
  668.  
  669. --if type(wrapper) ~= "table" then os.loadAPI('/discord/wrapper') end
  670. --local request = wrapper
  671. --if type(class) ~= "table" then os.loadAPI('/discord/class') end
  672. --if type(json) ~= "table" then os.loadAPI('/discord/json') end
  673. --if type(endpoints) ~= "table" then os.loadAPI('/discord/endpoints') end
  674. --if type(util) ~= "table" then os.loadAPI('/discord/util') end
  675. -- if type() ~= "table" then os.loadAPI('/discord/') end
  676.  
  677. Message = class('MessageObject')
  678.  
  679. --- Internally initialize's the Message class.
  680. --- Please use Message:new(packet, token) instead.
  681. -- @param packet Packet to be sent as the message.
  682. -- @param token Authentication token from login.
  683. function Message:initialize(packet, token)
  684.  
  685. self.packet = packet or {}
  686. self.token = token or ''
  687.  
  688. self.headers = {}
  689. self.headers['authorization'] = self.token
  690. self.headers['Content-Type'] = 'application/json'
  691.  
  692. end
  693.  
  694. --- Edits a sent message.
  695. -- @param msg The new message to replace the old one.
  696. -- @return Response Packet received from Discord
  697. function Message:edit(msg)
  698.  
  699. local payload = {
  700. content = tostring(msg)
  701. }
  702.  
  703. local response = send(endpoints.channels .. '/' .. self.packet.channel_id .. '/messages/' .. self.packet.id, 'PATCH', payload, self.headers)
  704.  
  705. if responseIsSuccessful(response) then
  706. self.packet = decode(response.body)
  707. end
  708.  
  709. return utssl.responseIsSuccessful(response)
  710.  
  711. end
  712.  
  713. --- Deletes a sent message.
  714. -- @return Response Packet received from Discord
  715. function Message:delete()
  716.  
  717. local response = send(endpoints.channels .. '/' .. self.packet.channel_id .. '/messages/' .. self.packet.id, 'DELETE', nil, self.headers)
  718.  
  719. if responseIsSuccessful(response) then
  720. self = nil
  721. end
  722.  
  723. return responseIsSuccessful(response)
  724.  
  725. end
  726.  
  727.  
  728. -- client.lua
  729.  
  730. -- This code is licensed under the MIT Open Source License.
  731.  
  732. -------------------------------------
  733. -- Discord Client Class
  734. -- @module Client
  735.  
  736. -- local path = (...):match('(.-)[^%.]+$')
  737.  
  738. --if type(wrapper) ~= "table" then os.loadAPI('/discord/wrapper') end
  739. --local request = wrapper
  740. --if type(class) ~= "table" then os.loadAPI('/discord/class') end
  741. --if type(json) ~= "table" then os.loadAPI('/discord/json') end
  742. --if type(endpoints) ~= "table" then os.loadAPI('/discord/endpoints') end
  743. --if type(util) ~= "table" then os.loadAPI('/discord/util') end
  744.  
  745. --if type(message) ~= "table" then os.loadAPI('/discord/message') end
  746.  
  747. print('Loaded client')
  748.  
  749. Client = class('ClientObject')
  750.  
  751. --- Internally initialize's the Client class.
  752. --- Please use Client:new(options) instead.
  753. -- @param options Options table (Currently useless.)
  754. function Client:initialize(options)
  755.  
  756. self.isLoggedIn = false
  757. self.options = options
  758. self.token = ''
  759. self.email = ''
  760. self.user = {}
  761.  
  762. self.headers = {}
  763.  
  764. self.headers['authorization'] = self.token
  765. self.headers['Content-Type'] = 'application/json'
  766. self.headers['User-Agent'] = 'Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1)'
  767.  
  768. self.callbacks = {}
  769.  
  770. self.socket = nil
  771.  
  772. end
  773.  
  774. --- Logs the Client into Discord's servers.
  775. --- This is required to use most of the Clients functions.
  776. -- @param email E-mail Address of the account to log in.
  777. -- @param password Password of the account to log in.
  778. -- (WARNING: Do NOT store this password in a GitHub repo or anything of the sorts.)
  779. -- @return True or False depending on success.
  780. function Client:login(email, password)
  781.  
  782. local payload = {
  783. email = email,
  784. password = password
  785. }
  786.  
  787. local response = send(endpoints.login, 'POST', payload, self.headers)
  788. local success = responseIsSuccessful(response)
  789.  
  790. if success then
  791.  
  792. self.token = decode(response.body).token
  793. self.isLoggedIn = true
  794. self.headers['authorization'] = self.token
  795. self.email = email
  796.  
  797. self.user = self:getCurrentUser()
  798.  
  799. end
  800.  
  801. return self.token
  802.  
  803. end
  804.  
  805. function Client:loginWithToken(token)
  806.  
  807. self.token = token
  808. self.isLoggedIn = true
  809. self.headers['authorization'] = token
  810.  
  811. self.user = self:getCurrentUser()
  812.  
  813. return token
  814. end
  815.  
  816. --- Logs the Client out of the Discord server.
  817. --- (This is currently useless/does nothing)
  818. -- @param email E-mail Address of the account to log in.
  819. -- @param password Password of the account to log in.
  820. -- (WARNING: Do NOT store this password in a GitHub repo or anything of the sorts.)
  821. -- @return True or False depending on success.
  822. function Client:logout()
  823.  
  824. if self.isLoggedIn then
  825.  
  826. local payload = {
  827. token = self.token
  828. }
  829.  
  830. local response = send(endpoints.login, 'POST', payload)
  831. local success = responseIsSuccessful(response)
  832.  
  833. if success then
  834. self.isLoggedIn = false
  835. self.token = nil
  836. end
  837.  
  838. return success
  839.  
  840. else
  841. return false
  842. end
  843.  
  844. end
  845.  
  846. --- Gets the current authentication token.
  847. --- (Only if logged in of course.)
  848. -- @return Authentication Token
  849. function Client:getToken()
  850.  
  851. if self.isLoggedIn then
  852. return self.token
  853. else
  854. return nil
  855. end
  856.  
  857. end
  858.  
  859. --- Gets the current Gateway we are connected to.
  860. --- (Only if logged in of course.)
  861. -- @return Gateway URL
  862. function Client:getGateway()
  863.  
  864. if self.isLoggedIn then
  865.  
  866. local response = send(endpoints.gateway, 'GET', nil, self.headers)
  867.  
  868. if responseIsSuccessful(response) then
  869. return decode(response.body).url
  870. else
  871. return nil
  872. end
  873.  
  874. end
  875.  
  876. end
  877.  
  878. --- Gets the current User information.
  879. --- (Only if logged in of course.)
  880. -- @return User Table
  881. function Client:getCurrentUser()
  882.  
  883. if self.isLoggedIn then
  884.  
  885. local response = send(endpoints.users .. '/@me', 'GET', nil, self.headers)
  886. if responseIsSuccessful(response) then
  887. return decode(response.body)
  888. else
  889. return nil
  890. end
  891.  
  892. else
  893. return nil
  894. end
  895.  
  896. end
  897.  
  898. --- Gets the GuildMember information for userid in guild.
  899. -- @param guild The guild of the member.
  900. -- @param userid The id of the user.
  901. -- @return GuildMember Table
  902. function Client:getGuildMember(guild, userid)
  903. if self.isLoggedIn then
  904. local response = send(endpoints.servers .. "/" .. guild .. "/members/" .. userid, 'GET', nil, self.headers)
  905. if responseIsSuccessful(response) then
  906. return decode(response.body)
  907. else
  908. return nil
  909. end
  910. else
  911. return nil
  912. end
  913. end
  914.  
  915. --- Gets roles for a guild.
  916. -- @param guild The guild to find roles.
  917. -- @return Table of roles
  918. function Client:getRoles(guild)
  919. if self.isLoggedIn then
  920. local response = send(endpoints.servers .. "/" .. guild .. "/roles", 'GET', nil, self.headers)
  921. if responseIsSuccessful(response) then
  922. return decode(response.body)
  923. else
  924. return nil
  925. end
  926. else
  927. return nil
  928. end
  929. end
  930.  
  931. --- Gets a table of Servers the current User is connected to.
  932. --- (Only if logged in of course.)
  933. -- @return Server Table
  934. function Client:getServerList()
  935.  
  936. if self.isLoggedIn then
  937.  
  938. local response = send(endpoints.users .. '/@me/guilds', 'GET', nil, self.headers)
  939.  
  940. if responseIsSuccessful(response) then
  941. self.user = decode(response.body)
  942. return decode(response.body)
  943. else
  944. return nil
  945. end
  946.  
  947. else
  948. return nil
  949. end
  950.  
  951. end
  952.  
  953. --- Gets a table of Channels from the provided Server id.
  954. --- (Only if logged in of course.)
  955. -- @param id Server ID
  956. -- @return Channel Table
  957. function Client:getChannelList(id)
  958.  
  959. if self.isLoggedIn then
  960.  
  961. local response = send(endpoints.servers .. '/' .. id .. '/channels', 'GET', nil, self.headers)
  962.  
  963. if responseIsSuccessful(response) then
  964. return decode(response.body)
  965. else
  966. return nil
  967. end
  968.  
  969. else
  970. return nil
  971. end
  972.  
  973. end
  974.  
  975. -- Gets all messages in a channel
  976. -- @param id Channel ID
  977. -- @return Array of messages (NOT Lua Message objects, but Discord internal)
  978. function Client:getMessages(id)
  979. if self.isLoggedIn then
  980. local response = http.get(endpoints.channels .. "/" .. id .. "/messages", self.headers)
  981. if response.getResponseCode() >= 200 and response.getResponseCode() < 300 then
  982. local res = decode(response.readAll())
  983. response.close()
  984. return res
  985. else
  986. return nil
  987. end
  988. else
  989. return nil
  990. end
  991. end
  992.  
  993. --- Sends a Message from the Client to a Channel.
  994. --- (Only if logged in of course.)
  995. -- @param message Message to be sent.
  996. -- @param id ID for Channel to send to.
  997. -- @return Message Class
  998. function Client:sendMessage(message, id)
  999.  
  1000. if self.isLoggedIn then
  1001.  
  1002. local payload = {
  1003. content = tostring(message)
  1004. }
  1005.  
  1006. local response = http.post(endpoints.channels .. '/' .. id .. '/messages', textutils.serializeJSON(payload), self.headers)
  1007.  
  1008. --return :new(decode(response.body), self.token)
  1009. --local ret = decode(response.readAll())
  1010. --response.close()
  1011. return nil
  1012.  
  1013. else
  1014. return nil
  1015. end
  1016.  
  1017. end
  1018.  
  1019. --- Edits a sent Message.
  1020. --- (Only if logged in of course.)
  1021. -- @param message The new message to replace the old one.
  1022. -- @param msgClass Message Class to edit.
  1023. -- @return Message Class
  1024. function Client:editMessage(message, msgClass)
  1025.  
  1026. if self.isLoggedIn then
  1027.  
  1028. msgClass:edit(message)
  1029.  
  1030. end
  1031.  
  1032. end
  1033.  
  1034. --- Deletes a sent Message.
  1035. --- (Only if logged in of course.)
  1036. -- @param msgClass Message Class to delete.
  1037. -- @return Message Class
  1038. function Client:deleteMessage(msgClass)
  1039.  
  1040. if self.isLoggedIn then
  1041.  
  1042. msgClass:delete()
  1043.  
  1044. end
  1045.  
  1046. end
  1047.  
  1048. --- Starts the Client loop.
  1049. --- (Does nothing of real use at the moment, will interact with WebSockets in the future)
  1050. function Client:run()
  1051.  
  1052. if self.isLoggedIn then
  1053.  
  1054. while true do
  1055. if self.callbacks.think then self.callbacks.think() end
  1056.  
  1057. end
  1058.  
  1059. end
  1060.  
  1061. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement