Add DB + some things
This commit is contained in:
		
							parent
							
								
									569dbe1026
								
							
						
					
					
						commit
						7f68524d5a
					
				
					 11 changed files with 789 additions and 30 deletions
				
			
		|  | @ -28,6 +28,7 @@ local env = { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| return { | return { | ||||||
|  |   private = true, | ||||||
|   args = '<code>', |   args = '<code>', | ||||||
|   desc = 'evaluates code', |   desc = 'evaluates code', | ||||||
|   run = function(C, msg, owner) |   run = function(C, msg, owner) | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| return { | return { | ||||||
|   token = 'atokenyanedam', |   token = 'atokenyanedam', | ||||||
|   owner = 'Er2Official', -- hehe |   owner = 935626920 , -- hehe | ||||||
|   cmds = { |   cmds = { | ||||||
|     'eval', |     'eval', | ||||||
|     'rub', |     'rub', | ||||||
|  |  | ||||||
							
								
								
									
										4
									
								
								db/.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								db/.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,4 @@ | ||||||
|  | * | ||||||
|  | !.gitignore | ||||||
|  | !db.lua | ||||||
|  | !mp.lua | ||||||
							
								
								
									
										73
									
								
								db/db.lua
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								db/db.lua
									
										
									
									
									
										Normal file
									
								
							|  | @ -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 | ||||||
|  | }) | ||||||
							
								
								
									
										634
									
								
								db/mp.lua
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										634
									
								
								db/mp.lua
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,634 @@ | ||||||
|  | -- lua-MessagePack <https://fperrad.frama.io/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 | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| return function(C, api, msg) | return function(C, api, msg) | ||||||
|   local cmd = C.cmds[msg.cmd] |   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 |   if cmd == nil then | ||||||
|     api:send(msg, 'Invaid command provided.') |     api:send(msg, 'Invaid command provided.') | ||||||
| 
 | 
 | ||||||
|  | @ -14,7 +14,8 @@ | ||||||
|     local succ, err = pcall(cmd.run, C, msg, owner) |     local succ, err = pcall(cmd.run, C, msg, owner) | ||||||
|     if not succ then |     if not succ then | ||||||
|       api:reply(msg, 'Произошла ошибочка, которая была отправлена создателю') |       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:forward(cid, msg.chat.id, msg.message_id, false) | ||||||
|       api:send(cid, err) |       api:send(cid, err) | ||||||
|     end |     end | ||||||
|  |  | ||||||
|  | @ -37,4 +37,9 @@ return function(C, api) | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
|   api:setMyCommands(a) |   api:setMyCommands(a) | ||||||
|  | 
 | ||||||
|  |   a = {'levels', } | ||||||
|  |   for i = 1, #a do | ||||||
|  |     if not C.db[a[i]] then C.db[a[i]] = {} end | ||||||
|  |   end | ||||||
| end | end | ||||||
							
								
								
									
										27
									
								
								init.lua
									
										
									
									
									
								
							
							
						
						
									
										27
									
								
								init.lua
									
										
									
									
									
								
							|  | @ -1,6 +1,7 @@ | ||||||
| local config = require 'config' | local config = require 'config' | ||||||
| 
 | 
 | ||||||
| local Core = { | local Core = { | ||||||
|  |   db = require 'db.db' ('db'), | ||||||
|   tg = require 'tg', |   tg = require 'tg', | ||||||
|   tools = tools, |   tools = tools, | ||||||
|   config = config, |   config = config, | ||||||
|  | @ -30,16 +31,34 @@ function Core:load(what) | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
| function Core:init() | function Core:init() | ||||||
|   self.api = tg(config.token) |   self.api = tg {norun = true} | ||||||
|   self.config.token = nil |  | ||||||
| 
 | 
 | ||||||
|   print('Logged on as @' .. self.api.info.username) |  | ||||||
|   print 'Client initialization...' |   print 'Client initialization...' | ||||||
| 
 | 
 | ||||||
|   self:load 'events' |   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!' |   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 | end | ||||||
| 
 | 
 | ||||||
| Core:init() | Core:init() | ||||||
|  | @ -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 |   pmod = (type(pmod) == 'boolean' and pmod == true) and 'markdown' or pmod | ||||||
|   if dwp == nil then dwp = true end |   if dwp == nil then dwp = true end | ||||||
| 
 | 
 | ||||||
|  |   if txt and #txt > 4096 then | ||||||
|  |     txt = txt:sub(0, 4092) .. '...' | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|   return self:request('sendMessage', { |   return self:request('sendMessage', { | ||||||
|     chat_id = msg, |     chat_id = msg, | ||||||
|     text = txt, |     text = txt, | ||||||
|  |  | ||||||
							
								
								
									
										47
									
								
								tg/core.lua
									
										
									
									
									
								
							
							
						
						
									
										47
									
								
								tg/core.lua
									
										
									
									
									
								
							|  | @ -20,7 +20,7 @@ function api.onQuery(_) end | ||||||
| function api.onUpdate(_) end | function api.onUpdate(_) end | ||||||
| 
 | 
 | ||||||
| -- UPDATES -- | -- 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 |   allowed = type(allowed) == 'table' and tools.json.encode(allowed) or allowed | ||||||
|   return self:request('getUpdates', { |   return self:request('getUpdates', { | ||||||
|     timeout = tout, |     timeout = tout, | ||||||
|  | @ -66,24 +66,29 @@ local function receiveUpdate(self, update) | ||||||
|   end |   end | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
| function api:_loop(lim, tout, offs, al) | function api:_getUpd(lim, offs, ...) | ||||||
|   while true do |   local u, ok = self:getUpdates(lim, offs, ...) | ||||||
|     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 return end | ||||||
|     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 |   for _, v in pairs(u.result) do | ||||||
|     offs = v.update_id + 1 |     offs = v.update_id + 1 | ||||||
|     receiveUpdate(self, v) |     receiveUpdate(self, v) | ||||||
|   end |   end | ||||||
|     ::f:: |   return offs | ||||||
| end | end | ||||||
|   self:getUpdates(tout, offs, lim, al) | 
 | ||||||
|  | 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 | end | ||||||
| 
 | 
 | ||||||
| -- RUN -- | -- RUN -- | ||||||
| function api:run(lim, tout, offs, al) | function api:run(lim, offs, tout, al) | ||||||
|   lim = tonumber(lim) or 1 |   lim = tonumber(lim) or 1 | ||||||
|   tout = tonumber(tout) or 0 |  | ||||||
|   offs = tonumber(offs) or 0 |   offs = tonumber(offs) or 0 | ||||||
|  |   tout = tonumber(tout) or 0 | ||||||
| 
 | 
 | ||||||
|   self.runs = true |   self.runs = true | ||||||
|   self:onReady() |   self:onReady() | ||||||
|  | @ -94,17 +99,29 @@ end | ||||||
| 
 | 
 | ||||||
| function api:destroy() self.runs = false end | function api:destroy() self.runs = false end | ||||||
| 
 | 
 | ||||||
| return function(token) | function api:login(token, thn) | ||||||
|   if not token or type(token) ~= 'string' then token = nil end |   self.token = assert(token or self.token, 'Provide token!') | ||||||
|   local self = setmetatable({}, api) |  | ||||||
|   self.token = assert(token, 'Provide token!') |  | ||||||
| 
 | 
 | ||||||
|   repeat |   repeat | ||||||
|     local b,a = self:getMe() |     local r, o = self:getMe() | ||||||
|     if a then self.info = b end |     if o and r then self.info = r end | ||||||
|   until (self.info or {}).result |   until (self.info or {}).result | ||||||
| 
 | 
 | ||||||
|   self.info = self.info.result |   self.info = self.info.result | ||||||
|   self.info.name = self.info.first_name |   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 |   return self | ||||||
| end | end | ||||||
|  | @ -38,14 +38,15 @@ function tools.req(url) | ||||||
|   return resp[1], true |   return resp[1], true | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
| function tools.requ(url) | function tools.requ(url, dbg) | ||||||
|   local res, succ = tools.req(url) |   local res, succ = tools.req(url) | ||||||
|  |   if dbg then print(succ, res) end | ||||||
|   res = json.decode(res or '{}') |   res = json.decode(res or '{}') | ||||||
|   if not succ or not res then return {}, false end |   if not succ or not res then return {}, false end | ||||||
|   return res, true |   return res, true | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
| function tools.request(token, endpoint, param) | function tools.request(token, endpoint, param, dbg) | ||||||
|   assert(token, 'Provide token!') |   assert(token, 'Provide token!') | ||||||
|   assert(endpoint, 'Provide endpoint!') |   assert(endpoint, 'Provide endpoint!') | ||||||
| 
 | 
 | ||||||
|  | @ -57,7 +58,7 @@ function tools.request(token, endpoint, param) | ||||||
|   local url = 'https://api.telegram.org/bot' .. token .. '/' .. endpoint |   local url = 'https://api.telegram.org/bot' .. token .. '/' .. endpoint | ||||||
|   if #params > 1 then url = url .. '?' .. params:sub(2) end |   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 |   return resp, resp.ok or false | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue