// Helper functions for serialise functions local function SerialiseChunk( chunk, tables ) local type = type( chunk ) if type == "number" then return 'N:'..chunk elseif type == "string" then return 'S:"'..chunk..'"' elseif type == "boolean" then return 'B:'..tostring( chunk ):sub( 1,1 ) elseif type == "Entity" then if chunk == GetWorldEntity() then return 'E:W' elseif chunk == NULL then return 'E:N' else return 'E:'..chunk:EntIndex() end elseif type == "Vector" then return 'V:'..chunk.x.."|"..chunk.y.."|"..chunk.z elseif type == "Angle" then return 'A:'..chunk.pitch.."|"..chunk.yaw.."|"..chunk.roll elseif type == "Player" then return 'P:'..chunk:UniqueID() elseif type == "table" then local ID = tostring( chunk ):sub( 8 ) if !tables[ID] then tables[ID] = true tables[ID] = SerialiseTableKeyValues( chunk, tables ) end return 'T:'..ID end end local function DeSerialiseChunk( chunk, tables ) local type = chunk:sub(1,1) if type == "N" then return chunk:sub(3) elseif type == "S" then return chunk:sub( 4, -2 ) elseif type == "B" then return chunk:sub(3) == "t" elseif type == "E" then local ent = chunk:sub(3) if ent == "W" then return GetWorldEntity() elseif ent == "N" then return NULL else return Entity( ent ) end elseif type == "V" then return Vector( string.Explode( '|', chunk:sub(3) ) ) elseif type == "A" then return Angle( string.Explode( '|', chunk:sub(3) ) ) elseif type == "P" then return player.GetByUniqueID( chunk:sub(3) ) elseif type == "T" then local ID = chunk:sub(3) local t = {} if !tables[ID] then tables[ID] = {} end table.insert( tables[ID], t ) return t end end function SerialiseTableKeyValues( tbl, tables ) local temp = {} local DoKeys = true //!table.IsSequential( tbl ) for k,v in pairs( tbl ) do print(k,v) local str = SerialiseChunk( v, tables ) if DoKeys then str = SerialiseChunk( k, tables ) .."=".. str end table.insert( temp, str ) end return temp end /*--------------------------------------------------------- Name: table.serialise( table ) table.deserialise( table ) Desc: Converts an arbitrary table containing vectors, angles, bools, players, entities, etc to & from a compact string. (will handle circular references) ---------------------------------------------------------*/ function table.serialise( t ) local tables = {} local str = "" local headID = tostring(t):sub(8) local head = SerialiseTableKeyValues( t, tables ) local str = headID.."{".. table.concat( tables[ headID ], ";" ) ..";}" for k,v in pairs( tables ) do str = str..k.."{".. table.concat( v, ";" ) ..";}" end return str end function table.deserialise( str ) local tables = {} local subtables = {} local head = nil // I'm not too good at regex, so there's probably a more efficient/reliable way of doing this for ID,tbl in string.gmatch(str, "(........)[\{](.-)[\}]") do // Get each table block tables[ID] = {} for k,v in string.gmatch(tbl, "\(.-)[\=](.-)[\;]") do // Split each table block into k/v pairs k = DeSerialiseChunk( k, subtables ) // deserialise each k/v pair v = DeSerialiseChunk( v, subtables ) tables[ID][k] = v end //the first table will be the head if !head then head = tables[ID] end end // Restore table references for ID,tbls in pairs( subtables ) do for _,tbl in pairs( tbls ) do print( tbl, tables[ID], ID ) table.Merge( tbl, tables[ID] ) end end return head end