2024-03-13 01:01:27 +00:00
|
|
|
--!strict
|
|
|
|
--!native
|
|
|
|
--!optimize 2
|
|
|
|
local DedicatedBuffer = {}
|
|
|
|
DedicatedBuffer.__index = DedicatedBuffer
|
|
|
|
|
|
|
|
local create = buffer.create
|
|
|
|
local copy = buffer.copy
|
2024-03-16 16:49:23 +00:00
|
|
|
local writei8 = buffer.writei8
|
|
|
|
local writei16 = buffer.writei16
|
|
|
|
local writei32 = buffer.writei32
|
2024-03-13 01:01:27 +00:00
|
|
|
local writeu8 = buffer.writeu8
|
2024-03-16 16:49:23 +00:00
|
|
|
local writeu16 = buffer.writeu16
|
|
|
|
local writeu32 = buffer.writeu32
|
|
|
|
local writef32 = buffer.writef32
|
|
|
|
local writef64 = buffer.writef64
|
|
|
|
local writestring = buffer.writestring
|
2024-03-13 01:01:27 +00:00
|
|
|
|
2024-11-19 11:24:46 +00:00
|
|
|
local default: { [string]: number } = {
|
2024-03-13 01:01:27 +00:00
|
|
|
point = 0,
|
2024-03-16 16:49:23 +00:00
|
|
|
next = 0,
|
2024-11-20 03:25:00 +00:00
|
|
|
size = 128,
|
|
|
|
bufferSize = 128,
|
2024-03-13 01:01:27 +00:00
|
|
|
}
|
|
|
|
|
2024-03-17 09:04:48 +00:00
|
|
|
function DedicatedBuffer.copy(self: any, offset: number, b: buffer?, src: buffer?, srcOffset: number?, count: number?)
|
|
|
|
if not b then
|
|
|
|
copy(create(count or default.size), offset, src or self.buffer, srcOffset, count)
|
|
|
|
else
|
|
|
|
copy(b, offset, src or self.buffer, srcOffset, count)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2024-03-13 01:01:27 +00:00
|
|
|
function DedicatedBuffer.alloc(self: any, byte: number)
|
|
|
|
local size: number = self.size
|
|
|
|
local b: buffer = self.buffer
|
2024-03-24 09:36:31 +00:00
|
|
|
|
2024-11-19 11:24:46 +00:00
|
|
|
while self.next + byte >= size do
|
2024-11-30 16:49:37 +00:00
|
|
|
size = math.floor(size * 1.25) -- +25% increase
|
2024-03-13 01:01:27 +00:00
|
|
|
end
|
|
|
|
local newBuffer: buffer = create(size)
|
|
|
|
copy(newBuffer, 0, b)
|
|
|
|
|
|
|
|
b = newBuffer
|
2024-03-16 16:49:23 +00:00
|
|
|
|
|
|
|
self.point = self.next
|
2024-11-19 11:24:46 +00:00
|
|
|
self.buffer = b
|
2024-03-16 16:49:23 +00:00
|
|
|
self.next += byte
|
2024-03-13 01:01:27 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
function DedicatedBuffer.build(self: any): buffer
|
2024-03-24 09:36:31 +00:00
|
|
|
local p: number = self.next > self.point and self.next or self.point
|
2024-03-13 01:01:27 +00:00
|
|
|
local build: buffer = create(p)
|
|
|
|
|
|
|
|
copy(build, 0, self.buffer, 0, p)
|
|
|
|
return build
|
|
|
|
end
|
|
|
|
|
2024-11-23 12:50:06 +00:00
|
|
|
function DedicatedBuffer.buildAndRemove(self: any): (buffer, (any)?)
|
2024-11-19 11:24:46 +00:00
|
|
|
local p: number = self.next > self.point and self.next or self.point
|
|
|
|
local build: buffer = create(p)
|
2024-11-23 12:50:06 +00:00
|
|
|
local ref = #self.ref > 0 and table.clone(self.ref) or nil
|
2024-11-19 11:24:46 +00:00
|
|
|
|
|
|
|
copy(build, 0, self.buffer, 0, p)
|
2024-12-02 07:37:46 +00:00
|
|
|
|
2024-11-19 11:24:46 +00:00
|
|
|
self:remove()
|
2024-11-23 12:50:06 +00:00
|
|
|
return build, ref
|
2024-11-19 11:24:46 +00:00
|
|
|
end
|
|
|
|
|
2024-11-20 03:25:00 +00:00
|
|
|
function DedicatedBuffer.wi8(self: any, val: number, alloc: number?)
|
2024-04-02 06:10:21 +00:00
|
|
|
if not val then return end
|
2024-11-20 03:25:00 +00:00
|
|
|
self:alloc(alloc or 1)
|
2024-03-16 16:49:23 +00:00
|
|
|
writei8(self.buffer, self.point, val)
|
|
|
|
end
|
|
|
|
|
2024-11-20 03:25:00 +00:00
|
|
|
function DedicatedBuffer.wi16(self: any, val: number, alloc: number?)
|
2024-04-02 06:10:21 +00:00
|
|
|
if not val then return end
|
2024-11-20 03:25:00 +00:00
|
|
|
self:alloc(alloc or 2)
|
2024-03-16 16:49:23 +00:00
|
|
|
writei16(self.buffer, self.point, val)
|
|
|
|
end
|
|
|
|
|
2024-11-20 03:25:00 +00:00
|
|
|
function DedicatedBuffer.wi32(self: any, val: number, alloc: number?)
|
2024-04-02 06:10:21 +00:00
|
|
|
if not val then return end
|
2024-11-20 03:25:00 +00:00
|
|
|
self:alloc(alloc or 4)
|
2024-03-16 16:49:23 +00:00
|
|
|
writei32(self.buffer, self.point, val)
|
|
|
|
end
|
|
|
|
|
2024-11-20 03:25:00 +00:00
|
|
|
function DedicatedBuffer.wu8(self: any, val: number, alloc: number?)
|
2024-04-02 06:10:21 +00:00
|
|
|
if not val then return end
|
2024-11-20 03:25:00 +00:00
|
|
|
self:alloc(alloc or 1)
|
2024-03-13 01:01:27 +00:00
|
|
|
writeu8(self.buffer, self.point, val)
|
2024-03-16 16:49:23 +00:00
|
|
|
end
|
|
|
|
|
2024-11-20 03:25:00 +00:00
|
|
|
function DedicatedBuffer.wu16(self: any, val: number, alloc: number?)
|
2024-04-02 06:10:21 +00:00
|
|
|
if not val then return end
|
2024-11-20 03:25:00 +00:00
|
|
|
self:alloc(alloc or 2)
|
2024-03-16 16:49:23 +00:00
|
|
|
writeu16(self.buffer, self.point, val)
|
|
|
|
end
|
|
|
|
|
2024-11-20 03:25:00 +00:00
|
|
|
function DedicatedBuffer.wu32(self: any, val: number, alloc: number?)
|
2024-04-02 06:10:21 +00:00
|
|
|
if not val then return end
|
2024-11-20 03:25:00 +00:00
|
|
|
self:alloc(alloc or 4)
|
2024-03-16 16:49:23 +00:00
|
|
|
writeu32(self.buffer, self.point, val)
|
|
|
|
end
|
|
|
|
|
2024-11-20 03:25:00 +00:00
|
|
|
function DedicatedBuffer.wf32(self: any, val: number, alloc: number?)
|
2024-04-02 06:10:21 +00:00
|
|
|
if not val then return end
|
2024-11-20 03:25:00 +00:00
|
|
|
self:alloc(alloc or 4)
|
2024-03-16 16:49:23 +00:00
|
|
|
writef32(self.buffer, self.point, val)
|
|
|
|
end
|
|
|
|
|
2024-11-20 03:25:00 +00:00
|
|
|
function DedicatedBuffer.wf64(self: any, val: number, alloc: number?)
|
2024-04-02 06:10:21 +00:00
|
|
|
if not val then return end
|
2024-11-20 03:25:00 +00:00
|
|
|
self:alloc(alloc or 8)
|
2024-03-16 16:49:23 +00:00
|
|
|
writef64(self.buffer, self.point, val)
|
|
|
|
end
|
|
|
|
|
|
|
|
function DedicatedBuffer.wstring(self: any, val: string)
|
2024-04-02 06:10:21 +00:00
|
|
|
if not val then return end
|
2024-04-09 08:49:06 +00:00
|
|
|
self:alloc(#val)
|
2024-03-16 16:49:23 +00:00
|
|
|
writestring(self.buffer, self.point, val)
|
2024-03-13 01:01:27 +00:00
|
|
|
end
|
|
|
|
|
2024-11-20 03:25:00 +00:00
|
|
|
function DedicatedBuffer.wType(self: any, ref: number)
|
|
|
|
writeu8(self.buffer, self.point, ref)
|
2024-11-19 11:24:46 +00:00
|
|
|
self.point += 1
|
|
|
|
end
|
|
|
|
|
2024-11-23 12:50:06 +00:00
|
|
|
function DedicatedBuffer.wRef(self: any, value: any, alloc: number?)
|
2024-12-02 07:37:46 +00:00
|
|
|
if not value then return end
|
2024-11-23 12:50:06 +00:00
|
|
|
self:alloc(alloc or 1)
|
|
|
|
table.insert(self.ref, value)
|
|
|
|
local index = #self.ref
|
|
|
|
writeu8(self.buffer, self.point, index)
|
|
|
|
self.point += 1
|
|
|
|
end
|
|
|
|
|
2024-11-19 11:24:46 +00:00
|
|
|
function DedicatedBuffer.pack(self: any, data: {any})
|
2024-11-20 03:25:00 +00:00
|
|
|
if typeof(data) == "nil" then
|
|
|
|
self:wi8(0)
|
2024-11-21 06:57:53 +00:00
|
|
|
elseif typeof(data) == "Instance" then
|
|
|
|
self:wi8(-1) -- Instance marker
|
2024-11-23 12:50:06 +00:00
|
|
|
self:wRef(data)
|
2024-11-21 06:57:53 +00:00
|
|
|
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}`)
|
2024-11-20 03:25:00 +00:00
|
|
|
elseif typeof(data) == "number" then
|
2024-11-19 11:24:46 +00:00
|
|
|
if math.floor(data) == data then -- Integer
|
|
|
|
if data >= 0 and data <= 255 then
|
|
|
|
self:wi8(1) -- u8 marker
|
|
|
|
self:wu8(data)
|
|
|
|
elseif data >= -32768 and data <= 32767 then
|
|
|
|
self:wi8(2) -- i16 marker
|
|
|
|
self:wi16(data)
|
|
|
|
elseif data >= -2147483647 and data <= 2147483647 then
|
|
|
|
self:wi8(3) -- i32 marker
|
|
|
|
self:wi32(data)
|
|
|
|
else
|
|
|
|
self:wi8(4) -- f64 marker
|
|
|
|
self:wf64(data)
|
|
|
|
end
|
|
|
|
else
|
|
|
|
self:wi8(4) -- f64 marker
|
|
|
|
self:wf64(data)
|
|
|
|
end
|
|
|
|
elseif typeof(data) == "boolean" then
|
|
|
|
self:wi8(5) -- boolean marker
|
|
|
|
self:wu8(data and 1 or 0)
|
|
|
|
elseif typeof(data) == "string" then
|
|
|
|
local length = #data
|
2024-11-20 03:25:00 +00:00
|
|
|
if length <= 255 then
|
|
|
|
self:wi8(6)
|
|
|
|
self:wu8(length)
|
|
|
|
elseif length <= 65535 then
|
|
|
|
self:wi8(7)
|
|
|
|
self:wu16(length)
|
2024-11-19 11:24:46 +00:00
|
|
|
else
|
2024-11-20 03:25:00 +00:00
|
|
|
self:wi8(8)
|
|
|
|
self:wi32(length)
|
2024-11-19 11:24:46 +00:00
|
|
|
end
|
|
|
|
self:wstring(data)
|
|
|
|
elseif typeof(data) == "Vector3" then
|
2024-11-20 03:25:00 +00:00
|
|
|
self:wi8(9) -- Vector3 marker
|
2024-11-19 11:24:46 +00:00
|
|
|
self:wf32(data.X)
|
|
|
|
self:wf32(data.Y)
|
|
|
|
self:wf32(data.Z)
|
2024-11-20 03:25:00 +00:00
|
|
|
elseif typeof(data) == "Vector2" then
|
|
|
|
self:wi8(10) -- Vector2 marker
|
|
|
|
self:wf32(data.X)
|
|
|
|
self:wf32(data.Y)
|
2024-11-19 11:24:46 +00:00
|
|
|
elseif typeof(data) == "CFrame" then
|
2024-11-20 03:25:00 +00:00
|
|
|
self:wi8(11) -- CFrame marker
|
2024-11-19 11:24:46 +00:00
|
|
|
for _, v in {data:GetComponents()} do
|
|
|
|
self:wf32(v)
|
|
|
|
end
|
2024-11-20 03:25:00 +00:00
|
|
|
elseif typeof(data) == "Color3" then
|
|
|
|
self:wi8(12) -- Color3 marker
|
|
|
|
self:wu8(data.R * 255)
|
|
|
|
self:wu8(data.G * 255)
|
|
|
|
self:wu8(data.B * 255)
|
2024-11-19 11:24:46 +00:00
|
|
|
else
|
2024-11-20 03:25:00 +00:00
|
|
|
warn(`Unsupported data type: {typeof(data)} value: {data}`)
|
2024-11-19 11:24:46 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2024-03-13 01:01:27 +00:00
|
|
|
function DedicatedBuffer.flush(self: any)
|
|
|
|
self.point = default.point
|
2024-03-16 16:49:23 +00:00
|
|
|
self.next = default.next
|
2024-03-13 01:01:27 +00:00
|
|
|
self.size = default.size
|
2024-03-16 16:49:23 +00:00
|
|
|
self.buffer = create(default.bufferSize)
|
2024-11-23 12:50:06 +00:00
|
|
|
table.clear(self.ref)
|
2024-03-13 01:01:27 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
function DedicatedBuffer.new()
|
|
|
|
return setmetatable({
|
|
|
|
point = default.point,
|
2024-03-16 16:49:23 +00:00
|
|
|
next = default.next,
|
2024-03-13 01:01:27 +00:00
|
|
|
size = default.size,
|
2024-11-23 12:50:06 +00:00
|
|
|
buffer = create(default.bufferSize),
|
|
|
|
ref = {},
|
2024-03-13 01:01:27 +00:00
|
|
|
}, DedicatedBuffer)
|
|
|
|
end
|
|
|
|
|
|
|
|
function DedicatedBuffer.remove(self: any)
|
2024-11-19 11:24:46 +00:00
|
|
|
self:flush()
|
2024-09-27 04:10:12 +00:00
|
|
|
table.clear(self)
|
2024-03-13 01:01:27 +00:00
|
|
|
setmetatable(self, nil)
|
|
|
|
end
|
|
|
|
|
2024-11-19 11:24:46 +00:00
|
|
|
export type DedicatedType = typeof(DedicatedBuffer.new())
|
|
|
|
|
2024-03-13 01:01:27 +00:00
|
|
|
return DedicatedBuffer.new :: typeof(DedicatedBuffer.new)
|