improved ServerProcess

This commit is contained in:
EternityDev 2024-05-10 16:15:39 +07:00
parent b4ee5dc1e3
commit 6acf92d913

View file

@ -19,6 +19,7 @@ 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 queueOut: { local queueOut: {
[Player]: { [Player]: {
@ -61,12 +62,12 @@ local UnreliableEvent = Event.Unreliable
local RequestEvent = Event.Request local RequestEvent = Event.Request
local function initializeEachPlayer(player: Player) local function initializeEachPlayer(player: Player)
players = Players:GetPlayers()
if not player then return end if not player then return end
if not queueOut[player] then if not queueOut[player] then
queueOut[player] = {} queueOut[player] = {}
end end
for Identifier: string in serverQueue do
for _, Identifier: string in registeredIdentifier do
if not player then break end if not player then break end
if not queueOut[player][Identifier] then if not queueOut[player][Identifier] then
queueOut[player][Identifier] = {} queueOut[player][Identifier] = {}
@ -89,9 +90,6 @@ local function initializeEachPlayer(player: Player)
end end
Players.PlayerAdded:Connect(initializeEachPlayer) Players.PlayerAdded:Connect(initializeEachPlayer)
Players.PlayerRemoving:Connect(function()
players = Players:GetPlayers()
end)
function ServerProcess.insertQueue(Identifier: string, reliable: boolean, player: Player, ...: any) function ServerProcess.insertQueue(Identifier: string, reliable: boolean, player: Player, ...: any)
if not reliable then if not reliable then
@ -124,7 +122,8 @@ 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 serverQueue[Identifier] then if not table.find(registeredIdentifier, Identifier) then
table.insert(registeredIdentifier, Identifier)
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 if conf.logging then
ServerProcess.logger(Identifier, conf.logging.store, conf.logging.opt) ServerProcess.logger(Identifier, conf.logging.store, conf.logging.opt)
@ -132,14 +131,14 @@ function ServerProcess.add(Identifier: string, originId: string, conf: Type.Serv
if not serverQueue[Identifier] then if not serverQueue[Identifier] then
serverQueue[Identifier] = {} serverQueue[Identifier] = {}
end end
if not unreliableServerQueue[Identifier] then if not serverRequestQueue[Identifier] then
unreliableServerQueue[Identifier] = {} serverRequestQueue[Identifier] = {}
end end
if not serverCallback[Identifier] then if not serverCallback[Identifier] then
serverCallback[Identifier] = {} serverCallback[Identifier] = {}
end end
if not serverRequestQueue[Identifier] then if not unreliableServerQueue[Identifier] then
serverRequestQueue[Identifier] = {} unreliableServerQueue[Identifier] = {}
end end
if not queueIn[Identifier] then if not queueIn[Identifier] then
@ -191,93 +190,98 @@ function ServerProcess.start()
debug.setmemorycategory("Warp") debug.setmemorycategory("Warp")
RunService.PostSimulation:Connect(function() RunService.PostSimulation:Connect(function()
for Identifier: string, players in unreliableServerQueue do for Identifier: string, players in unreliableServerQueue do
for player: Player, data: any in players do for player: Player, content: any in players do
if #data == 0 then continue end if #content == 0 then continue end
UnreliableEvent:FireClient(player, Buffer.revert(Identifier), data) UnreliableEvent:FireClient(player, Buffer.revert(Identifier), content)
if logger[Identifier] then if logger[Identifier] then
task.defer(Logger.write, Identifier, `state: out -> unreliable -> {#data} data.`) task.defer(Logger.write, Identifier, `state: out -> unreliable -> {#content} data.`)
end end
table.clear(data) unreliableServerQueue[Identifier][player] = nil
end end
end end
for _, player: Player in ipairs(players) do
if not player or not queueOut[player] then continue end for Identifier: string, contents: { [Player]: { any } } in serverQueue do
for Identifier: string, data: any in queueOut[player] do
if #data == 0 then continue end
ReliableEvent:FireClient(player, Buffer.revert(Identifier), data)
if logger[Identifier] then
task.defer(Logger.write, Identifier, `state: out -> reliable -> {#data} data.`)
end
table.clear(data)
end
end
for Identifier: string, players in serverQueue do
local callback = serverCallback[Identifier] or nil local callback = serverCallback[Identifier] or nil
for player: Player, data in players do for player, content: any in contents do
if #data > 0 and queueOut[player] then if #content > 0 and queueOut[player] then
queueOut[player][Identifier] = table.clone(data) ReliableEvent:FireClient(player, Buffer.revert(Identifier), content)
table.clear(data) serverQueue[Identifier][player] = nil
end end
if #serverRequestQueue[Identifier][player] > 0 then if #serverRequestQueue[Identifier][player] > 0 then
for _, requestData in serverRequestQueue[Identifier][player] do for _, requestData in serverRequestQueue[Identifier][player] do
if not requestData[3] then continue end if not requestData[3] then continue end
if not queueOutRequest[1][Identifier][player] then
queueOutRequest[1][Identifier][player] = {}
end
table.insert(queueOutRequest[1][Identifier][player], { requestData[1], requestData[3] }) table.insert(queueOutRequest[1][Identifier][player], { requestData[1], requestData[3] })
table.remove(requestData, #requestData) serverRequestQueue[Identifier][player] = nil
end end
end end
if callback then
if #queueIn[Identifier][player] > 0 then
for _, packedDatas: any in queueIn[Identifier][player] do
if #packedDatas == 0 then continue end
for _, fn: any in callback do
for i=1,math.min(1e3, #packedDatas) do
Spawn(fn, player, table.unpack(packedDatas[i] or {}))
end
end
end
table.clear(queueIn[Identifier][player])
end
if #queueInRequest[1][Identifier][player] > 0 then
for idx, packetDatas: any in queueInRequest[1][Identifier][player] do
if #packetDatas == 0 then continue end
for _, fn: any in callback do
for i=1,math.min(1e3, #packetDatas) do
local packetData = packetDatas[i]
if not packetData then continue end
Spawn(function()
local requestReturn = { fn(player, table.unpack(packetData[2])) }
table.insert(queueOutRequest[2][Identifier][player], { packetData[1], requestReturn })
end)
end
end
end
table.clear(queueInRequest[1][Identifier][player])
end
if #queueInRequest[2][Identifier][player] > 0 then
for _, packetDatas: any in queueInRequest[2][Identifier][player] do
for idx, packetData in packetDatas do
if #packetData == 1 then continue end
for y=1, math.min(1e3, #serverRequestQueue[Identifier][player]) do
local serverRequest = serverRequestQueue[Identifier][player][y]
if not serverRequest then continue end
if serverRequest[1] == packetData[1] then
Spawn(serverRequest[2], table.unpack(packetData[2]))
table.remove(packetDatas, idx)
table.remove(serverRequestQueue[Identifier][player], y)
break
end
end
end
end
table.clear(queueInRequest[2][Identifier][player])
end
for player: Player, requestsData: any in queueOutRequest[1][Identifier] do for player: Player, requestsData: any in queueOutRequest[1][Identifier] do
if #requestsData == 0 then continue end if #requestsData == 0 then continue end
RequestEvent:FireClient(player, Buffer.revert(Identifier), "\1", requestsData) RequestEvent:FireClient(player, Buffer.revert(Identifier), "\1", requestsData)
if logger[Identifier] then if logger[Identifier] then
task.defer(Logger.write, Identifier, `state: out -> request -> {#requestsData} data.`) task.defer(Logger.write, Identifier, `state: out -> request -> {#requestsData} data.`)
end end
table.clear(requestsData) queueOutRequest[1][Identifier][player] = nil
end
if callback then
local requestIn1: any = queueInRequest[1][Identifier][player]
local requestIn2: any = queueInRequest[2][Identifier][player]
local incoming: any = queueIn[Identifier][player]
if incoming then
for _, packedDatas: any in incoming do
if #packedDatas == 0 then continue end
for _, fn: any in callback do
for i=1,#packedDatas do
Spawn(fn, player, table.unpack(packedDatas[i] or {}))
end
end
end
incoming = nil
queueIn[Identifier][player] = nil
end
if requestIn1 then
for _, packetDatas: any in requestIn1 do
if #packetDatas == 0 then continue end
for _, fn: any in callback do
for i=1,#packetDatas do
local packetData = packetDatas[i]
if not packetData then continue end
Spawn(function()
local requestReturn = { fn(player, table.unpack(packetData[2])) }
local state = queueOutRequest[2][Identifier][player]
if not queueOutRequest[2][Identifier][player] then
queueOutRequest[2][Identifier][player] = {}
end
table.insert(queueOutRequest[2][Identifier][player], { packetData[1], requestReturn })
end)
end
end
end
requestIn1 = nil
queueInRequest[1][Identifier][player] = nil
end
if requestIn2 then
for _, packetDatas: any in requestIn2 do
for _, packetData in packetDatas do
if #packetData == 1 then continue end
local data = serverRequestQueue[Identifier][player]
for i=1,#data do
local serverRequest = data[i]
if not serverRequest then continue end
if serverRequest[1] == packetData[1] then
Spawn(serverRequest[2], table.unpack(packetData[2]))
table.remove(data, i)
break
end
end
end
end
requestIn2 = nil
queueInRequest[2][Identifier][player] = nil
end
end end
for player: Player, toReturnDatas: any in queueOutRequest[2][Identifier] do for player: Player, toReturnDatas: any in queueOutRequest[2][Identifier] do
if #toReturnDatas == 0 then continue end if #toReturnDatas == 0 then continue end
@ -285,8 +289,7 @@ function ServerProcess.start()
if logger[Identifier] then if logger[Identifier] then
task.defer(Logger.write, Identifier, `state: out -> return request -> {#toReturnDatas} data.`) task.defer(Logger.write, Identifier, `state: out -> return request -> {#toReturnDatas} data.`)
end end
table.clear(toReturnDatas) queueOutRequest[2][Identifier][player] = nil
end
end end
end end
end end