/*--------------------------------------------------------- Name: table.Sanitise( table ) table.DeSanitise( table ) Desc: Converts an arbitrary table containing vectors, angles, bools, players, entities so it can be safely converted to and from keyvalues, NOTE: table keys must be numbers or strings ---------------------------------------------------------*/ function table.Sanitise( t, done ) local done = done or {} local tbl = {} local Sequential = table.IsSequential( t ) for key, val in pairs ( t ) do local kvTable = {} local keytype = type( val ) kvTable.type = keytype if ( !Sequential ) then kvTable.key = key end if ( keytype == "table" ) then --// entry is a table // We do it it like this so we can support cyclic tables. if !done[ val ] then done[ val ] = kvTable kvTable.value = table.Sanitise ( val, done ) else done[ val ].index = tostring( done[ val ] ) kvTable.index = tostring( done[ val ] ) end elseif ( keytype == "Entity" ) then kvTable.value = val:EntIndex() elseif ( keytype == "boolean" ) then kvTable.value = tostring( val ) elseif ( keytype == "Vector" ) then kvTable.value = val.x.." "..val.y.." "..val.z elseif ( keytype == "Angle" ) then kvTable.value = val.pitch.." "..val.yaw.." "..val.roll elseif ( keytype == "Player" ) then if ( CLIENT ) then kvTable = nil else kvTable.value = val:UniqueID() end elseif ( keytype == "string" || keytype == "number" ) then kvTable.value = val kvTable.type = nil end if ( Sequential ) then tbl[ key ] = kvTable else table.insert( tbl, kvTable ) end end return tbl end /*--------------------------------------------------------- Name: table.DeSanitise( table ) Desc: Converts a Sanitised table back to a conventional lua table ---------------------------------------------------------*/ function table.DeSanitise( t, done, idx, i ) local done = done or {} local idx = idx or {} local tbl = {} if !type( t ) == "table" then return t,done end for key, val in pairs ( t ) do local value = nil local key = val.key or key if val.type == "table" then // This loop is only called for tables which are referenced more than once, and is used to re-connect any cyclic references if val.index then if val.value then value = table.DeSanitise ( val.value, done, idx ) done[ val.index ] = value //Do for all cyclic references we found before finding the actual table if idx[ val.index ] then for _,v in pairs( idx[ val.index ] ) do table.Merge( v,value ) end end else // Check if we already handled the table this cyclic reference refers to if done[ val.index ] then value = done[ val.index ] else value = {} if !idx[ val.index ] then idx[ val.index ] = {} end table.insert( idx[ val.index ], value ) end end else value = table.DeSanitise ( val.value, done, idx ) end elseif val.type == "Entity" then value = Entity( val.value ) if !value:IsValid() then value = NULL end elseif val.type == "Vector" then value = Vector( unpack( string.Explode( " ", val.value ) ) ) elseif val.type == "Angle" then value = Angle( unpack( string.Explode( " ", val.value ) ) ) elseif val.type == "Player" then value = player.GetByUniqueID( tostring( val.value ) ) or NULL else value = val.value end tbl[ key ] = value end return tbl end