From 7f68524d5a610cfb84303f5691d69ea35e4011fb Mon Sep 17 00:00:00 2001 From: Ertu Date: Sat, 17 Apr 2021 12:20:00 +0300 Subject: [PATCH] Add DB + some things --- cmds/eval.lua | 1 + config.lua | 2 +- db/.gitignore | 4 + db/db.lua | 73 ++++++ db/mp.lua | 634 +++++++++++++++++++++++++++++++++++++++++++++ events/command.lua | 5 +- events/ready.lua | 5 + init.lua | 29 ++- tg/api.lua | 4 + tg/core.lua | 55 ++-- tg/tools.lua | 7 +- 11 files changed, 789 insertions(+), 30 deletions(-) create mode 100644 db/.gitignore create mode 100644 db/db.lua create mode 100644 db/mp.lua diff --git a/cmds/eval.lua b/cmds/eval.lua index 00fced7..ec342d4 100644 --- a/cmds/eval.lua +++ b/cmds/eval.lua @@ -28,6 +28,7 @@ local env = { } return { + private = true, args = '', desc = 'evaluates code', run = function(C, msg, owner) diff --git a/config.lua b/config.lua index 2b06f5f..ca07dba 100644 --- a/config.lua +++ b/config.lua @@ -1,6 +1,6 @@ return { token = 'atokenyanedam', - owner = 'Er2Official', -- hehe + owner = 935626920 , -- hehe cmds = { 'eval', 'rub', diff --git a/db/.gitignore b/db/.gitignore new file mode 100644 index 0000000..becae58 --- /dev/null +++ b/db/.gitignore @@ -0,0 +1,4 @@ +* +!.gitignore +!db.lua +!mp.lua \ No newline at end of file diff --git a/db/db.lua b/db/db.lua new file mode 100644 index 0000000..8073f22 --- /dev/null +++ b/db/db.lua @@ -0,0 +1,73 @@ +local mp = require 'db.mp' + +local tools = { + isFile = function(path) + local f = io.open(path, 'r') + if not f then return false end + f:close() + return true + end, + isDir = function(path) + path = (path .. '/'):gsub('//', '/') + local o, _, c = os.rename(path, path) + return o or c == 13 + end, + + loadPg = function(db, k) + local f = io.open(db._path .. '/' .. k, 'rb') + if not f then return end + + local res = mp.unpack(f:read '*a') + f:close() + return res + end, + + savePg = function(db, k, page) + if type(k) == 'string' and k:sub(1, 1) == '_' then return '_' end + local f = io.open(db._path .. '/' .. k, 'wb') + if type(page) ~= 'table' or not f then return false end + + f:write(mp.pack(page)) + f:close() + return true + end, +} + +local dbInt = { + save = function(db, p) + if p then + if type(p) ~= 'string' or type(db[p]) ~= 'table' then return false end + return tools.savePg(db, p, db[p]) + end + for p, con in pairs(db) do + if not tools.savePg(db, p, con) then return false end + end + return true + end, +} + +local _db = { + __index = function(db, k) + if dbInt[k] then return dbInt[k] end + if tools.isFile(db._path .. '/' .. k) then + db[k] = tools.loadPg(db, k) + end + return rawget(db, k) + end, + __newindex = function(db, k, v) + if type(k) ~= 'string' or type(v) == 'function' then return end + if k:sub(1, 1) == '_' then return end + return rawset(db, k, v) + end +} + +return setmetatable({}, { + __mode = 'kv', + __call = function(self, path) + assert(tools.isDir(path), path .. ' is not a directory') + if self[path] then return self[path] end + local db = setmetatable({_path = path}, _db) + self[path] = db + return db + end +}) diff --git a/db/mp.lua b/db/mp.lua new file mode 100644 index 0000000..7f7ea97 --- /dev/null +++ b/db/mp.lua @@ -0,0 +1,634 @@ +-- lua-MessagePack +-- MIT/X11 License + +local char = require'string'.char +local format = require'string'.format +local math_type = require'math'.type +local tointeger = require'math'.tointeger +local tconcat = require'table'.concat +local pack = require'string'.pack +local unpack = require'string'.unpack +local m = {} + +--[[ debug only +local function hexadump (s) + return (s:gsub('.', function (c) return format('%02X ', c:byte()) end)) +end +m.hexadump = hexadump +--]] + +local function argerror (caller, narg, extramsg) + error("bad argument #" .. tostring(narg) .. " to " + .. caller .. " (" .. extramsg .. ")") +end + +local function typeerror (caller, narg, arg, tname) + argerror(caller, narg, tname .. " expected, got " .. type(arg)) +end + +local function checktype (caller, narg, arg, tname) + if type(arg) ~= tname then + typeerror(caller, narg, arg, tname) + end +end + +local packers = setmetatable({}, { + __index = function (t, k) + if k == 1 then return end -- allows ipairs + error("pack '" .. k .. "' is unimplemented") + end +}) +m.packers = packers + +packers['nil'] = function (buffer) + buffer[#buffer+1] = char(0xC0) -- nil +end + +packers['boolean'] = function (buffer, bool) + if bool then + buffer[#buffer+1] = char(0xC3) -- true + else + buffer[#buffer+1] = char(0xC2) -- false + end +end + +packers['string_compat'] = function (buffer, str) + local n = #str + if n <= 0x1F then + buffer[#buffer+1] = char(0xA0 + n) -- fixstr + elseif n <= 0xFFFF then + buffer[#buffer+1] = pack('>B I2', 0xDA, n) -- str16 + elseif n <= 0xFFFFFFFF.0 then + buffer[#buffer+1] = pack('>B I4', 0xDB, n) -- str32 + else + error"overflow in pack 'string_compat'" + end + buffer[#buffer+1] = str +end + +packers['_string'] = function (buffer, str) + local n = #str + if n <= 0x1F then + buffer[#buffer+1] = char(0xA0 + n) -- fixstr + elseif n <= 0xFF then + buffer[#buffer+1] = char(0xD9, n) -- str8 + elseif n <= 0xFFFF then + buffer[#buffer+1] = pack('>B I2', 0xDA, n) -- str16 + elseif n <= 0xFFFFFFFF.0 then + buffer[#buffer+1] = pack('>B I4', 0xDB, n) -- str32 + else + error"overflow in pack 'string'" + end + buffer[#buffer+1] = str +end + +packers['binary'] = function (buffer, str) + local n = #str + if n <= 0xFF then + buffer[#buffer+1] = char(0xC4, n) -- bin8 + elseif n <= 0xFFFF then + buffer[#buffer+1] = pack('>B I2', 0xC5, n) -- bin16 + elseif n <= 0xFFFFFFFF.0 then + buffer[#buffer+1] = pack('>B I4', 0xC6, n) -- bin32 + else + error"overflow in pack 'binary'" + end + buffer[#buffer+1] = str +end + +local set_string = function (str) + if str == 'string_compat' then + packers['string'] = packers['string_compat'] + elseif str == 'string' then + packers['string'] = packers['_string'] + elseif str == 'binary' then + packers['string'] = packers['binary'] + else + argerror('set_string', 1, "invalid option '" .. str .."'") + end +end +m.set_string = set_string + +packers['map'] = function (buffer, tbl, n) + if n <= 0x0F then + buffer[#buffer+1] = char(0x80 + n) -- fixmap + elseif n <= 0xFFFF then + buffer[#buffer+1] = pack('>B I2', 0xDE, n) -- map16 + elseif n <= 0xFFFFFFFF.0 then + buffer[#buffer+1] = pack('>B I4', 0xDF, n) -- map32 + else + error"overflow in pack 'map'" + end + for k, v in pairs(tbl) do + packers[type(k)](buffer, k) + packers[type(v)](buffer, v) + end +end + +packers['array'] = function (buffer, tbl, n) + if n <= 0x0F then + buffer[#buffer+1] = char(0x90 + n) -- fixarray + elseif n <= 0xFFFF then + buffer[#buffer+1] = pack('>B I2', 0xDC, n) -- array16 + elseif n <= 0xFFFFFFFF.0 then + buffer[#buffer+1] = pack('>B I4', 0xDD, n) -- array32 + else + error"overflow in pack 'array'" + end + for i = 1, n do + local v = tbl[i] + packers[type(v)](buffer, v) + end +end + +local set_array = function (array) + if array == 'without_hole' then + packers['_table'] = function (buffer, tbl) + local is_map, n, max = false, 0, 0 + for k in pairs(tbl) do + if type(k) == 'number' and k > 0 then + if k > max then + max = k + end + else + is_map = true + end + n = n + 1 + end + if max ~= n then -- there are holes + is_map = true + end + if is_map then + packers['map'](buffer, tbl, n) + else + packers['array'](buffer, tbl, n) + end + end + elseif array == 'with_hole' then + packers['_table'] = function (buffer, tbl) + local is_map, n, max = false, 0, 0 + for k in pairs(tbl) do + if type(k) == 'number' and k > 0 then + if k > max then + max = k + end + else + is_map = true + end + n = n + 1 + end + if is_map then + packers['map'](buffer, tbl, n) + else + packers['array'](buffer, tbl, max) + end + end + elseif array == 'always_as_map' then + packers['_table'] = function(buffer, tbl) + local n = 0 + for k in pairs(tbl) do + n = n + 1 + end + packers['map'](buffer, tbl, n) + end + else + argerror('set_array', 1, "invalid option '" .. array .."'") + end +end +m.set_array = set_array + +packers['table'] = function (buffer, tbl) + packers['_table'](buffer, tbl) +end + +packers['unsigned'] = function (buffer, n) + if n >= 0 then + if n <= 0x7F then + buffer[#buffer+1] = char(n) -- fixnum_pos + elseif n <= 0xFF then + buffer[#buffer+1] = char(0xCC, n) -- uint8 + elseif n <= 0xFFFF then + buffer[#buffer+1] = pack('>B I2', 0xCD, n) -- uint16 + elseif n <= 0xFFFFFFFF.0 then + buffer[#buffer+1] = pack('>B I4', 0xCE, n) -- uint32 + else + buffer[#buffer+1] = pack('>B I8', 0xCF, n) -- uint64 + end + else + if n >= -0x20 then + buffer[#buffer+1] = char(0x100 + n) -- fixnum_neg + elseif n >= -0x80 then + buffer[#buffer+1] = pack('>B i1', 0xD0, n) -- int8 + elseif n >= -0x8000 then + buffer[#buffer+1] = pack('>B i2', 0xD1, n) -- int16 + elseif n >= -0x80000000 then + buffer[#buffer+1] = pack('>B i4', 0xD2, n) -- int32 + else + buffer[#buffer+1] = pack('>B i8', 0xD3, n) -- int64 + end + end +end + +packers['signed'] = function (buffer, n) + if n >= 0 then + if n <= 0x7F then + buffer[#buffer+1] = char(n) -- fixnum_pos + elseif n <= 0x7FFF then + buffer[#buffer+1] = pack('>B i2', 0xD1, n) -- int16 + elseif n <= 0x7FFFFFFF then + buffer[#buffer+1] = pack('>B i4', 0xD2, n) -- int32 + else + buffer[#buffer+1] = pack('>B i8', 0xD3, n) -- int64 + end + else + if n >= -0x20 then + buffer[#buffer+1] = char(0xE0 + 0x20 + n) -- fixnum_neg + elseif n >= -0x80 then + buffer[#buffer+1] = pack('>B i1', 0xD0, n) -- int8 + elseif n >= -0x8000 then + buffer[#buffer+1] = pack('>B i2', 0xD1, n) -- int16 + elseif n >= -0x80000000 then + buffer[#buffer+1] = pack('>B i4', 0xD2, n) -- int32 + else + buffer[#buffer+1] = pack('>B i8', 0xD3, n) -- int64 + end + end +end + +local set_integer = function (integer) + if integer == 'unsigned' then + packers['integer'] = packers['unsigned'] + elseif integer == 'signed' then + packers['integer'] = packers['signed'] + else + argerror('set_integer', 1, "invalid option '" .. integer .."'") + end +end +m.set_integer = set_integer + +packers['float'] = function (buffer, n) + buffer[#buffer+1] = pack('>B f', 0xCA, n) +end + +packers['double'] = function (buffer, n) + buffer[#buffer+1] = pack('>B d', 0xCB, n) +end + +local set_number = function (number) + if number == 'float' then + packers['number'] = function (buffer, n) + if math_type(n) == 'integer' then + packers['integer'](buffer, n) + else + packers['float'](buffer, n) + end + end + elseif number == 'double' then + packers['number'] = function (buffer, n) + if math_type(n) == 'integer' then + packers['integer'](buffer, n) + else + packers['double'](buffer, n) + end + end + else + argerror('set_number', 1, "invalid option '" .. number .."'") + end +end +m.set_number = set_number + +for k = 0, 4 do + local n = tointeger(2^k) + local fixext = 0xD4 + k + packers['fixext' .. tostring(n)] = function (buffer, tag, data) + assert(#data == n, "bad length for fixext" .. tostring(n)) + buffer[#buffer+1] = pack('>B i1', fixext, tag) + buffer[#buffer+1] = data + end +end + +packers['ext'] = function (buffer, tag, data) + local n = #data + if n <= 0xFF then + buffer[#buffer+1] = pack('>B B i1', 0xC7, n, tag) -- ext8 + elseif n <= 0xFFFF then + buffer[#buffer+1] = pack('>B I2 i1', 0xC8, n, tag) -- ext16 + elseif n <= 0xFFFFFFFF.0 then + buffer[#buffer+1] = pack('>B I4 i1', 0xC9, n, tag) -- ext32 + else + error"overflow in pack 'ext'" + end + buffer[#buffer+1] = data +end + +function m.pack (data) + local buffer = {} + packers[type(data)](buffer, data) + return tconcat(buffer) +end + + +local unpackers -- forward declaration + +local function unpack_cursor (c) + local s, i, j = c.s, c.i, c.j + if i > j then + c:underflow(i) + s, i, j = c.s, c.i, c.j + end + local val = s:byte(i) + c.i = i+1 + return unpackers[val](c, val) +end +m.unpack_cursor = unpack_cursor + +local function unpack_str (c, n) + local s, i, j = c.s, c.i, c.j + local e = i+n-1 + if e > j or n < 0 then + c:underflow(e) + s, i, j = c.s, c.i, c.j + e = i+n-1 + end + c.i = i+n + return s:sub(i, e) +end + +local function unpack_array (c, n) + local t = {} + for i = 1, n do + t[i] = unpack_cursor(c) + end + return t +end + +local function unpack_map (c, n) + local t = {} + for i = 1, n do + local k = unpack_cursor(c) + local val = unpack_cursor(c) + if k == nil or k ~= k then + k = m.sentinel + end + if k ~= nil then + t[k] = val + end + end + return t +end + +local function unpack_float (c) + local s, i, j = c.s, c.i, c.j + if i+3 > j then + c:underflow(i+3) + s, i, j = c.s, c.i, c.j + end + c.i = i+4 + return unpack('>f', s, i) +end + +local function unpack_double (c) + local s, i, j = c.s, c.i, c.j + if i+7 > j then + c:underflow(i+7) + s, i, j = c.s, c.i, c.j + end + c.i = i+8 + return unpack('>d', s, i) +end + +local function unpack_uint8 (c) + local s, i, j = c.s, c.i, c.j + if i > j then + c:underflow(i) + s, i, j = c.s, c.i, c.j + end + c.i = i+1 + return unpack('>I1', s, i) +end + +local function unpack_uint16 (c) + local s, i, j = c.s, c.i, c.j + if i+1 > j then + c:underflow(i+1) + s, i, j = c.s, c.i, c.j + end + c.i = i+2 + return unpack('>I2', s, i) +end + +local function unpack_uint32 (c) + local s, i, j = c.s, c.i, c.j + if i+3 > j then + c:underflow(i+3) + s, i, j = c.s, c.i, c.j + end + c.i = i+4 + return unpack('>I4', s, i) +end + +local function unpack_uint64 (c) + local s, i, j = c.s, c.i, c.j + if i+7 > j then + c:underflow(i+7) + s, i, j = c.s, c.i, c.j + end + c.i = i+8 + return unpack('>I8', s, i) +end + +local function unpack_int8 (c) + local s, i, j = c.s, c.i, c.j + if i > j then + c:underflow(i) + s, i, j = c.s, c.i, c.j + end + c.i = i+1 + return unpack('>i1', s, i) +end + +local function unpack_int16 (c) + local s, i, j = c.s, c.i, c.j + if i+1 > j then + c:underflow(i+1) + s, i, j = c.s, c.i, c.j + end + c.i = i+2 + return unpack('>i2', s, i) +end + +local function unpack_int32 (c) + local s, i, j = c.s, c.i, c.j + if i+3 > j then + c:underflow(i+3) + s, i, j = c.s, c.i, c.j + end + c.i = i+4 + return unpack('>i4', s, i) +end + +local function unpack_int64 (c) + local s, i, j = c.s, c.i, c.j + if i+7 > j then + c:underflow(i+7) + s, i, j = c.s, c.i, c.j + end + c.i = i+8 + return unpack('>i8', s, i) +end + +function m.build_ext (tag, data) + return nil +end + +local function unpack_ext (c, n, tag) + local s, i, j = c.s, c.i, c.j + local e = i+n-1 + if e > j or n < 0 then + c:underflow(e) + s, i, j = c.s, c.i, c.j + e = i+n-1 + end + c.i = i+n + return m.build_ext(tag, s:sub(i, e)) +end + +unpackers = setmetatable({ + [0xC0] = function () return nil end, + [0xC2] = function () return false end, + [0xC3] = function () return true end, + [0xC4] = function (c) return unpack_str(c, unpack_uint8(c)) end, -- bin8 + [0xC5] = function (c) return unpack_str(c, unpack_uint16(c)) end, -- bin16 + [0xC6] = function (c) return unpack_str(c, unpack_uint32(c)) end, -- bin32 + [0xC7] = function (c) return unpack_ext(c, unpack_uint8(c), unpack_int8(c)) end, + [0xC8] = function (c) return unpack_ext(c, unpack_uint16(c), unpack_int8(c)) end, + [0xC9] = function (c) return unpack_ext(c, unpack_uint32(c), unpack_int8(c)) end, + [0xCA] = unpack_float, + [0xCB] = unpack_double, + [0xCC] = unpack_uint8, + [0xCD] = unpack_uint16, + [0xCE] = unpack_uint32, + [0xCF] = unpack_uint64, + [0xD0] = unpack_int8, + [0xD1] = unpack_int16, + [0xD2] = unpack_int32, + [0xD3] = unpack_int64, + [0xD4] = function (c) return unpack_ext(c, 1, unpack_int8(c)) end, + [0xD5] = function (c) return unpack_ext(c, 2, unpack_int8(c)) end, + [0xD6] = function (c) return unpack_ext(c, 4, unpack_int8(c)) end, + [0xD7] = function (c) return unpack_ext(c, 8, unpack_int8(c)) end, + [0xD8] = function (c) return unpack_ext(c, 16, unpack_int8(c)) end, + [0xD9] = function (c) return unpack_str(c, unpack_uint8(c)) end, + [0xDA] = function (c) return unpack_str(c, unpack_uint16(c)) end, + [0xDB] = function (c) return unpack_str(c, unpack_uint32(c)) end, + [0xDC] = function (c) return unpack_array(c, unpack_uint16(c)) end, + [0xDD] = function (c) return unpack_array(c, unpack_uint32(c)) end, + [0xDE] = function (c) return unpack_map(c, unpack_uint16(c)) end, + [0xDF] = function (c) return unpack_map(c, unpack_uint32(c)) end, +}, { + __index = function (t, k) + if k < 0xC0 then + if k < 0x80 then + return function (c, val) return val end + elseif k < 0x90 then + return function (c, val) return unpack_map(c, val & 0xF) end + elseif k < 0xA0 then + return function (c, val) return unpack_array(c, val & 0xF) end + else + return function (c, val) return unpack_str(c, val & 0x1F) end + end + elseif k > 0xDF then + return function (c, val) return val - 0x100 end + else + return function () error("unpack '" .. format('%#x', k) .. "' is unimplemented") end + end + end +}) + +local function cursor_string (str) + return { + s = str, + i = 1, + j = #str, + underflow = function () + error "missing bytes" + end, + } +end + +local function cursor_loader (ld) + return { + s = '', + i = 1, + j = 0, + underflow = function (self, e) + self.s = self.s:sub(self.i) + e = e - self.i + 1 + self.i = 1 + self.j = 0 + while e > self.j do + local chunk = ld() + if not chunk then + error "missing bytes" + end + self.s = self.s .. chunk + self.j = #self.s + end + end, + } +end + +function m.unpack (s) + checktype('unpack', 1, s, 'string') + local cursor = cursor_string(s) + local data = unpack_cursor(cursor) + if cursor.i <= cursor.j then + error "extra bytes" + end + return data +end + +function m.unpacker (src) + if type(src) == 'string' then + local cursor = cursor_string(src) + return function () + if cursor.i <= cursor.j then + return cursor.i, unpack_cursor(cursor) + end + end + elseif type(src) == 'function' then + local cursor = cursor_loader(src) + return function () + if cursor.i > cursor.j then + pcall(cursor.underflow, cursor, cursor.i) + end + if cursor.i <= cursor.j then + return true, unpack_cursor(cursor) + end + end + else + argerror('unpacker', 1, "string or function expected, got " .. type(src)) + end +end + +set_string'string_compat' +set_integer'unsigned' +if #pack('n', 0.0) == 4 then + m.small_lua = true + unpackers[0xCB] = nil -- double + unpackers[0xCF] = nil -- uint64 + unpackers[0xD3] = nil -- int64 + set_number'float' +else + m.full64bits = true + set_number'double' + if #pack('n', 0.0) > 8 then + m.long_double = true + end +end +set_array'without_hole' + +m._VERSION = '0.5.2' +m._DESCRIPTION = "lua-MessagePack : a pure Lua 5.3 implementation" +m._COPYRIGHT = "Copyright (c) 2012-2019 Francois Perrad" +return m diff --git a/events/command.lua b/events/command.lua index 84bb004..9bf9d0a 100644 --- a/events/command.lua +++ b/events/command.lua @@ -1,6 +1,6 @@ return function(C, api, msg) local cmd = C.cmds[msg.cmd] - local owner = msg.from.username == C.config.owner + local owner = msg.from.id == C.config.owner if cmd == nil then api:send(msg, 'Invaid command provided.') @@ -14,7 +14,8 @@ local succ, err = pcall(cmd.run, C, msg, owner) if not succ then api:reply(msg, 'Произошла ошибочка, которая была отправлена создателю') - local cid = api:getChat('@' .. C.config.owner).id + print(err) + local cid = C.config.owner api:forward(cid, msg.chat.id, msg.message_id, false) api:send(cid, err) end diff --git a/events/ready.lua b/events/ready.lua index d6fe250..1af8c5a 100644 --- a/events/ready.lua +++ b/events/ready.lua @@ -37,4 +37,9 @@ return function(C, api) end end api:setMyCommands(a) + + a = {'levels', } + for i = 1, #a do + if not C.db[a[i]] then C.db[a[i]] = {} end + end end \ No newline at end of file diff --git a/init.lua b/init.lua index c54c14c..701bfe9 100644 --- a/init.lua +++ b/init.lua @@ -1,6 +1,7 @@ local config = require 'config' local Core = { + db = require 'db.db' ('db'), tg = require 'tg', tools = tools, config = config, @@ -30,16 +31,34 @@ function Core:load(what) end function Core:init() - self.api = tg(config.token) - self.config.token = nil - - print('Logged on as @' .. self.api.info.username) + self.api = tg {norun = true} + print 'Client initialization...' self:load 'events' + self.api:login(config.token, function() + print('Logged on as @' .. self.api.info.username) + self.config.token = nil + self.api:onReady() + end) + print 'Done!' - self.api:run() + + local offs, o = 0 + self.t = os.time() + self.api.runs = true + while self.api.runs do + o = self.api:_getUpd(1, offs, 0) + offs = o and o or offs + + if os.time() - self.t >= 60 * 5 then + self.t = os.time() + print 'saving...' + self.db:save() + end + end + self.api:getUpdates(1, offs, 0) end Core:init() \ No newline at end of file diff --git a/tg/api.lua b/tg/api.lua index a541ffc..cbcfe98 100644 --- a/tg/api.lua +++ b/tg/api.lua @@ -26,6 +26,10 @@ function api:send(msg, txt, pmod, dwp, dnot, rtmid, rmp) pmod = (type(pmod) == 'boolean' and pmod == true) and 'markdown' or pmod if dwp == nil then dwp = true end + if txt and #txt > 4096 then + txt = txt:sub(0, 4092) .. '...' + end + return self:request('sendMessage', { chat_id = msg, text = txt, diff --git a/tg/core.lua b/tg/core.lua index dcf3a92..c6c6997 100644 --- a/tg/core.lua +++ b/tg/core.lua @@ -20,7 +20,7 @@ function api.onQuery(_) end function api.onUpdate(_) end -- UPDATES -- -function api:getUpdates(tout, offs, lim, allowed) +function api:getUpdates(lim, offs, tout, allowed) allowed = type(allowed) == 'table' and tools.json.encode(allowed) or allowed return self:request('getUpdates', { timeout = tout, @@ -66,24 +66,29 @@ local function receiveUpdate(self, update) end end -function api:_loop(lim, tout, offs, al) - while true do - local u, ok = self:getUpdates(tout, offs, lim, al) - if not ok or not u or (u and type(u) ~= 'table') or not u.result then goto f end - for _, v in pairs(u.result) do - offs = v.update_id + 1 - receiveUpdate(self, v) - end - ::f:: +function api:_getUpd(lim, offs, ...) + local u, ok = self:getUpdates(lim, offs, ...) + if not ok or not u or (u and type(u) ~= 'table') or not u.result then return end + for _, v in pairs(u.result) do + offs = v.update_id + 1 + receiveUpdate(self, v) end - self:getUpdates(tout, offs, lim, al) + return offs +end + +function api:_loop(lim, offs, ...) + while api.runs do + local o = self:_getUpd(lim, offs, ...) + offs = o and o or offs + end + self:getUpdates(lim, offs, ...) end -- RUN -- -function api:run(lim, tout, offs, al) +function api:run(lim, offs, tout, al) lim = tonumber(lim) or 1 - tout = tonumber(tout) or 0 offs = tonumber(offs) or 0 + tout = tonumber(tout) or 0 self.runs = true self:onReady() @@ -94,17 +99,29 @@ end function api:destroy() self.runs = false end -return function(token) - if not token or type(token) ~= 'string' then token = nil end - local self = setmetatable({}, api) - self.token = assert(token, 'Provide token!') +function api:login(token, thn) + self.token = assert(token or self.token, 'Provide token!') repeat - local b,a = self:getMe() - if a then self.info = b end + local r, o = self:getMe() + if o and r then self.info = r end until (self.info or {}).result self.info = self.info.result self.info.name = self.info.first_name + + if type(thn) == 'function' then thn(self) end + + if not self.nr then self:run() end +end + +return function(opts) + if not token or type(token) ~= 'string' then token = nil end + local self = setmetatable({}, api) + if not opts then return self end + + if opts.token then self.token = opts.token end + if opts.norun then self.nr = true end + return self end \ No newline at end of file diff --git a/tg/tools.lua b/tg/tools.lua index b73ad1a..a34462f 100644 --- a/tg/tools.lua +++ b/tg/tools.lua @@ -38,14 +38,15 @@ function tools.req(url) return resp[1], true end -function tools.requ(url) +function tools.requ(url, dbg) local res, succ = tools.req(url) + if dbg then print(succ, res) end res = json.decode(res or '{}') if not succ or not res then return {}, false end return res, true end -function tools.request(token, endpoint, param) +function tools.request(token, endpoint, param, dbg) assert(token, 'Provide token!') assert(endpoint, 'Provide endpoint!') @@ -57,7 +58,7 @@ function tools.request(token, endpoint, param) local url = 'https://api.telegram.org/bot' .. token .. '/' .. endpoint if #params > 1 then url = url .. '?' .. params:sub(2) end - local resp = tools.requ(url) + local resp = tools.requ(url, dbg) return resp, resp.ok or false end