summaryrefslogtreecommitdiff
path: root/gamemode/server/glon.lua
diff options
context:
space:
mode:
Diffstat (limited to 'gamemode/server/glon.lua')
-rw-r--r--gamemode/server/glon.lua365
1 files changed, 365 insertions, 0 deletions
diff --git a/gamemode/server/glon.lua b/gamemode/server/glon.lua
new file mode 100644
index 0000000..ccc7376
--- /dev/null
+++ b/gamemode/server/glon.lua
@@ -0,0 +1,365 @@
+-- GLON: Garry's Mod Lua Object Notation
+-- A dialect 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
+ -- 255: reference (Sends the ID of the table to use (for "local t = {} t.a=t"))
+local pairs = pairs
+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
+module("glon")
+local idcount = {}
+local encode_types
+local decode_types
+local function InDataEscape(s)
+ return string.gsub(string.gsub(s, "([\1\2])", "\2%1"), "%z", "\2\3")
+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
+ 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 tostring(o) .. "\1"
+ 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},
+ 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},
+}
+function Write(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
+ 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,
+ [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,
+ [255] = function(reader, rtabs) -- Reference
+ return rtabs[decode_types[6](reader) - 1]
+ end
+}
+function Read(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
+function reader_meta:Next()
+ 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
+function reader_meta:StepBack()
+ 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
+function reader_meta:Peek()
+ return self.p, self.i + 1
+end
+function 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
+ return Read(setmetatable({
+ s = data,
+ i = 0,
+ c = string.sub(data, 0, 0),
+ p = string.sub(data, 1, 1),
+ }, reader_meta), {})
+end
+function 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