This commit is contained in:
EternityDev 2024-11-19 18:24:46 +07:00
parent a377788f22
commit 22996c9357
15 changed files with 242 additions and 294 deletions

View file

@ -1,37 +0,0 @@
--!strict
--!optimize 2
local Logger = {}
local Logs: {
[string]: {
[string]: string
}
} = {}
local logging: {
[string]: boolean
} = {}
local now = tick()
function Logger.write(Identifier: string, text: string, log: boolean?)
if not Logs[Identifier] then
Logs[Identifier] = {}
end
if log ~= nil then
logging[Identifier] = log
end
now = tick()
Logs[Identifier][tostring(now)] = text
if logging[Identifier] then
print(`[{now}] ->`, text)
end
end
function Logger.read(Identifier: string)
return Logs[Identifier]
end
function Logger.clear(Identifier: string)
Logs[Identifier] = nil
end
return Logger :: typeof(Logger)

View file

@ -12,18 +12,14 @@ local Spawn = require(Util.Spawn)
local Key = require(Util.Key) local Key = require(Util.Key)
local RateLimit = require(Util.RateLimit) local RateLimit = require(Util.RateLimit)
local Buffer = require(Util.Buffer) local Buffer = require(Util.Buffer)
local Logger = require(script.Logger)
local clientRatelimit: Type.StoredRatelimit = {} local clientRatelimit: Type.StoredRatelimit = {}
local clientQueue: Type.QueueMap = {} local clientQueue: Type.QueueMap = {}
local unreliableClientQueue: Type.QueueMap = {} local unreliableClientQueue: Type.QueueMap = {}
local clientCallback: Type.CallbackMap = {} local clientCallback: Type.CallbackMap = {}
local clientRequestQueue: Type.QueueMap = {} local clientRequestQueue: Type.QueueMap = {}
local registeredIdentifier: { string } = {} local registeredIdentifier: { [string]: boolean } = {}
local queueIn: {
[string]: {any}
} = {}
local queueInRequest: { local queueInRequest: {
[number]: { [number]: {
[string]: { [string]: {
@ -38,9 +34,6 @@ local queueOutRequest: {
} }
} }
} = {} } = {}
local logger: {
[string]: boolean
} = {}
queueInRequest[1] = {} queueInRequest[1] = {}
queueInRequest[2] = {} queueInRequest[2] = {}
@ -82,12 +75,9 @@ function ClientProcess.insertRequest(Identifier: string, timeout: number, ...: a
end end
function ClientProcess.add(Identifier: any, originId: string, conf: Type.ClientConf) function ClientProcess.add(Identifier: any, originId: string, conf: Type.ClientConf)
if not table.find(registeredIdentifier, Identifier) then if not registeredIdentifier[Identifier] then
table.insert(registeredIdentifier, Identifier) registeredIdentifier[Identifier] = true
if conf.logging then
ClientProcess.logger(Identifier, conf.logging.store, conf.logging.opt)
end
if not clientRatelimit[Identifier] then if not clientRatelimit[Identifier] then
clientRatelimit[Identifier] = RateLimit.create(originId) clientRatelimit[Identifier] = RateLimit.create(originId)
end end
@ -116,15 +106,12 @@ function ClientProcess.add(Identifier: any, originId: string, conf: Type.ClientC
if not queueInRequest[2][Identifier] then if not queueInRequest[2][Identifier] then
queueInRequest[2][Identifier] = {} queueInRequest[2][Identifier] = {}
end end
if not queueIn[Identifier] then
queueIn[Identifier] = {}
end
end end
end end
function ClientProcess.remove(Identifier: string) function ClientProcess.remove(Identifier: string)
if not table.find(registeredIdentifier, Identifier) then return end if not registeredIdentifier[Identifier] then return end
table.remove(registeredIdentifier, table.find(registeredIdentifier, Identifier)) registeredIdentifier[Identifier] = nil
clientQueue[Identifier] = nil clientQueue[Identifier] = nil
unreliableClientQueue[Identifier] = nil unreliableClientQueue[Identifier] = nil
clientRequestQueue[Identifier] = nil clientRequestQueue[Identifier] = nil
@ -134,31 +121,14 @@ function ClientProcess.remove(Identifier: string)
queueOutRequest[2][Identifier] = nil queueOutRequest[2][Identifier] = nil
queueInRequest[1][Identifier] = nil queueInRequest[1][Identifier] = nil
queueInRequest[2][Identifier] = nil queueInRequest[2][Identifier] = nil
queueIn[Identifier] = nil
Logger.clear(Identifier)
end
function ClientProcess.logger(Identifier: string, store: boolean, log: boolean)
logger[Identifier] = store
Logger.write(Identifier, `state: change -> {log == true and "enabled" or "disabled"} logger.`, log)
end
function ClientProcess.getlogs(Identifier: string)
return Logger.read(Identifier)
end end
function ClientProcess.addCallback(Identifier: string, key: string, callback) function ClientProcess.addCallback(Identifier: string, key: string, callback)
clientCallback[Identifier][key] = callback clientCallback[Identifier][key] = callback
if logger[Identifier] then
task.defer(Logger.write, Identifier, `state: change -> new callback added.`)
end
end end
function ClientProcess.removeCallback(Identifier: string, key: string) function ClientProcess.removeCallback(Identifier: string, key: string)
clientCallback[Identifier][key] = nil clientCallback[Identifier][key] = nil
if logger[Identifier] then
task.defer(Logger.write, Identifier, `state: change -> removed a callback.`)
end
end end
function ClientProcess.start() function ClientProcess.start()
@ -168,9 +138,8 @@ function ClientProcess.start()
for Identifier: string, data: any in unreliableClientQueue do for Identifier: string, data: any in unreliableClientQueue do
if #data == 0 then continue end if #data == 0 then continue end
if clientRatelimit[Identifier](#data) then if clientRatelimit[Identifier](#data) then
UnreliableEvent:FireServer(Buffer.revert(Identifier), data) for _, unpacked in data do
if logger[Identifier] then UnreliableEvent:FireServer(Buffer.write(unpacked))
task.defer(Logger.write, Identifier, `state: out -> unreliable -> {#data} data.`)
end end
end end
unreliableClientQueue[Identifier] = nil unreliableClientQueue[Identifier] = nil
@ -179,9 +148,8 @@ function ClientProcess.start()
for Identifier: string, data: any in clientQueue do for Identifier: string, data: any in clientQueue do
if #data > 0 then if #data > 0 then
if clientRatelimit[Identifier](#data) then if clientRatelimit[Identifier](#data) then
ReliableEvent:FireServer(Buffer.revert(Identifier), data) for _, unpacked in data do
if logger[Identifier] then ReliableEvent:FireServer(Buffer.write(unpacked))
task.defer(Logger.write, Identifier, `state: out -> reliable -> {#data} data.`)
end end
end end
clientQueue[Identifier] = nil clientQueue[Identifier] = nil
@ -191,22 +159,16 @@ function ClientProcess.start()
for Identifier: string, requestsData in queueOutRequest[1] do for Identifier: string, requestsData in queueOutRequest[1] do
if #requestsData == 0 then continue end if #requestsData == 0 then continue end
RequestEvent:FireServer(Buffer.revert(Identifier), "\1", requestsData) RequestEvent:FireServer(Buffer.revert(Identifier), "\1", requestsData)
if logger[Identifier] then
task.defer(Logger.write, Identifier, `state: out -> request -> {#requestsData} data.`)
end
queueOutRequest[1][Identifier] = nil queueOutRequest[1][Identifier] = nil
end end
-- Sent returning invokes -- Sent returning invokes
for Identifier: string, toReturnDatas in queueOutRequest[2] do for Identifier: string, toReturnDatas in queueOutRequest[2] do
if #toReturnDatas == 0 then continue end if #toReturnDatas == 0 then continue end
RequestEvent:FireServer(Buffer.revert(Identifier), "\0", toReturnDatas) RequestEvent:FireServer(Buffer.revert(Identifier), "\0", toReturnDatas)
if logger[Identifier] then
task.defer(Logger.write, Identifier, `state: out -> return request -> {#toReturnDatas} data.`)
end
queueOutRequest[2][Identifier] = nil queueOutRequest[2][Identifier] = nil
end end
for _, Identifier: string in registeredIdentifier do for Identifier: string in registeredIdentifier do
if clientRequestQueue[Identifier] then if clientRequestQueue[Identifier] then
for _, requestData in clientRequestQueue[Identifier] do for _, requestData in clientRequestQueue[Identifier] do
if not requestData[3] then continue end if not requestData[3] then continue end
@ -222,18 +184,6 @@ function ClientProcess.start()
local callback = clientCallback[Identifier] or nil local callback = clientCallback[Identifier] or nil
if not callback then continue end if not callback then continue end
if queueIn[Identifier] then
for _, packedDatas: any in queueIn[Identifier] do
if #packedDatas == 0 then continue end
for _, fn: any in callback do
for i=1,#packedDatas do
Spawn(fn, table.unpack(packedDatas[i] or {}))
end
end
end
queueIn[Identifier] = nil
end
-- Return Invoke -- Return Invoke
if queueInRequest[1][Identifier] then if queueInRequest[1][Identifier] then
for _, packetDatas: any in queueInRequest[1][Identifier] do for _, packetDatas: any in queueInRequest[1][Identifier] do
@ -280,15 +230,16 @@ function ClientProcess.start()
end end
end end
end) end)
local function onClientNetworkReceive(Identifier: any, data: any) local function onClientNetworkReceive(data: buffer)
if not Identifier or not data then return end if not data then return end
Identifier = Buffer.convert(Identifier) local read = Buffer.read(data)
if not queueIn[Identifier] then if not read then return end
queueIn[Identifier] = {} for Identifier: string in registeredIdentifier do
end local callback = clientCallback[Identifier] or nil
table.insert(queueIn[Identifier], data) if not callback then continue end
if logger[Identifier] then for _, fn: any in callback do
task.defer(Logger.write, Identifier, `state: in -> net -> {#data} data.`) Spawn(fn, table.unpack(read))
end
end end
end end
ReliableEvent.OnClientEvent:Connect(onClientNetworkReceive) ReliableEvent.OnClientEvent:Connect(onClientNetworkReceive)
@ -307,9 +258,6 @@ function ClientProcess.start()
end end
table.insert(queueInRequest[2][Identifier], data) table.insert(queueInRequest[2][Identifier], data)
end end
if logger[Identifier] then
task.defer(Logger.write, Identifier, `state: in -> request -> {#data} data.`)
end
end) end)
end end

View file

@ -24,17 +24,12 @@ function Client.new(Identifier: string, conf: Type.ClientConf?)
self._conf = table.freeze(conf or {}) self._conf = table.freeze(conf or {})
self.IsConnected = false self.IsConnected = false
ClientProcess.add(self.id, Identifier, conf or { yieldWait = 10, logging = { store = false, opt = false } }) ClientProcess.add(self.id, Identifier, conf or { yieldWait = 10 })
self._buffer:remove() self._buffer:remove()
return self return self
end end
function Client:logs()
Assert(self._conf.logging, "[Client]: Event is not configured with logging.")
return ClientProcess.getlogs(self.id)
end
function Client:Fire(reliable: boolean,...: any) function Client:Fire(reliable: boolean,...: any)
ClientProcess.insertQueue(self.id, reliable, ...) ClientProcess.insertQueue(self.id, reliable, ...)
end end

View file

@ -30,11 +30,6 @@ function Server.new(Identifier: string, conf: Type.ServerConf?)
return self return self
end end
function Server:logs()
Assert(self._conf.logging, "[Server]: Event is not configured with logging.")
return ServerProcess.getlogs(self.id)
end
function Server:Fire(reliable: boolean, player: Player, ...: any) function Server:Fire(reliable: boolean, player: Player, ...: any)
ServerProcess.insertQueue(self.id, reliable, player, ...) ServerProcess.insertQueue(self.id, reliable, player, ...)
end end

View file

@ -1,37 +0,0 @@
--!strict
--!optimize 2
local Logger = {}
local Logs: {
[string]: {
[string]: string
}
} = {}
local logging: {
[string]: boolean
} = {}
local now = tick()
function Logger.write(Identifier: string, text: string, log: boolean?)
if not Logs[Identifier] then
Logs[Identifier] = {}
end
if log ~= nil then
logging[Identifier] = log
end
now = tick()
Logs[Identifier][tostring(now)] = text
if logging[Identifier] then
print(`[{now}] ->`, text)
end
end
function Logger.read(Identifier: string)
return Logs[Identifier]
end
function Logger.clear(Identifier: string)
Logs[Identifier] = nil
end
return Logger :: typeof(Logger)

View file

@ -13,24 +13,18 @@ local Spawn = require(Util.Spawn)
local Key = require(Util.Key) local Key = require(Util.Key)
local RateLimit = require(Util.RateLimit) local RateLimit = require(Util.RateLimit)
local Buffer = require(Util.Buffer) local Buffer = require(Util.Buffer)
local Logger = require(script.Logger)
local serverQueue: Type.QueueMap = {} local serverQueue: Type.QueueMap = {}
local unreliableServerQueue: Type.QueueMap = {} local unreliableServerQueue: Type.QueueMap = {}
local serverCallback: Type.CallbackMap = {} local serverCallback: Type.CallbackMap = {}
local serverRequestQueue: Type.QueueMap = {} local serverRequestQueue: Type.QueueMap = {}
local registeredIdentifier: { string } = {} local registeredIdentifier: { [string]: boolean } = {}
local queueOut: { local queueOut: {
[Player]: { [Player]: {
[string]: {any}, [string]: {any},
} }
} = {} } = {}
local queueIn: {
[string]: {
[Player]: {any},
}
} = {}
local queueInRequest: { local queueInRequest: {
[number]: { [number]: {
[string]: { [string]: {
@ -45,12 +39,6 @@ local queueOutRequest: {
} }
} }
} = {} } = {}
local logger: {
[string]: boolean
} = {}
local players: {
Player
} = {}
queueInRequest[1] = {} queueInRequest[1] = {}
queueInRequest[2] = {} queueInRequest[2] = {}
@ -78,9 +66,6 @@ local function initializeEachPlayer(player: Player)
if not serverRequestQueue[Identifier][player] then if not serverRequestQueue[Identifier][player] then
serverRequestQueue[Identifier][player] = {} serverRequestQueue[Identifier][player] = {}
end end
if not queueIn[Identifier][player] then
queueIn[Identifier][player] = {}
end
if not queueOutRequest[1][Identifier] then if not queueOutRequest[1][Identifier] then
queueOutRequest[1][Identifier] = {} queueOutRequest[1][Identifier] = {}
end end
@ -140,14 +125,11 @@ function ServerProcess.insertRequest(Identifier: string, timeout: number, player
end end
function ServerProcess.add(Identifier: string, originId: string, conf: Type.ServerConf) function ServerProcess.add(Identifier: string, originId: string, conf: Type.ServerConf)
if not table.find(registeredIdentifier, Identifier) then if not registeredIdentifier[Identifier] then
table.insert(registeredIdentifier, Identifier) registeredIdentifier[Identifier] = true
RateLimit.create(originId, conf.rateLimit and conf.rateLimit.maxEntrance or 200, conf.rateLimit and conf.rateLimit.interval or 2) RateLimit.create(originId, conf.rateLimit and conf.rateLimit.maxEntrance or 200, conf.rateLimit and conf.rateLimit.interval or 2)
if conf.logging then
ServerProcess.logger(Identifier, conf.logging.store, conf.logging.opt)
end
if not serverQueue[Identifier] then if not serverQueue[Identifier] then
serverQueue[Identifier] = {} serverQueue[Identifier] = {}
end end
@ -161,9 +143,6 @@ function ServerProcess.add(Identifier: string, originId: string, conf: Type.Serv
unreliableServerQueue[Identifier] = {} unreliableServerQueue[Identifier] = {}
end end
if not queueIn[Identifier] then
queueIn[Identifier] = {}
end
if not queueInRequest[1][Identifier] then if not queueInRequest[1][Identifier] then
queueInRequest[1][Identifier] = {} queueInRequest[1][Identifier] = {}
end end
@ -184,41 +163,24 @@ function ServerProcess.add(Identifier: string, originId: string, conf: Type.Serv
end end
function ServerProcess.remove(Identifier: string) function ServerProcess.remove(Identifier: string)
if not table.find(registeredIdentifier, Identifier) then return end if not registeredIdentifier[Identifier] then return end
table.remove(registeredIdentifier, table.find(registeredIdentifier, Identifier)) registeredIdentifier[Identifier] = nil
serverQueue[Identifier] = nil serverQueue[Identifier] = nil
serverRequestQueue[Identifier] = nil serverRequestQueue[Identifier] = nil
serverCallback[Identifier] = nil serverCallback[Identifier] = nil
unreliableServerQueue[Identifier] = nil unreliableServerQueue[Identifier] = nil
queueIn[Identifier] = nil
queueInRequest[1][Identifier] = nil queueInRequest[1][Identifier] = nil
queueInRequest[2][Identifier] = nil queueInRequest[2][Identifier] = nil
queueOutRequest[1][Identifier] = nil queueOutRequest[1][Identifier] = nil
queueOutRequest[2][Identifier] = nil queueOutRequest[2][Identifier] = nil
Logger.clear(Identifier)
end
function ServerProcess.logger(Identifier: string, store: boolean, log: boolean)
logger[Identifier] = store
Logger.write(Identifier, `state: change -> {log == true and "enabled" or "disabled"} logger.`, log)
end
function ServerProcess.getlogs(Identifier: string)
return Logger.read(Identifier)
end end
function ServerProcess.addCallback(Identifier: string, key: string, callback) function ServerProcess.addCallback(Identifier: string, key: string, callback)
serverCallback[Identifier][key] = callback serverCallback[Identifier][key] = callback
if logger[Identifier] then
task.defer(Logger.write, Identifier, `state: change -> new callback added.`)
end
end end
function ServerProcess.removeCallback(Identifier: string, key: string) function ServerProcess.removeCallback(Identifier: string, key: string)
serverCallback[Identifier][key] = nil serverCallback[Identifier][key] = nil
if logger[Identifier] then
task.defer(Logger.write, Identifier, `state: change -> removed a callback.`)
end
end end
function ServerProcess.start() function ServerProcess.start()
@ -228,9 +190,8 @@ function ServerProcess.start()
for Identifier: string, players in unreliableServerQueue do for Identifier: string, players in unreliableServerQueue do
for player: Player, content: any in players do for player: Player, content: any in players do
if #content == 0 then continue end if #content == 0 then continue end
UnreliableEvent:FireClient(player, Buffer.revert(Identifier), content) for _, unpacked in content do
if logger[Identifier] then UnreliableEvent:FireClient(player, Buffer.write(unpacked))
task.defer(Logger.write, Identifier, `state: out -> unreliable -> {#content} data.`)
end end
unreliableServerQueue[Identifier][player] = nil unreliableServerQueue[Identifier][player] = nil
end end
@ -240,7 +201,9 @@ function ServerProcess.start()
for Identifier: string, contents: { [Player]: { any } } in serverQueue do for Identifier: string, contents: { [Player]: { any } } in serverQueue do
for player, content: any in contents do for player, content: any in contents do
if #content > 0 and queueOut[player] then if #content > 0 and queueOut[player] then
ReliableEvent:FireClient(player, Buffer.revert(Identifier), content) for _, unpacked in content do
ReliableEvent:FireClient(player, Buffer.write(unpacked))
end
end end
serverQueue[Identifier][player] = nil serverQueue[Identifier][player] = nil
end end
@ -251,9 +214,6 @@ function ServerProcess.start()
for player: Player, requestsData: any in contents do for player: Player, requestsData: any in contents do
if #requestsData > 0 then if #requestsData > 0 then
RequestEvent:FireClient(player, Buffer.revert(Identifier), "\1", requestsData) RequestEvent:FireClient(player, Buffer.revert(Identifier), "\1", requestsData)
if logger[Identifier] then
task.defer(Logger.write, Identifier, `state: out -> request -> {#requestsData} data.`)
end
end end
queueOutRequest[1][Identifier][player] = nil queueOutRequest[1][Identifier][player] = nil
end end
@ -264,16 +224,13 @@ function ServerProcess.start()
for player: Player, toReturnDatas: any in contents do for player: Player, toReturnDatas: any in contents do
if #toReturnDatas > 0 then if #toReturnDatas > 0 then
RequestEvent:FireClient(player, Buffer.revert(Identifier), "\0", toReturnDatas) RequestEvent:FireClient(player, Buffer.revert(Identifier), "\0", toReturnDatas)
if logger[Identifier] then
task.defer(Logger.write, Identifier, `state: out -> return request -> {#toReturnDatas} data.`)
end
end end
queueOutRequest[2][Identifier][player] = nil queueOutRequest[2][Identifier][player] = nil
end end
queueOutRequest[2][Identifier] = nil queueOutRequest[2][Identifier] = nil
end end
for _, Identifier: string in registeredIdentifier do for Identifier: string in registeredIdentifier do
if serverRequestQueue[Identifier] then if serverRequestQueue[Identifier] then
for player, content in serverRequestQueue[Identifier] do for player, content in serverRequestQueue[Identifier] do
if #content == 0 then serverRequestQueue[Identifier][player] = nil continue end if #content == 0 then serverRequestQueue[Identifier][player] = nil continue end
@ -294,21 +251,6 @@ function ServerProcess.start()
local callback = serverCallback[Identifier] or nil local callback = serverCallback[Identifier] or nil
if not callback then continue end if not callback then continue end
-- Unreliable & Reliable
for player, content in queueIn[Identifier] do
if not callback then break end
for _, incoming in content do
if not callback then break end
if #incoming == 0 then continue end
for _, fn: any in callback do
for i=1,#incoming do
Spawn(fn, player, table.unpack(incoming[i] or {}))
end
end
end
queueIn[Identifier][player] = nil
end
-- Return Invoke -- Return Invoke
for player, content in queueInRequest[1][Identifier] do for player, content in queueInRequest[1][Identifier] do
if not callback then break end if not callback then break end
@ -361,22 +303,17 @@ function ServerProcess.start()
end end
end end
end) end)
local function onServerNetworkReceive(player: Player, Identifier: any, data: any) local function onServerNetworkReceive(player: Player, data: buffer)
if not Identifier or not data then return end if not data then return end
Identifier = Buffer.convert(Identifier) local read = Buffer.read(data)
if not serverQueue[Identifier] then if not read then return end
serverQueue[Identifier] = {} for Identifier: string in registeredIdentifier do
local callback = serverCallback[Identifier] or nil
if not callback then continue end
for _, fn: any in callback do
Spawn(fn, player, table.unpack(read))
end
end end
if not serverQueue[Identifier][player] then
serverQueue[Identifier][player] = {}
end
if not queueIn[Identifier][player] then
queueIn[Identifier][player] = {}
end
if logger[Identifier] then
task.defer(Logger.write, Identifier, `state: in -> net -> {#data} data.`)
end
table.insert(queueIn[Identifier][player], data)
end end
ReliableEvent.OnServerEvent:Connect(onServerNetworkReceive) ReliableEvent.OnServerEvent:Connect(onServerNetworkReceive)
UnreliableEvent.OnServerEvent:Connect(onServerNetworkReceive) UnreliableEvent.OnServerEvent:Connect(onServerNetworkReceive)
@ -400,9 +337,6 @@ function ServerProcess.start()
else else
table.insert(queueInRequest[2][Identifier][player], data) table.insert(queueInRequest[2][Identifier][player], data)
end end
if logger[Identifier] then
task.defer(Logger.write, Identifier, `state: in -> request -> {#data} data.`)
end
end) end)
end end

View file

@ -3,7 +3,6 @@
--!optimize 2 --!optimize 2
local Signal = {} local Signal = {}
Signal.__index = Signal Signal.__index = Signal
Signal.ClassName = "Signal"
local DedicatedSignal = require(script.Dedicated) local DedicatedSignal = require(script.Dedicated)

View file

@ -4,19 +4,12 @@ type rateLimitArg = {
interval: number?, interval: number?,
} }
type logging = {
store: boolean,
opt: boolean,
}
export type ServerConf = { export type ServerConf = {
rateLimit: rateLimitArg?, rateLimit: rateLimitArg?,
logging: logging?,
} }
export type ClientConf = { export type ClientConf = {
yieldWait: number?, yieldWait: number?,
logging: logging?,
} }
export type Middleware = { export type Middleware = {
@ -34,7 +27,6 @@ export type Client = {
DisconnectAll: (self: Client) -> (), DisconnectAll: (self: Client) -> (),
Wait: (self: Client) -> number, Wait: (self: Client) -> number,
Destroy: (self: Client) -> (), Destroy: (self: Client) -> (),
logs: (self: Client) -> any,
} }
export type Server = { export type Server = {
@ -47,7 +39,6 @@ export type Server = {
DisconnectAll: (self: Server) -> (), DisconnectAll: (self: Server) -> (),
Wait: (self: Server) -> number, Wait: (self: Server) -> number,
Destroy: (self: Server) -> (), Destroy: (self: Server) -> (),
logs: (self: Server) -> any,
} }
export type Signal = { export type Signal = {

View file

@ -16,11 +16,11 @@ local writef32 = buffer.writef32
local writef64 = buffer.writef64 local writef64 = buffer.writef64
local writestring = buffer.writestring local writestring = buffer.writestring
local default = { local default: { [string]: number } = {
point = 0, point = 0,
next = 0, next = 0,
size = 128, size = 32,
bufferSize = 128, bufferSize = 32,
} }
function DedicatedBuffer.copy(self: any, offset: number, b: buffer?, src: buffer?, srcOffset: number?, count: number?) function DedicatedBuffer.copy(self: any, offset: number, b: buffer?, src: buffer?, srcOffset: number?, count: number?)
@ -35,17 +35,16 @@ function DedicatedBuffer.alloc(self: any, byte: number)
local size: number = self.size local size: number = self.size
local b: buffer = self.buffer local b: buffer = self.buffer
while self.next + byte >= size do
while self.point + byte >= size do size = math.floor(size * 1.2)
size = math.floor(size * 1.5)
end end
local newBuffer: buffer = create(size) local newBuffer: buffer = create(size)
copy(newBuffer, 0, b) copy(newBuffer, 0, b)
b = newBuffer b = newBuffer
self.point = self.next self.point = self.next
self.buffer = b
self.next += byte self.next += byte
end end
@ -57,6 +56,15 @@ function DedicatedBuffer.build(self: any): buffer
return build return build
end end
function DedicatedBuffer.buildAndRemove(self: any): buffer
local p: number = self.next > self.point and self.next or self.point
local build: buffer = create(p)
copy(build, 0, self.buffer, 0, p)
self:remove()
return build
end
function DedicatedBuffer.wi8(self: any, val: number) function DedicatedBuffer.wi8(self: any, val: number)
if not val then return end if not val then return end
self:alloc(1) self:alloc(1)
@ -111,6 +119,85 @@ function DedicatedBuffer.wstring(self: any, val: string)
writestring(self.buffer, self.point, val) writestring(self.buffer, self.point, val)
end end
function DedicatedBuffer.wType(self: any, typeByte: number)
self:alloc(1)
writeu8(self.buffer, self.point, typeByte)
self.point += 1
end
function DedicatedBuffer.pack(self: any, data: {any})
if typeof(data) == "number" then
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
self:wi8(6) -- string marker
local length = #data
if length < 255 then
--self:wi8(7) -- small string marker
self:wu8(length) -- use 1 byte for length if small
else
--self:wi8(8) -- large string marker
self:wi32(length) -- 32-bit for larger strings
end
self:wstring(data)
elseif typeof(data) == "Vector3" then
self:wi8(7) -- Vector3 marker
self:wf32(data.X)
self:wf32(data.Y)
self:wf32(data.Z)
elseif typeof(data) == "CFrame" then
self:wi8(8) -- CFrame marker
for _, v in {data:GetComponents()} do
self:wf32(v)
end
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(9) -- array marker
self:wi32(count) -- use 32-bit length
for _, v in data do
self:pack(v)
end
else
self:wi8(10) -- dictionary marker
self:wi32(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
else
error("Unsupported data type: " .. typeof(data))
end
end
function DedicatedBuffer.flush(self: any) function DedicatedBuffer.flush(self: any)
self.point = default.point self.point = default.point
self.next = default.next self.next = default.next
@ -128,8 +215,11 @@ function DedicatedBuffer.new()
end end
function DedicatedBuffer.remove(self: any) function DedicatedBuffer.remove(self: any)
self:flush()
table.clear(self) table.clear(self)
setmetatable(self, nil) setmetatable(self, nil)
end end
export type DedicatedType = typeof(DedicatedBuffer.new())
return DedicatedBuffer.new :: typeof(DedicatedBuffer.new) return DedicatedBuffer.new :: typeof(DedicatedBuffer.new)

View file

@ -8,8 +8,84 @@ local Dedicated = require(script.Dedicated)
local tostring = buffer.tostring local tostring = buffer.tostring
local fromstring = buffer.fromstring local fromstring = buffer.fromstring
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
function Buffer.new() local function readValue(b: buffer, position: number): (any, number)
local typeByte = readu8(b, position)
position += 1
if typeByte == 1 then -- u8
local value = readu8(b, position)
return value, position + 1
elseif typeByte == 2 then -- i16
local value = readi16(b, position)
return value, position + 2
elseif typeByte == 3 then -- i32
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
elseif typeByte == 6 then -- string
local lengthByte = readu8(b, position)
position += 1
local value
if lengthByte < 255 then
value = readstring(b, position, lengthByte)
return value, position + lengthByte
else
local length = readi32(b, position)
position += 4
value = readstring(b, position, length)
return value, position + length
end
elseif typeByte == 7 then -- Vector3
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
elseif typeByte == 8 then -- CFrame
local components = {}
for i = 1, 12 do
table.insert(components, readf32(b, position + (i - 1) * 4))
end
return CFrame.new(unpack(components)), position + 48
elseif typeByte == 9 then -- array
local length = readi32(b, position)
position += 4
local array = {}
for _ = 1, length do
local value
value, position = readValue(b, position)
table.insert(array, value)
end
return array, position
elseif typeByte == 10 then -- dictionary
local length = readi32(b, position)
position += 4
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
end
error(`Unsupported type marker: {typeByte}`)
end
function Buffer.new(): Dedicated.DedicatedType
return Dedicated() return Dedicated()
end end
@ -21,4 +97,21 @@ function Buffer.revert(s: string): buffer
return fromstring(s) return fromstring(s)
end end
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
return Buffer :: typeof(Buffer) return Buffer :: typeof(Buffer)

View file

@ -1,5 +1,5 @@
--!strict --!strict
--!optimize 2 --!optimize 2
return function(): number? return function(): number?
return tonumber(tostring(Random.new():NextNumber()):sub(3, 7)) -- 4-5 digits return tonumber(string.sub(tostring(Random.new():NextNumber()), 3, 8)) -- 6 digits
end end

View file

@ -15,7 +15,7 @@ function RateLimit.create(Identifier: string, entrance: number?, interval: numbe
Event:SetAttribute(Identifier.."_int", interval) Event:SetAttribute(Identifier.."_int", interval)
else else
while (not Event:GetAttribute(Identifier.."_ent")) or (not Event:GetAttribute(Identifier.."_int")) do while (not Event:GetAttribute(Identifier.."_ent")) or (not Event:GetAttribute(Identifier.."_int")) do
task.wait(0.5) task.wait(0.25)
end end
entrance = tonumber(Event:GetAttribute(Identifier.."_ent")) entrance = tonumber(Event:GetAttribute(Identifier.."_ent"))
interval = tonumber(Event:GetAttribute(Identifier.."_int")) interval = tonumber(Event:GetAttribute(Identifier.."_int"))

View file

@ -24,7 +24,7 @@ function SerDes.increment(Identifier: string, timeout: number?): number
error(`Serdes: {Identifier} is taking too long to retrieve, seems like it's not replicated on server.`, 2) error(`Serdes: {Identifier} is taking too long to retrieve, seems like it's not replicated on server.`, 2)
end) end)
task.spawn(function() task.spawn(function()
while coroutine.status(cancel) ~= "dead" and task.wait(0.5) do -- let it loop for yields! while coroutine.status(cancel) ~= "dead" and task.wait(0.25) do -- let it loop for yields!
if Event:GetAttribute(Identifier) then if Event:GetAttribute(Identifier) then
task.cancel(cancel) task.cancel(cancel)
task.spawn(yieldThread, Event:GetAttribute(Identifier)) task.spawn(yieldThread, Event:GetAttribute(Identifier))

View file

@ -2,43 +2,20 @@
--!strict --!strict
--!optimize 2 --!optimize 2
local thread: thread? local thread: thread?
local threads: {
thread
} = {}
local function passer<T...>(func: (T...) -> (), ...: T...): () local function passer<T...>(func: (T...) -> (), ...: T...): ()
local HoldThread: thread = thread :: thread local HoldThread: thread = thread :: thread
thread = nil thread = nil
func(...) func(...)
if not thread then thread = HoldThread
thread = HoldThread
return
end
table.insert(threads, HoldThread)
end end
local function yield(): never local function newThread(): ()
while true do thread = coroutine.running()
passer(coroutine.yield()) while true do passer(coroutine.yield()) end
end
end
local function createThread(): ()
local newThread: thread = coroutine.create(yield)
coroutine.resume(newThread, newThread)
table.insert(threads, newThread)
end
for _=1,5 do
createThread()
end end
return function<T...>(func: (T...) -> (), ...: T...): () return function<T...>(func: (T...) -> (), ...: T...): ()
if not thread then if not thread then task.spawn(newThread) end
if #threads == 0 then
createThread()
end
thread = table.remove(threads, 1)
end
task.spawn(thread :: thread, func, ...) task.spawn(thread :: thread, func, ...)
end end

View file

@ -1,6 +1,6 @@
[package] [package]
name = "imezx/warp" name = "imezx/warp"
version = "1.0.12" version = "1.0.13"
registry = "https://github.com/UpliftGames/wally-index" registry = "https://github.com/UpliftGames/wally-index"
realm = "shared" realm = "shared"
license = "MIT" license = "MIT"