2024-03-13 01:01:27 +00:00
|
|
|
--!strict
|
|
|
|
--!native
|
|
|
|
--!optimize 2
|
|
|
|
local Buffer = {}
|
|
|
|
Buffer.__index = Buffer
|
|
|
|
|
|
|
|
local Dedicated = require(script.Dedicated)
|
|
|
|
|
|
|
|
local tostring = buffer.tostring
|
|
|
|
local fromstring = buffer.fromstring
|
2024-11-19 11:24:46 +00:00
|
|
|
local readu8 = buffer.readu8
|
|
|
|
local readi8 = buffer.readi8
|
|
|
|
local readu16 = buffer.readu16
|
|
|
|
local readi16 = buffer.readi16
|
|
|
|
local readi32 = buffer.readi32
|
|
|
|
local readf32 = buffer.readf32
|
|
|
|
local readf64 = buffer.readf64
|
|
|
|
local readstring = buffer.readstring
|
|
|
|
local len = buffer.len
|
2024-03-13 01:01:27 +00:00
|
|
|
|
2024-11-19 11:24:46 +00:00
|
|
|
local function readValue(b: buffer, position: number): (any, number)
|
|
|
|
local typeByte = readu8(b, position)
|
|
|
|
position += 1
|
2024-11-20 03:25:00 +00:00
|
|
|
if typeByte == 0 then -- nil
|
|
|
|
return nil, position
|
|
|
|
elseif typeByte == 1 then -- int u8
|
2024-11-19 11:24:46 +00:00
|
|
|
local value = readu8(b, position)
|
|
|
|
return value, position + 1
|
2024-11-20 03:25:00 +00:00
|
|
|
elseif typeByte == 2 then -- int i16
|
2024-11-19 11:24:46 +00:00
|
|
|
local value = readi16(b, position)
|
|
|
|
return value, position + 2
|
2024-11-20 03:25:00 +00:00
|
|
|
elseif typeByte == 3 then -- int i32
|
2024-11-19 11:24:46 +00:00
|
|
|
local value = readi32(b, position)
|
|
|
|
return value, position + 4
|
|
|
|
elseif typeByte == 4 then -- f64
|
|
|
|
local value = readf64(b, position)
|
|
|
|
return value, position + 8
|
|
|
|
elseif typeByte == 5 then -- boolean
|
|
|
|
local value = readu8(b, position) == 1
|
|
|
|
return value, position + 1
|
2024-11-20 03:25:00 +00:00
|
|
|
elseif typeByte == 6 then -- string u8
|
|
|
|
local length = readu8(b, position)
|
|
|
|
local value = readstring(b, position + 1, length)
|
|
|
|
return value, position + length + 1
|
|
|
|
elseif typeByte == 7 then -- string u16
|
|
|
|
local length = readu16(b, position)
|
|
|
|
local value = readstring(b, position + 2, length)
|
|
|
|
return value, position + length + 2
|
|
|
|
elseif typeByte == 8 then -- string i32
|
|
|
|
local length = readi32(b, position)
|
|
|
|
local value = readstring(b, position + 4, length)
|
|
|
|
return value, position + length + 4
|
|
|
|
elseif typeByte == 9 then -- Vector3
|
2024-11-19 11:24:46 +00:00
|
|
|
local x = readf32(b, position)
|
|
|
|
local y = readf32(b, position + 4)
|
|
|
|
local z = readf32(b, position + 8)
|
|
|
|
return Vector3.new(x, y, z), position + 12
|
2024-11-20 03:25:00 +00:00
|
|
|
elseif typeByte == 10 then -- Vector2
|
|
|
|
local x = readf32(b, position)
|
|
|
|
local y = readf32(b, position + 8)
|
|
|
|
return Vector2.new(x, y), position + 8
|
|
|
|
elseif typeByte == 11 then -- CFrame
|
2024-11-19 11:24:46 +00:00
|
|
|
local components = {}
|
|
|
|
for i = 1, 12 do
|
|
|
|
table.insert(components, readf32(b, position + (i - 1) * 4))
|
|
|
|
end
|
|
|
|
return CFrame.new(unpack(components)), position + 48
|
2024-11-20 03:25:00 +00:00
|
|
|
elseif typeByte == 12 then -- Vector2
|
|
|
|
local r = readu8(b, position)
|
|
|
|
local g = readu8(b, position + 1)
|
|
|
|
local b = readu8(b, position + 2)
|
|
|
|
return Color3.fromRGB(r, g, b), position + 3
|
|
|
|
elseif typeByte == 13 then -- array
|
|
|
|
local length = readu16(b, position)
|
|
|
|
position += 2
|
2024-11-19 11:24:46 +00:00
|
|
|
local array = {}
|
|
|
|
for _ = 1, length do
|
|
|
|
local value
|
|
|
|
value, position = readValue(b, position)
|
|
|
|
table.insert(array, value)
|
|
|
|
end
|
|
|
|
return array, position
|
2024-11-20 03:25:00 +00:00
|
|
|
elseif typeByte == 14 then -- dictionary
|
|
|
|
local length = readu16(b, position)
|
|
|
|
position += 2
|
2024-11-19 11:24:46 +00:00
|
|
|
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
|
2024-11-20 03:25:00 +00:00
|
|
|
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
|
2024-11-19 11:24:46 +00:00
|
|
|
end
|
|
|
|
error(`Unsupported type marker: {typeByte}`)
|
|
|
|
end
|
|
|
|
|
|
|
|
function Buffer.new(): Dedicated.DedicatedType
|
2024-03-13 01:01:27 +00:00
|
|
|
return Dedicated()
|
|
|
|
end
|
|
|
|
|
|
|
|
function Buffer.convert(b: buffer): string
|
|
|
|
return tostring(b)
|
|
|
|
end
|
|
|
|
|
|
|
|
function Buffer.revert(s: string): buffer
|
|
|
|
return fromstring(s)
|
|
|
|
end
|
|
|
|
|
2024-11-19 11:24:46 +00:00
|
|
|
function Buffer.write(data: { any }): buffer
|
|
|
|
local newBuffer = Dedicated()
|
|
|
|
newBuffer:pack(data)
|
|
|
|
return newBuffer:buildAndRemove()
|
|
|
|
end
|
|
|
|
|
|
|
|
function Buffer.read(b: buffer): any?
|
|
|
|
local position = 0
|
|
|
|
local result = {}
|
|
|
|
while position < len(b) do
|
|
|
|
local value
|
|
|
|
value, position = readValue(b, position)
|
|
|
|
table.insert(result, value)
|
|
|
|
end
|
|
|
|
return table.unpack(result)
|
|
|
|
end
|
|
|
|
|
2024-03-13 01:01:27 +00:00
|
|
|
return Buffer :: typeof(Buffer)
|