Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[====[
- Storage
- * Maintainer: Profiver
- * Version: 1.4.0 (final)
- --]====]
- do
- local Utils_CallbackFire,
- Utils_getTypeOf,
- Utils_getMetatableOf,
- Utils_isCallable,
- Utils_setMetatableOf,
- Utils_next,
- Utils_toNumber,
- Utils_toString,
- Uint_dumpUInt,
- Uint_parseUInt,
- Table_unpack,
- Bit32_band,
- Bit32_rshift,
- Math_max,
- String_bytes,
- String_char,
- String_find,
- String_sub,
- Storage_API,
- Storage_Messages,
- Storage_assertf,
- Storage_errorf,
- Storage_formatMsg,
- Class_createEmptyClass,
- Class_createInstanceOf,
- Class_isInstanceOf,
- Class_setConstructorOf,
- Class_setPrototypeOf,
- LUA_BOOLF,
- LUA_BOOLT,
- LUA_NUMBER,
- LUA_TABLE,
- LUA_STRING,
- LUA_NIL,
- Buffer_BufferScanner,
- Buffer_toBuffer,
- Public_File,
- Public_PlayerData,
- Storage_events,
- Storage_linkEvents;
- Utils_getTypeOf = type;
- Utils_getMetatableOf = getmetatable;
- Utils_next = next;
- Utils_setMetatableOf = setmetatable;
- Utils_toNumber = tonumber;
- Utils_toString = tostring;
- Bit32_band = bit32.band;
- Bit32_rshift = bit32.rshift;
- Math_max = math.max;
- String_bytes = string.byte;
- String_char = string.char;
- String_find = string.find;
- String_sub = string.sub;
- Table_unpack = table.unpack;
- LUA_BOOLF, LUA_BOOLT, LUA_NUMBER, LUA_TABLE, LUA_STRING, LUA_NIL = 0, 1, 2, 3, 4, 5;
- function Uint_dumpUInt (n)
- -- Get range of bits
- local r, s = 0, n;
- while (s >= 0) do s = s - 0xFF; r = r + 8; end; r = Math_max(0, r - 8);
- local b, bytes, i = 0, {}, 1;
- repeat
- bytes[i] = Bit32_band(Bit32_rshift(n, b), 0xFF);
- b, i = b + 8, i + 1;
- until b > r;
- return Table_unpack(bytes);
- end
- function UInt_parseUInt (s)
- local l, r = #s, 0;
- for i = 1, l do r = r + (String_bytes(s, i) * (16 ^ (l - i))) end;
- return r;
- end
- function Class_createEmptyClass () return Utils_setMetatableOf({ protometa = {} }, {}) end
- function Class_createInstanceOf (Class) return Utils_setMetatableOf({}, Class.protometa) end
- function Class_isInstanceOf (Class, v) return Utils_getMetatableOf(v) == Class.protometa end
- function Class_setConstructorOf (Class, c) Utils_getMetatableOf(Class).__call = c end
- function Class_setPrototypeOf (Class, p) Class.protometa.__index = p end
- function Buffer_toBuffer (v)
- if (v == nil) then return String_char(LUA_NIL) end;
- local tp = Utils_getTypeOf(v);
- if (tp == 'number') then return String_char(LUA_NUMBER)..Utils_toString(v)..String_char(0) end;
- if (tp == 'boolean') then return String_char(v and LUA_BOOLT or LUA_BOOLF) end;
- if (tp == 'table') then
- local f = '';
- for k1, v1 in Utils_next, v do f = f..(Buffer_toBuffer(k1)..Buffer_toBuffer(v1)) end;
- return String_char(LUA_TABLE)..f..String_char(0x28);
- end
- if (tp == 'string') then
- local len = String_char(Uint_dumpUInt(#v));
- return String_char(LUA_STRING)..#len..len..v;
- end
- Storage_errorf(Storage_Messages.UnsupportedLuaType);
- end
- Buffer_BufferScanner = Class_createEmptyClass();
- Class_setPrototypeOf(Buffer_BufferScanner, {
- scan = function (self)
- -- self.src:byte(self.idx);
- local tp = String_bytes(self.src, self.idx);
- self.idx = self.idx + 1;
- if (tp <= LUA_BOOLT) then return tp == LUA_BOOLT end;
- if (tp == LUA_NUMBER) then
- local j = String_find(self.src, String_char(0), self.idx);
- local c = String_sub(self.src, self.idx, j - 1);
- self.idx = j + 1; return Utils_toNumber(c);
- end
- if (tp == LUA_TABLE) then
- local t = {};
- while (true) do
- local b = String_bytes(self.src, self.idx);
- if (b == 0x28) then self.idx = self.idx + 1; return t; else
- local k, v = self:scan(), self:scan(); t[k] = v;
- end
- end
- end
- if (tp == LUA_STRING) then
- local l = String_bytes(self.src, self.idx);
- local bi = self.idx + l;
- local len = UInt_parseUInt(String_sub(self.src, self.idx + 1, self.idx + l));
- local bj = bi + len;
- self.idx = bj + 1;
- return String_sub(self.src, bi, bj);
- end
- end
- });
- Class_setConstructorOf(Buffer_BufferScanner, function (C, src)
- local instance = Class_createInstanceOf(C);
- instance.idx = 1;
- instance.src = src;
- return instance;
- end);
- Utils_CallbackFire = Class_createEmptyClass();
- Class_setPrototypeOf(Utils_CallbackFire, {
- _changeState = function (self, state, ...)
- self._vals = {...}; self._state = state; self:_fire();
- end,
- _fire = function (self)
- local stck = self._cbs[self._state];
- local vals = self._vals;
- while (true) do
- local k = Utils_next(stck);
- if (not k) then break end;
- stck[k] = nil;
- if (Utils_isCallable(k)) then k(Table_unpack(vals)) end;
- end
- end,
- action = function (self, onComplete, onError)
- local cbs = self._cbs;
- local state = self._state;
- if (onComplete) then
- if (state == 0) then onComplete(Table_unpack(self._vals)) end;
- local stck = cbs[0];
- stck[#stck + 1] = onComplete;
- end
- if (onError) then
- if (state == 1) then onError(Table_unpack(self._vals)) end;
- local stck = cbs[1];
- stck[#stck + 1] = onError;
- end
- end
- });
- Class_setConstructorOf(Utils_CallbackFire, function (C, exec)
- local instance = Class_createInstanceOf(C);
- instance._cbs = { [0] = {}, [1] = {} };
- instance._state = 2;
- local function complete (...) instance:_changeState(0, ...); end
- local function fail (...) instance:_changeState(1, ...); end
- exec(complete, fail);
- end);
- Storage_Messages = {
- UnsupportedLuaType = 'value of type %1 cannot be stored'
- };
- function Storage_assertf (test, msg, ...) if not test then Storage_errorf(msg, ...) end end
- function Storage_errorf (msg, ...) error(Storage_formatMsg(msg, ...)) end
- function Storage_linkEvents ()
- local root = _G;
- for k, v in Utils_next, Storage_events do Storage_events[k] = v end;
- end
- storage = {
- events = Storage_events,
- linkEvents = Storage_linkEvents,
- File = Public_File,
- PlayerData = Public_PlayerData
- };
- function Utils_isCallable (v)
- if (Utils_getTypeOf(v) == 'function') then return true end;
- local t = Utils_getMetatableOf(v);
- return (not not t) and Utils_getTypeOf(t.__call) == 'function';
- end
- print(
- next(Buffer_BufferScanner(
- Buffer_toBuffer{0, 'wowow'}
- ):scan())
- );
- end
- --[====[
- Storage
- * Maintainer: Profiver.
- * Version: 1.2.0.
- ]====]
- do
- local library;
- local API_STORAGE = 0;
- local VIRTUAL_STORAGE = 1;
- local tfm_get_room = tfm.get.room;
- local room_playerlist = tfm.get.room.playerList;
- local bit32_band = bit32.band;
- local bit32_rshift = bit32.rshift;
- local uint_dump;
- local uint_parse;
- local BUFFER_BFALSE = 0;
- local BUFFER_BTRUE = 1;
- local BUFFER_NUMBER = 2;
- local BUFFER_TABLE = 3;
- local BUFFER_STRING = 4;
- local BUFFER_NIL = 5;
- local BUFFER_END_NUMBER = 0;
- local BUFFER_END_TABLE = 12;
- local buffer_advance;
- local buffer_parse;
- local buffer_posi;
- local buffer_scan;
- local buffer_tostring;
- local class_super;
- local class_create;
- local class_instantiate;
- local class_isinstance;
- local class_setconstructor;
- local class_setprototype;
- local class_updatesuper;
- local table_unpack = table.unpack;
- local string_byte = string.byte;
- local string_char = string.char;
- local string_find = string.find;
- local string_gmatch = string.gmatch;
- local string_sub = string.sub;
- local format;
- local getmetatable = getmetatable;
- local setmetatable = setmetatable;
- local tonumber = tonumber;
- local tostring = tostring;
- local type = type;
- local next = next;
- local print = print;
- local math_max = math.max;
- local iscallable;
- local root = _G;
- local useapi;
- local CallbackHandler;
- local PlayerData;
- local ModuleFile;
- local Messages;
- local events = {};
- -- Class handling. Optionally includes inheritance,
- -- which is not needed this time.
- -- class_create() creates a template class.
- function class_create ()
- local staticFields = { _proto = {} };
- return setmetatable(staticFields, {});
- end
- -- class_instantiate() returns an instance of a class.
- function class_instantiate (Class)
- return setmetatable({}, Class._proto);
- end
- -- class_setconstructor() sets the constructor function
- -- of a class. It's directly called in the class, i.e.:
- -- Class(...args)
- function class_setconstructor (Class, constructor)
- local staticMeta = getmetatable(Class);
- staticMeta.__call = constructor;
- end
- -- class_super() constructs the superior class of a class.
- -- The superior class MUST return an instance, which will then
- -- be re-prototyped by the child class here and returned again.
- function class_super (Class,...)
- local staticMeta = getmetatable(Class);
- return setmetatable(staticMeta.__index(...), Class._proto);
- end
- -- class_setprototype() sets the field base of a class, which is distributed
- -- to the instance metatable.
- -- This base is accessible by the instances of that class.
- function class_setprototype (Class, prototype)
- local protoMeta = Class._proto;
- protoMeta.__index = prototype;
- local SuperClass = getmetatable(Class).__index;
- if SuperClass then
- setmetatable(protoMeta.__index, SuperClass._proto);
- end
- end
- -- class_updatesuper() sets the super class ("inherited class") of a class.
- -- The super class is accessible thru child class __index meta field.
- function class_updatesuper (ChildClass, SuperClass)
- -- Allows the child class to index the super class.
- local childStaticMeta = getmetatable(ChildClass);
- childStaticMeta.__index = SuperClass;
- local childProtoMeta = ChildClass._proto;
- setmetatable(childProtoMeta.__index, SuperClass._proto);
- end
- -- class_isinstance() checks if a value is instance of a class.
- function class_isinstance (val, Class)
- local protoMeta = Class._proto;
- local valMeta = getmetatable(val);
- if not valMeta then return false end; -- skip
- -- Go checking for the protoype of inherited classes too.
- while protoMeta do
- if protoMeta == valMeta then
- return true;
- end
- protoMeta = getmetatable(protoMeta.__index);
- protoMeta = protoMeta and protoMeta.__index;
- end
- return false;
- end
- -- Buffer utils.
- function buffer_tostring (val)
- if val == nil return string_char(BUFFER_NIL) end;
- local tp = type(val);
- if tp == 'number' then
- return string_char(BUFFER_NUMBER)..tostring(val)..
- string_char(BUFFER_END_NUMBER);
- end
- if tp == 'string' then
- -- String resume:
- -- byte lengthBytes, uint length, byte[] bytes
- local bytelen = uint_dump(#val);
- return ((string_char(BUFFER_STRING)..#bytelen)..bytelen)..val;
- end
- if tp == 'table' then
- local f = '';
- for k, v in next, val do
- local p = buffer_tostring(k)..buffer_tostring(v);
- f = f..p;
- end
- return string_char(BUFFER_TABLE)..f..
- string_char(BUFFER_END_TABLE);
- end
- end
- PlayerData =
- -- State callback handler utility.
- CallbackHandler = class_create();
- class_setprototype(CallbackHandler, {
- _execcallbacks = function (self)
- local stack = self._callbacks[self._state];
- -- Call every callback and go removing them.
- while true do
- local k = next(stack);
- if not k then break end;
- stack[k] = nil;
- if iscallable(k) then
- k(table_unpack(self._values));
- end
- end
- end,
- action = function (self, onComplete, onError)
- local callbacks = self._callbacks;
- local state = self._state;
- if onComplete then
- if state == 0 then onComplete(table_unpack(self._values)) end;
- local stack = callbacks[0];
- stack[#stack + 1] = onComplete;
- end
- if onError then
- if state == 1 then onError(table_unpack(self._values)) end;
- local stack = callbacks[1];
- stack[#stack + 1] = onError;
- end
- end
- });
- class_setconstructor(CallbackHandler, function (C, executor)
- local instance = class_instantiate(C);
- instance._callbacks = { [0] = {}, [1] = {} };
- instance._state = 2;
- local function complete (...)
- instance._values = {...};
- instance._state = 0;
- instance:_execcallbacks();
- end
- local function finisherror (...)
- instance._values = {...};
- instance._state = 1;
- instance:_execcallbacks();
- end
- executor(complete, finisherror);
- return instance;
- end);
- -- Unsigned integer composition and decomposition utils.
- function uint_parse (s)
- local bytelen = #s;
- local ret = 0;
- for i = 1, bytelen do
- ret = ret + (string_byte(s, i) * (16 ^ (bytelen - i)));
- end
- return ret;
- end
- function uint_dump (n)
- -- Pre-calculates the neccessary range of bytes/bits to
- -- represent the number.
- local bitrange = 0;
- local s = n;
- while s >= 0 do
- s = s - 0xFF;
- bitrange = bitrange + 8;
- end
- bitrange = math_max(0, bitrange - 8);
- -- Now go recognizing the each byte (big-endian order).
- local b = 0;
- local bytes = {};
- local posi = 1;
- repeat
- bytes[posi] = bit32_band(bit32_rshift(n, b), 0xFF);
- b = b + 8;
- posi = posi + 1;
- until b > bitrange;
- return table_unpack(bytes);
- end
- -- Unclassified utils.
- function format (s, ...)
- -- No extra encoding support.
- local args = {...};
- local f = '';
- local i = 1;
- local l = #s;
- while i <= l do
- local a, j, c = string_find(s, '%%(.)', i);
- if c then
- f = f..(string_sub(s, i, a - 1)..args[tonumber(c)]);
- i = j + 1;
- else
- f = f..string_sub(s, i);
- break;
- end
- end
- return '(storage) '..f;
- end
- function iscallable (value)
- if type(value) == 'function' then
- return true;
- end
- local meta = getmetatable(value);
- return meta and (type(meta.__call) == 'function');
- end
- function useapi ()
- return library.storageMode == API_STORAGE;
- end
- Messagess = {
- TypeNotSupported = '%1 type cannot be stored'
- };
- library = {
- API_STORAGE = API_STORAGE,
- VIRTUAL_STORAGE = VIRTUAL_STORAGE,
- ModuleFile = ModuleFile,
- PlayerData = PlayerData,
- storageMode = (tfm_get_room.name:byte(2) == 3) and
- VIRTUAL_STORAGE or API_STORAGE,
- placeStorageEvents = function ()
- for k, v in next, events do
- root[k] = v;
- end
- end
- };
- root.storage = library;
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement