add more type support to buffer

This commit is contained in:
EternityDev 2024-11-21 13:57:53 +07:00
parent 8ba9540550
commit 91862a65fe
3 changed files with 86 additions and 62 deletions

BIN
Warp.rbxm

Binary file not shown.

View file

@ -127,6 +127,47 @@ end
function DedicatedBuffer.pack(self: any, data: {any}) function DedicatedBuffer.pack(self: any, data: {any})
if typeof(data) == "nil" then if typeof(data) == "nil" then
self:wi8(0) self:wi8(0)
elseif typeof(data) == "Instance" then
self:wi8(-1) -- Instance marker
self:pack(data.ClassName) -- Serialize ClassName
self:pack(data.Name) -- Serialize Name
self:pack(data:GetAttributes())
elseif typeof(data) == "table" then
--local isArray = (next(data) ~= nil and #data > 0) and true or false
local isArray = true
local count = 0
for k in data do
count += 1
if typeof(k) ~= "number" or math.floor(k) ~= k then
isArray = false
end
end
if isArray then
self:wi8(-2) -- array marker
self:wu16(count) -- use 32-bit length
for _, v in data do
self:pack(v)
end
else
self:wi8(-3) -- dictionary marker
self:wu16(count) -- number of key-value pairs
for k, v in data do
self:pack(k) -- pack the key
self:pack(v) -- pack the value
end
end
elseif typeof(data) == "EnumItem" then
self:wi8(-4)
self:wi8(#`{data.EnumType}`)
self:wstring(`{data.EnumType}`)
self:wu8(data.Value)
elseif typeof(data) == "BrickColor" then
self:wi8(-5)
self:wi16(data.Number)
elseif typeof(data) == "Enum" then
self:wi8(-6)
self:wi8(#`{data}`)
self:wstring(`{data}`)
elseif typeof(data) == "number" then elseif typeof(data) == "number" then
if math.floor(data) == data then -- Integer if math.floor(data) == data then -- Integer
if data >= 0 and data <= 255 then if data >= 0 and data <= 255 then
@ -181,35 +222,6 @@ function DedicatedBuffer.pack(self: any, data: {any})
self:wu8(data.R * 255) self:wu8(data.R * 255)
self:wu8(data.G * 255) self:wu8(data.G * 255)
self:wu8(data.B * 255) self:wu8(data.B * 255)
elseif typeof(data) == "table" then
--local isArray = (next(data) ~= nil and #data > 0) and true or false
local isArray = true
local count = 0
for k in data do
count += 1
if typeof(k) ~= "number" or math.floor(k) ~= k then
isArray = false
end
end
if isArray then
self:wi8(13) -- array marker
self:wu16(count) -- use 32-bit length
for _, v in data do
self:pack(v)
end
else
self:wi8(14) -- dictionary marker
self:wu16(count) -- number of key-value pairs
for k, v in data do
self:pack(k) -- pack the key
self:pack(v) -- pack the value
end
end
elseif typeof(data) == "Instance" then
self:wi8(15) -- Instance marker
self:pack(data.ClassName) -- Serialize ClassName
self:pack(data.Name) -- Serialize Name
self:pack(data:GetAttributes())
else else
warn(`Unsupported data type: {typeof(data)} value: {data}`) warn(`Unsupported data type: {typeof(data)} value: {data}`)
end end

View file

@ -19,10 +19,53 @@ local readstring = buffer.readstring
local len = buffer.len local len = buffer.len
local function readValue(b: buffer, position: number): (any, number) local function readValue(b: buffer, position: number): (any, number)
local typeByte = readu8(b, position) local typeByte = readi8(b, position)
position += 1 position += 1
if typeByte == 0 then -- nil if typeByte == 0 then -- nil
return nil, position return nil, position
elseif typeByte == -1 then -- Instance
local className, position1 = readValue(b, position)
local name, position2 = readValue(b, position1)
local properties, position3 = readValue(b, position2)
local instance: Instance = Instance.new(className)
instance.Name = name
for key, value in properties do
instance:SetAttribute(key, value)
end
return instance, position3
elseif typeByte == -2 then -- array
local length = readu16(b, position)
position += 2
local array = {}
for _ = 1, length do
local value
value, position = readValue(b, position)
table.insert(array, value)
end
return array, position
elseif typeByte == -3 then -- dictionary
local length = readu16(b, position)
position += 2
local dict = {}
for _ = 1, length do
local key, value
key, position = readValue(b, position)
value, position = readValue(b, position)
dict[key] = value
end
return dict, position
elseif typeByte == -4 then -- EnumItem
local length = readi8(b, position)
local value = readstring(b, position + 1, length)
local value2 = readu8(b, position + 1 + length)
return Enum[value]:FromValue(value2), position + 2 + length
elseif typeByte == -5 then -- BrickColor
local value = readi16(b, position)
return BrickColor.new(value), position + 2
elseif typeByte == -6 then -- Enum
local length = readi8(b, position)
local value = readstring(b, position + 1, length)
return Enum[value], position + 1 + length
elseif typeByte == 1 then -- int u8 elseif typeByte == 1 then -- int u8
local value = readu8(b, position) local value = readu8(b, position)
return value, position + 1 return value, position + 1
@ -65,42 +108,11 @@ local function readValue(b: buffer, position: number): (any, number)
table.insert(components, readf32(b, position + (i - 1) * 4)) table.insert(components, readf32(b, position + (i - 1) * 4))
end end
return CFrame.new(unpack(components)), position + 48 return CFrame.new(unpack(components)), position + 48
elseif typeByte == 12 then -- Vector2 elseif typeByte == 12 then -- Color3
local r = readu8(b, position) local r = readu8(b, position)
local g = readu8(b, position + 1) local g = readu8(b, position + 1)
local b = readu8(b, position + 2) local b = readu8(b, position + 2)
return Color3.fromRGB(r, g, b), position + 3 return Color3.fromRGB(r, g, b), position + 3
elseif typeByte == 13 then -- array
local length = readu16(b, position)
position += 2
local array = {}
for _ = 1, length do
local value
value, position = readValue(b, position)
table.insert(array, value)
end
return array, position
elseif typeByte == 14 then -- dictionary
local length = readu16(b, position)
position += 2
local dict = {}
for _ = 1, length do
local key, value
key, position = readValue(b, position)
value, position = readValue(b, position)
dict[key] = value
end
return dict, position
elseif typeByte == 15 then -- Instance
local className, position1 = readValue(b, position)
local name, position2 = readValue(b, position1)
local properties, position3 = readValue(b, position2)
local instance: Instance = Instance.new(className)
instance.Name = name
for key, value in properties do
instance:SetAttribute(key, value)
end
return instance, position3
end end
error(`Unsupported type marker: {typeByte}`) error(`Unsupported type marker: {typeByte}`)
end end