zombiesurvival-evolved/gamemodes/zombiesurvival/entities/weapons/swep_construction_kit/glon.lua

414 lines
9.7 KiB
Lua
Raw Permalink Normal View History

-- NOTE by Clavus: glon was removed from GMod 13, replaced by the util.TableToJSON etc functions
-- In order to maintain compatability and not rewrite all that shit, I'm including it with the SCK.
2014-10-02 08:49:54 +08:00
-- GLON: Garry's Mod Lua Object Notation
-- A extension of LON: Lua Object Notation
-- Made entirely by Deco Da Man
-- Types:
-- 2: table
-- 3: array
-- 4: fasle boolean
-- 5: true boolean
-- 6: number (NOT COMPRESSED, it isn't worth it)
-- 7: string
---- non-LON types start here!
-- 8: Vector (NOT COMPRESSED, it isn't worth it)
-- 9: Angle (NOT COMPRESSED, it isn't worth it)
-- 10: Entity (Can do players, vehicles, npcs, weapons and any other type of entity (-1 for null entity))
-- 11: Player (By UserID)
-- 12: CEffectData
-- 13: ConVar (Not ClientConVar)
-- 15: Color
-- 254: The number equal to -math.huge (tostring(math.huge) == "-1.#INF")
-- 254: The number equal to math.huge (tostring(math.huge) == "1.#INF")
-- 255: reference (Sends the ID of the table to use (for "local t = {} t.a=t"))
--[[local pairs = pairs
2014-10-02 08:49:54 +08:00
local type = type
local string = string
local math = math
local tostring = tostring
local ValidEntity = ValidEntity
local error = error
local print = print
local setmetatable = setmetatable
local Vector = Vector
local Angle = Angle
local Entity = Entity
local EffectData = EffectData
local GetConVar = GetConVar
local tonumber = tonumber
local player = player
local IsValid = IsValid
module("glon")]]
2014-10-02 08:49:54 +08:00
glon = {}
local encode_types
local decode_types
local Write
local Read
local function InDataEscape(s)
s = string.gsub(s, "([\1\2])", "\2%1")
s = string.gsub(s, "%z", "\2\3")
s = string.gsub(s, "\"", "\4") -- escape the " character to simplify client commands
2014-10-02 08:49:54 +08:00
return s
end
encode_types = {
["nil"] = {nil, function()
return "", nil
end},
table = {2, function(o, rtabs)
for k,v in pairs(rtabs) do
if v == o then
return tostring(k).."\1", 255
end
end
rtabs[#rtabs+1] = o
local is_array = true
local i = 0
for k,v in pairs(o) do
i = i + 1
if k ~= i or type(k) ~= "number" or math.floor(k) ~= k then
is_array = false
break end
end
local s = ""
for k,v in pairs(o) do
2014-10-02 08:49:54 +08:00
if ( !encode_types[type(v)] ) then continue end
2014-10-02 08:49:54 +08:00
if not is_array then
s = s..Write(k, rtabs)
end
s = s..Write(v, rtabs)
end
return s.."\1", is_array and 3
end},
boolean = {4, function(o)
return "", o and 5
end},
number = {6, function(o)
o = o == 0 and "" or o
return o == ((o == math.huge or o == -math.huge) and "") or tostring(o).."\1", (o == math.huge and 254) or (o == -math.huge and 253)
end},
string = {7, function(o)
return InDataEscape(o).."\1"
end},
-- non-LON types start here!
Vector = {8, function(o)
return o.x.."\1"..o.y.."\1"..o.z.."\1"
end},
Angle = {9, function(o)
return o.p.."\1"..o.y.."\1"..o.r.."\1"
end},
Entity = {10, function(o)
return (ValidEntity(o) and o:EntIndex() or -1).."\1"
end},
NPC = {10, function(o)
return (ValidEntity(o) and o:EntIndex() or -1).."\1"
end},
Weapon = {10, function(o)
return (ValidEntity(o) and o:EntIndex() or -1).."\1"
end},
Player = {11, function(o)
return o:EntIndex().."\1"
end},
CEffectData = {12, function(o, rtabs)
local t = {}
if o:GetAngle() ~= Angle(0,0,0) then
t.a = o:GetAngle()
end
if o:GetAttachment() ~= 0 then
t.h = o:GetAttachment()
end
if o:GetEntity():IsValid() then
t.e = o:GetEntity()
end
if o:GetMagnitude() ~= 0 then
t.m = o:GetMagnitude()
end
if o:GetNormal() ~= Vector(0,0,0) then
t.n = o:GetNormal()
end
if o:GetOrigin() ~= Vector(0,0,0) then
t.o = o:GetOrigin()
end
if o:GetRadius() ~= 0 then
t.r = o:GetRadius()
end
if o:GetScale() ~= 0 then
t.c = o:GetScale()
end
if o:GetStart() ~= 0 then
t.s = o:GetStart()
end
if o:GetSurfaceProp() ~= 0 then
t.p = o:GetSurfaceProp()
end
return encode_types.table[2](t, rtabs)
end},
ConVar = {13, function(o)
return InDataEscape(o:GetName()).."\1"
end},
PhysObj = {14, function(o)
local parent, obj, id = o:GetEntity()
for i = 1, parent:GetPhysicsObjectCount() do
obj = parent:GetPhysicsObjectNum()
if obj == o then
id = i
break end
end
return parent:EntIndex().."\1"..id.."\1"
end},
Color = {15, function(o)
return o.r.."\1"..o.g.."\1"..o.b.."\1"..o.a.."\1"
end},
}
Write = function(data, rtabs)
local t = encode_types[type(data)]
if t then
local data, id_override = t[2](data, rtabs)
local char = id_override or t[1] or ""
if char ~= "" then char = string.char(char) end
return char..(data or "")
else
error(string.format("Tried to write unwriteable type: %s",
type(data)))
end
end
local CEffectDataTranslation = {
a = "Angle",
h = "Attachment",
e = "Entity",
m = "Magnitude",
n = "Normal",
o = "Origin",
r = "Radius",
c = "Scale",
s = "Start",
p = "SurfaceProp",
}
decode_types = {
-- \2\6omg\1\6omgavalue\1\1
[2 ] = function(reader, rtabs) -- table
local t, c, pos = {}, reader:Next()
rtabs[#rtabs+1] = t
local stage = false
local key
while true do
c, pos = reader:Peek()
if c == "\1" then
if stage then
error(string.format("Expected value to match key at %s! (Got EO Table)",
pos))
else
reader:Next()
return t
end
else
if stage then
t[key] = Read(reader, rtabs)
else
key = Read(reader, rtabs)
end
stage = not stage
end
end
end,
[3 ] = function(reader, rtabs) -- array
local t, i, c, pos = {}, 1, reader:Next()
rtabs[#rtabs+1] = t
while true do
c, pos = reader:Peek()
if c == "\1" then
reader:Next()
return t
else
t[i] = Read(reader, rtabs)
i = i+1
end
end
end,
[4 ] = function(reader) -- false boolean
reader:Next()
return false
end,
[5 ] = function(reader) -- true boolean
reader:Next()
return true
end,
[6 ] = function(reader) -- number
local s, c, pos, e = "", reader:Next()
while true do
c = reader:Next()
if not c then
error(string.format("Expected \1 to end number at %s! (Got EOF!)",
pos))
elseif c == "\1" then
break
else
s = s..c
end
end
if s == "" then s = "0" end
local n = tonumber(s)
if not n then
error(string.format("Invalid number at %s! (%q)",
pos, s))
end
return n
end,
[7 ] = function(reader) -- string
local s, c, pos, e = "", reader:Next()
while true do
c = reader:Next()
if not c then
error(string.format("Expected unescaped \1 to end string at position %s! (Got EOF)",
pos))
elseif e then
if c == "\3" then
s = s.."\0"
else
s = s..c
end
e = false
elseif c == "\2" then
e = true
elseif c == "\1" then
s = string.gsub(s, "\4", "\"") -- unescape quotes
2014-10-02 08:49:54 +08:00
return s
else
s = s..c
end
end
end,
[8 ] = function(reader) -- Vector
local x = decode_types[6](reader)
reader:StepBack()
local y = decode_types[6](reader)
reader:StepBack()
local z = decode_types[6](reader)
return Vector(x, y, z)
end,
[9 ] = function(reader) -- Angle
local p = decode_types[6](reader)
reader:StepBack()
local y = decode_types[6](reader)
reader:StepBack()
local r = decode_types[6](reader)
return Angle(p, y, r)
end,
[10 ] = function(reader) -- Entity
return Entity(decode_types[6](reader))
end,
[11 ] = function(reader) -- Player
local num = decode_types[6](reader)
return player.GetByID(num)
end,
[12 ] = function(reader, rtabs) -- CEffectData
local t = decode_types[2](reader, rtabs)
local d = EffectData()
for k,v in pairs(t) do
d["Set"..CEffectDataTranslation[k]](d, v)
end
return d
end,
[13 ] = function(reader) -- ConVar
return GetConVar(decode_types[7](reader))
end,
[14 ] = function(reader) -- PhysicsObject
2014-10-02 08:49:54 +08:00
local ent = Entity(decode_types[6](reader))
local bone = decode_types[6](reader)
if ( !IsValid( ent ) ) then return nil end;
2014-10-02 08:49:54 +08:00
return ent:GetPhysicsObjectNum( bone )
end,
[15 ] = function(reader) -- Color
local r = decode_types[6](reader)
reader:StepBack()
local g = decode_types[6](reader)
reader:StepBack()
local b = decode_types[6](reader)
reader:StepBack()
local a = decode_types[6](reader)
return Color(r, g, b, a)
end,
[253] = function(reader) -- -math.huge
reader:Next()
return -math.huge
end,
[254] = function(reader) -- math.huge
reader:Next()
return math.huge
end,
[255] = function(reader, rtabs) -- Reference
return rtabs[decode_types[6](reader) - 1]
end,
}
Read = function(reader, rtabs)
local t, pos = reader:Peek()
if not t then
error(string.format("Expected type ID at %s! (Got EOF)",
pos))
else
local dt = decode_types[string.byte(t)]
if not dt then
error(string.format("Unknown type ID, %s!",
string.byte(t)))
else
return dt(reader, rtabs or {0})
end
end
end
local reader_meta = {}
reader_meta.__index = reader_meta
reader_meta.Next = function(self)
self.i = self.i+1
self.c = string.sub(self.s, self.i, self.i)
if self.c == "" then self.c = nil end
self.p = string.sub(self.s, self.i+1, self.i+1)
if self.p == "" then self.p = nil end
return self.c, self.i
end
reader_meta.StepBack = function(self)
self.i = self.i-1
self.c = string.sub(self.s, self.i, self.i)
if self.c == "" then self.c = nil end
self.p = string.sub(self.s, self.i+1, self.i+1)
if self.p == "" then self.p = nil end
return self.c, self.i
end
reader_meta.Peek = function(self)
return self.p, self.i+1
end
function glon.decode(data)
if type(data) == "nil" then
return nil
elseif type(data) ~= "string" then
error(string.format("Expected string to decode! (Got type %s)",
type(data)
))
elseif data:len() == 0 then
return nil
end
2014-10-02 08:49:54 +08:00
return Read(setmetatable({
s = data,
i = 0,
c = string.sub(data, 0, 0),
p = string.sub(data, 1, 1),
}, reader_meta), {})
end
function glon.encode(data)
return Write(data, {0}) -- to use the first key, to prevent it from interfereing with \1s. You can have up to 254 unique tables (including arrays)
end