Skip to content

Commit

Permalink
Added Network.Compress and Network.Decompress functions
Browse files Browse the repository at this point in the history
- Added centralized compression and decompression functions for the networking library. These will also provide a way to optimize the network usage with vectors and add the posibility of sending entities.
  • Loading branch information
TwistedTail committed May 6, 2024
1 parent 762959a commit acd9cad
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 29 deletions.
109 changes: 109 additions & 0 deletions lua/acf/core/networking/networking_base.lua
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,112 @@ function Network.RemoveReceiver(Name)

Receiver[Name] = nil
end

do -- Data sanitization and compression
local ents = ents
local math = math
local table = table
local util = util
local Types = {
[TYPE_VECTOR] = {
Compress = function(Value)
return {
__t = TYPE_VECTOR,
math.floor(Value.x * 100),
math.floor(Value.y * 100),
math.floor(Value.z * 100),
}
end,
Decompress = function(Value)
return Vector(
Value[1] * 0.01,
Value[2] * 0.01,
Value[3] * 0.01
)
end,
},
[TYPE_ENTITY] = {
Compress = function(Value)
return {
__t = TYPE_ENTITY,
Value:EntIndex(),
}
end,
Decompress = function(Value)
return ents.GetByIndex(Value[1])
end,
},
}

local function ProcessRaw(Data, Result, Done)
local Keys = table.GetKeys(Data)

Result = Result or {}
Done = Done or {}

for I = 1, #Keys do
local Key = Keys[I]
local Value = Data[Key]

if istable(Value) and not Value.__t then
local Copy = Done[Value]

if not Copy then
Copy = {}

ProcessRaw(Value, Copy, Done)
end

Value = Copy
elseif Types[TypeID(Value)] then
local Functions = Types[TypeID(Value)]

Value = Functions.Compress(Value)
end

Result[Key] = Value
end

return Result
end

local function ProcessReceived(Data)
local Keys = table.GetKeys(Data)

for I = 1, #Keys do
local Key = Keys[I]
local Value = Data[Key]
if istable(Value) then
local Type = Value.__t
local Functions = Type and Types[Type]

if Functions then
Value = Functions.Decompress(Value)
else
ProcessReceived(Value)
end

end

Data[Key] = Value
end

return Data
end

function Network.Compress(Data)
local Processed = ProcessRaw(Data)
local Compress = util.Compress
local ToJSON = util.TableToJSON

return Compress(ToJSON(Processed))
end

function Network.Decompress(Data)
local Decompress = util.Decompress
local ToTable = util.JSONToTable
local Received = ToTable(Decompress(Data))

return ProcessReceived(Received)
end
end
29 changes: 13 additions & 16 deletions lua/acf/core/networking/networking_cl.lua
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
local ACF = ACF
local Network = ACF.Networking
local Sender = Network.Sender
local Receiver = Network.Receiver
local ToJSON = util.TableToJSON
local ToTable = util.JSONToTable
local Compress = util.Compress
local Decompress = util.Decompress
local Messages = {}
local ACF = ACF
local Network = ACF.Networking
local Sender = Network.Sender
local Receiver = Network.Receiver
local Messages = {}
local IsQueued

local function PrepareQueue(Name)
Expand All @@ -20,7 +16,7 @@ end
-- NOTE: Consider the overflow size
local function SendMessages()
if next(Messages) then
local Compressed = Compress(ToJSON(Messages))
local Compressed = Network.Compress(Messages)

net.Start("ACF_Networking")
net.WriteUInt(#Compressed, 16)
Expand Down Expand Up @@ -52,14 +48,15 @@ function Network.Send(Name, ...)
end

net.Receive("ACF_Networking", function(Bits)
local Bytes = net.ReadUInt(16)
local String = Decompress(net.ReadData(Bytes))
local Message = ToTable(String)
local Bytes = net.ReadUInt(16)
local Received = net.ReadData(Bytes)
local Message = Network.Decompress(Received)

if not Message then
local Error = "ACF Networking: Failed to parse message. Report this to the ACF Team.\nMessage size: %sB\nTotal size: %sB\nMessage: %s"
local Total = Bits * 0.125 -- Bits to bytes
local JSON = String ~= "" and String or "Empty, possible overflow."
local Error = "ACF Networking: Failed to parse message. Report this to the ACF Team.\nMessage size: %sB\nTotal size: %sB\nMessage: %s"
local Total = Bits * 0.125 -- Bits to bytes
local String = util.Decompress(Received)
local JSON = String ~= "" and String or "Empty, possible overflow."

ErrorNoHalt(Error:format(Bytes, Total, JSON))

Expand Down
21 changes: 8 additions & 13 deletions lua/acf/core/networking/networking_sv.lua
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
local ACF = ACF
local Network = ACF.Networking
local Sender = Network.Sender
local Receiver = Network.Receiver
local ToJSON = util.TableToJSON
local ToTable = util.JSONToTable
local Compress = util.Compress
local Decompress = util.Decompress
local Messages = {}
local ACF = ACF
local Network = ACF.Networking
local Sender = Network.Sender
local Receiver = Network.Receiver
local Messages = {}
local IsQueued

util.AddNetworkString("ACF_Networking")
Expand All @@ -28,7 +24,7 @@ local function SendMessages()
local All = Messages.All

if All and next(All) then
local Compressed = Compress(ToJSON(All))
local Compressed = Network.Compress(All) --Compress(ToJSON(All))

net.Start("ACF_Networking")
net.WriteUInt(#Compressed, 16)
Expand All @@ -40,7 +36,7 @@ local function SendMessages()

if next(Messages) then
for Target, Data in pairs(Messages) do
local Compressed = Compress(ToJSON(Data))
local Compressed = Network.Compress(Data) --Compress(ToJSON(Data))

net.Start("ACF_Networking")
net.WriteUInt(#Compressed, 16)
Expand Down Expand Up @@ -89,8 +85,7 @@ end

net.Receive("ACF_Networking", function(_, Player)
local Bytes = net.ReadUInt(16)
local String = Decompress(net.ReadData(Bytes))
local Message = ToTable(String)
local Message = Network.Decompress(net.ReadData(Bytes))

for Name, Data in pairs(Message) do
local Handler = Receiver[Name]
Expand Down

0 comments on commit acd9cad

Please sign in to comment.