mirror of
https://github.com/imezx/Warp.git
synced 2026-06-02 12:18:32 +00:00
chore(server): disable player buffer history in studio environment
Some checks failed
Deploy / Build & Deploy (push) Has been cancelled
Some checks failed
Deploy / Build & Deploy (push) Has been cancelled
This commit is contained in:
parent
704942c979
commit
80646eeebb
2 changed files with 399 additions and 397 deletions
|
|
@ -13,12 +13,12 @@ local deltaT: number, cycle: number = 0, 1 / 61
|
|||
local writer: Buffer.Writer = Buffer.createWriter()
|
||||
|
||||
type Connection = {
|
||||
Connected: boolean,
|
||||
Disconnect: (self: Connection) -> (),
|
||||
Connected: boolean,
|
||||
Disconnect: (self: Connection) -> (),
|
||||
}
|
||||
type Event = {
|
||||
i: number,
|
||||
c: (Player, ...any?) -> ...any?,
|
||||
i: number,
|
||||
c: (Player, ...any?) -> ...any?,
|
||||
}
|
||||
|
||||
local queueEvent: { { any } } = {}
|
||||
|
|
@ -37,79 +37,79 @@ Client.awaitReady = Replication.wait_for_ready
|
|||
--@schema Buffer.SchemaType
|
||||
-- Define a schema for strict data packing on a specific event.
|
||||
Client.useSchema = function(remoteName: string, schema: Buffer.SchemaType)
|
||||
local id = Replication.get_id(remoteName)
|
||||
if not id then
|
||||
warn(`[Warp]: ".useSchema"::"{remoteName}" does not exist, likely its not registered on the server yet.`)
|
||||
return
|
||||
end
|
||||
eventSchemas[id] = schema
|
||||
local id = Replication.get_id[remoteName]
|
||||
if not id then
|
||||
warn(`[Warp]: ".useSchema"::"{remoteName}" does not exist, likely its not registered on the server yet.`)
|
||||
return
|
||||
end
|
||||
eventSchemas[id] = schema
|
||||
end
|
||||
|
||||
--@remoteName string
|
||||
--@fn function
|
||||
-- Connect to an event to receive incoming data from the server.
|
||||
Client.Connect = function(remoteName: string, fn: (Player, ...any?) -> ...any?): Connection
|
||||
local id = Replication.get_id(remoteName)
|
||||
if not id then
|
||||
warn(`[Warp]: ".Connect"::"{remoteName}" does not exist, likely its not registered on the server yet.`)
|
||||
return { Connected = false, Disconnect = function() return end } :: Connection
|
||||
end
|
||||
local detail = {
|
||||
i = id,
|
||||
c = fn,
|
||||
}
|
||||
table.insert(eventListeners, detail)
|
||||
return {
|
||||
Connected = true,
|
||||
Disconnect = function(self: Connection)
|
||||
if not self.Connected then
|
||||
return
|
||||
end
|
||||
self.Connected = false
|
||||
local idx = table.find(eventListeners, detail)
|
||||
if idx then
|
||||
table.remove(eventListeners, idx)
|
||||
end
|
||||
end,
|
||||
} :: Connection
|
||||
local id = Replication.get_id[remoteName]
|
||||
if not id then
|
||||
warn(`[Warp]: ".Connect"::"{remoteName}" does not exist, likely its not registered on the server yet.`)
|
||||
return { Connected = false, Disconnect = function() return end } :: Connection
|
||||
end
|
||||
local detail = {
|
||||
i = id,
|
||||
c = fn,
|
||||
}
|
||||
table.insert(eventListeners, detail)
|
||||
return {
|
||||
Connected = true,
|
||||
Disconnect = function(self: Connection)
|
||||
if not self.Connected then
|
||||
return
|
||||
end
|
||||
self.Connected = false
|
||||
local idx = table.find(eventListeners, detail)
|
||||
if idx then
|
||||
table.remove(eventListeners, idx)
|
||||
end
|
||||
end,
|
||||
} :: Connection
|
||||
end
|
||||
|
||||
--@remoteName string
|
||||
--@fn function
|
||||
-- Similar to :Connect but automatically disconnects after the first firing.
|
||||
Client.Once = function(remoteName: string, fn: (...any?) -> ()): Connection
|
||||
local connection
|
||||
connection = Client.Connect(remoteName, function(...: any?)
|
||||
if connection then
|
||||
connection:Disconnect()
|
||||
end
|
||||
fn(...)
|
||||
end)
|
||||
return connection
|
||||
local connection
|
||||
connection = Client.Connect(remoteName, function(...: any?)
|
||||
if connection then
|
||||
connection:Disconnect()
|
||||
end
|
||||
fn(...)
|
||||
end)
|
||||
return connection
|
||||
end
|
||||
|
||||
--@remoteName string
|
||||
-- Wait for an event to be triggered. Yields the current thread.
|
||||
Client.Wait = function(remoteName: string): (number, ...any?)
|
||||
local thread, t = coroutine.running(), os.clock()
|
||||
Client.Once(remoteName, function(...: any?)
|
||||
task.spawn(thread, os.clock() - t, ...)
|
||||
end)
|
||||
return coroutine.yield()
|
||||
local thread, t = coroutine.running(), os.clock()
|
||||
Client.Once(remoteName, function(...: any?)
|
||||
task.spawn(thread, os.clock() - t, ...)
|
||||
end)
|
||||
return coroutine.yield()
|
||||
end
|
||||
|
||||
--@remoteName string
|
||||
-- Disconnect all connections for a specific event.
|
||||
Client.DisconnectAll = function(remoteName: string)
|
||||
local id = Replication.get_id(remoteName)
|
||||
if not id then
|
||||
return
|
||||
end
|
||||
for idx = #eventListeners, 1, -1 do
|
||||
if eventListeners[idx].i == id then
|
||||
table.remove(eventListeners, idx)
|
||||
end
|
||||
end
|
||||
local id = Replication.get_id[remoteName]
|
||||
if not id then
|
||||
return
|
||||
end
|
||||
for idx = #eventListeners, 1, -1 do
|
||||
if eventListeners[idx].i == id then
|
||||
table.remove(eventListeners, idx)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--@remoteName string
|
||||
|
|
@ -120,140 +120,140 @@ Client.Destroy = Client.DisconnectAll
|
|||
--@reliable boolean
|
||||
-- Fire an event to the server.
|
||||
Client.Fire = function(remoteName: string, reliable: boolean, ...: any?)
|
||||
local id = Replication.get_id(remoteName)
|
||||
if id then
|
||||
table.insert(reliable and queueEvent or queueUnreliableEvent, {
|
||||
Replication.get_id(remoteName),
|
||||
{ ... } :: any,
|
||||
})
|
||||
end
|
||||
local id = Replication.get_id[remoteName]
|
||||
if id then
|
||||
table.insert(reliable and queueEvent or queueUnreliableEvent, {
|
||||
Replication.get_id[remoteName],
|
||||
{ ... } :: any,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
--@remoteName string
|
||||
--@timeout number?
|
||||
-- Invoke the server with timeout support. Yields the current thread. Returns nil if timeout occurs.
|
||||
Client.Invoke = function(remoteName: string, timeout: number?, ...: any?): ...any?
|
||||
local id = Replication.get_id(remoteName)
|
||||
if not id then
|
||||
return nil
|
||||
end
|
||||
invokeId += 1
|
||||
local reqid, thread = `{invokeId}`, coroutine.running()
|
||||
local id = Replication.get_id[remoteName]
|
||||
if not id then
|
||||
return nil
|
||||
end
|
||||
invokeId += 1
|
||||
local reqid, thread = `{invokeId}`, coroutine.running()
|
||||
|
||||
pendingInvokes[reqid] = thread
|
||||
task.delay(timeout or 2, function()
|
||||
local pending = pendingInvokes[reqid]
|
||||
if not pending then
|
||||
return
|
||||
end
|
||||
task.spawn(pending, nil)
|
||||
pendingInvokes[reqid] = nil
|
||||
end)
|
||||
table.insert(queueEvent, {
|
||||
0,
|
||||
{ id, reqid :: any, { ... } :: any } :: any,
|
||||
})
|
||||
return coroutine.yield()
|
||||
pendingInvokes[reqid] = thread
|
||||
task.delay(timeout or 2, function()
|
||||
local pending = pendingInvokes[reqid]
|
||||
if not pending then
|
||||
return
|
||||
end
|
||||
task.spawn(pending, nil)
|
||||
pendingInvokes[reqid] = nil
|
||||
end)
|
||||
table.insert(queueEvent, {
|
||||
0,
|
||||
{ id, reqid :: any, { ... } :: any } :: any,
|
||||
})
|
||||
return coroutine.yield()
|
||||
end
|
||||
|
||||
if RunService:IsClient() then
|
||||
local function processIncoming(b: buffer, ref: { Instance }?, handleInvokes: boolean)
|
||||
if type(b) ~= "buffer" then
|
||||
return
|
||||
end
|
||||
local contents = Buffer.readEvents(b, ref, eventSchemas)
|
||||
for _, content in contents do
|
||||
local remote = content[1]
|
||||
local content = content[2]
|
||||
if handleInvokes then
|
||||
if remote == 0 then
|
||||
local id = content[1]
|
||||
local results = content[2]
|
||||
local pending = pendingInvokes[id]
|
||||
if pending then
|
||||
task.spawn(pending :: any, table.unpack(results))
|
||||
pendingInvokes[id] = nil
|
||||
end
|
||||
continue
|
||||
end
|
||||
if remote == 1 then
|
||||
if #eventListeners == 0 then
|
||||
continue
|
||||
end
|
||||
local remoteName = content[1]
|
||||
local id = content[2]
|
||||
local args = content[3]
|
||||
for _, connection in eventListeners do
|
||||
if connection.i == remoteName then
|
||||
Thread(function()
|
||||
local results = { connection.c(table.unpack(args)) }
|
||||
table.insert(queueEvent, {
|
||||
1,
|
||||
{ id, results } :: any,
|
||||
})
|
||||
end)
|
||||
break
|
||||
end
|
||||
end
|
||||
continue
|
||||
end
|
||||
end
|
||||
if #eventListeners == 0 then
|
||||
continue
|
||||
end
|
||||
for _, connection in eventListeners do
|
||||
if connection.i ~= remote then
|
||||
continue
|
||||
end
|
||||
Thread(connection.c, table.unpack(content))
|
||||
end
|
||||
end
|
||||
end
|
||||
local function processIncoming(b: buffer, ref: { Instance }?, handleInvokes: boolean)
|
||||
if type(b) ~= "buffer" then
|
||||
return
|
||||
end
|
||||
local contents = Buffer.readEvents(b, ref, eventSchemas)
|
||||
for _, content in contents do
|
||||
local remote = content[1]
|
||||
local content = content[2]
|
||||
if handleInvokes then
|
||||
if remote == 0 then
|
||||
local id = content[1]
|
||||
local results = content[2]
|
||||
local pending = pendingInvokes[id]
|
||||
if pending then
|
||||
task.spawn(pending :: any, table.unpack(results))
|
||||
pendingInvokes[id] = nil
|
||||
end
|
||||
continue
|
||||
end
|
||||
if remote == 1 then
|
||||
if #eventListeners == 0 then
|
||||
continue
|
||||
end
|
||||
local remoteName = content[1]
|
||||
local id = content[2]
|
||||
local args = content[3]
|
||||
for _, connection in eventListeners do
|
||||
if connection.i == remoteName then
|
||||
Thread(function()
|
||||
local results = { connection.c(table.unpack(args)) }
|
||||
table.insert(queueEvent, {
|
||||
1,
|
||||
{ id, results } :: any,
|
||||
})
|
||||
end)
|
||||
break
|
||||
end
|
||||
end
|
||||
continue
|
||||
end
|
||||
end
|
||||
if #eventListeners == 0 then
|
||||
continue
|
||||
end
|
||||
for _, connection in eventListeners do
|
||||
if connection.i ~= remote then
|
||||
continue
|
||||
end
|
||||
Thread(connection.c, table.unpack(content))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Event.OnClientEvent:Connect(function(b: buffer, ref: { Instance }?)
|
||||
processIncoming(b, ref, true)
|
||||
end)
|
||||
Event.OnClientEvent:Connect(function(b: buffer, ref: { Instance }?)
|
||||
processIncoming(b, ref, true)
|
||||
end)
|
||||
|
||||
UnreliableEvent.OnClientEvent:Connect(function(b: buffer, ref: { Instance }?)
|
||||
processIncoming(b, ref, false)
|
||||
end)
|
||||
UnreliableEvent.OnClientEvent:Connect(function(b: buffer, ref: { Instance }?)
|
||||
processIncoming(b, ref, false)
|
||||
end)
|
||||
|
||||
RunService.PostSimulation:Connect(function(d: number)
|
||||
deltaT += d
|
||||
if deltaT < cycle then
|
||||
return
|
||||
end
|
||||
deltaT = 0
|
||||
RunService.PostSimulation:Connect(function(d: number)
|
||||
deltaT += d
|
||||
if deltaT < cycle then
|
||||
return
|
||||
end
|
||||
deltaT = 0
|
||||
|
||||
-- reliable
|
||||
if #queueEvent > 0 then
|
||||
Buffer.writeEvents(writer, queueEvent, eventSchemas)
|
||||
do
|
||||
local buf, ref = Buffer.buildWithRefs(writer)
|
||||
Buffer.reset(writer)
|
||||
if not ref or #ref == 0 then
|
||||
Event:FireServer(buf)
|
||||
else
|
||||
Event:FireServer(buf, ref)
|
||||
end
|
||||
end
|
||||
table.clear(queueEvent)
|
||||
end
|
||||
-- unreliable
|
||||
if #queueUnreliableEvent > 0 then
|
||||
Buffer.writeEvents(writer, queueUnreliableEvent, eventSchemas)
|
||||
do
|
||||
local buf, ref = Buffer.buildWithRefs(writer)
|
||||
Buffer.reset(writer)
|
||||
if not ref or #ref == 0 then
|
||||
UnreliableEvent:FireServer(buf)
|
||||
else
|
||||
UnreliableEvent:FireServer(buf, ref)
|
||||
end
|
||||
end
|
||||
table.clear(queueUnreliableEvent)
|
||||
end
|
||||
end)
|
||||
-- reliable
|
||||
if #queueEvent > 0 then
|
||||
Buffer.writeEvents(writer, queueEvent, eventSchemas)
|
||||
do
|
||||
local buf, ref = Buffer.buildWithRefs(writer)
|
||||
Buffer.reset(writer)
|
||||
if not ref or #ref == 0 then
|
||||
Event:FireServer(buf)
|
||||
else
|
||||
Event:FireServer(buf, ref)
|
||||
end
|
||||
end
|
||||
table.clear(queueEvent)
|
||||
end
|
||||
-- unreliable
|
||||
if #queueUnreliableEvent > 0 then
|
||||
Buffer.writeEvents(writer, queueUnreliableEvent, eventSchemas)
|
||||
do
|
||||
local buf, ref = Buffer.buildWithRefs(writer)
|
||||
Buffer.reset(writer)
|
||||
if not ref or #ref == 0 then
|
||||
UnreliableEvent:FireServer(buf)
|
||||
else
|
||||
UnreliableEvent:FireServer(buf, ref)
|
||||
end
|
||||
end
|
||||
table.clear(queueUnreliableEvent)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
--[[
|
||||
|
|
|
|||
|
|
@ -16,19 +16,19 @@ local deltaT: number, cycle: number = 0, 1 / 61
|
|||
local writer: Buffer.Writer = Buffer.createWriter()
|
||||
|
||||
type Connection = {
|
||||
Connected: boolean,
|
||||
Disconnect: (self: Connection) -> (),
|
||||
Connected: boolean,
|
||||
Disconnect: (self: Connection) -> (),
|
||||
}
|
||||
type Event = {
|
||||
i: number,
|
||||
c: (Player, ...any?) -> ...any?,
|
||||
i: number,
|
||||
c: (Player, ...any?) -> ...any?,
|
||||
}
|
||||
|
||||
local queueEvent: {
|
||||
[Player]: { { any } },
|
||||
[Player]: { { any } },
|
||||
} = {}
|
||||
local queueUnreliableEvent: {
|
||||
[Player]: { { any } },
|
||||
[Player]: { { any } },
|
||||
} = {}
|
||||
local eventListeners: { Event } = {}
|
||||
local eventSchemas: { [number]: Buffer.SchemaType } = {}
|
||||
|
|
@ -41,78 +41,78 @@ local invokeId = 0
|
|||
--@optional
|
||||
-- Register namespaces to ensure all of the namespaces is being registered earlier on the server to prevent any unexpected issues on the client.
|
||||
Server.reg_namespaces = function(namespaces: { string })
|
||||
for _, name: string in namespaces do
|
||||
Identifier.get_id(name)
|
||||
end
|
||||
for _, name: string in namespaces do
|
||||
Identifier.get_id(name)
|
||||
end
|
||||
end
|
||||
|
||||
--@remoteName string
|
||||
--@schema Buffer.SchemaType
|
||||
-- Define a schema for strict data packing on a specific event.
|
||||
Server.useSchema = function(remoteName: string, schema: Buffer.SchemaType)
|
||||
eventSchemas[Identifier.get_id(remoteName)] = schema
|
||||
eventSchemas[Identifier.get_id(remoteName)] = schema
|
||||
end
|
||||
|
||||
--@remoteName string
|
||||
--@fn function
|
||||
-- Connect to an event to receive incoming data from clients.
|
||||
Server.Connect = function(remoteName: string, fn: (Player, ...any?) -> ...any?): Connection
|
||||
local detail = {
|
||||
i = Identifier.get_id(remoteName),
|
||||
c = fn,
|
||||
}
|
||||
table.insert(eventListeners, detail)
|
||||
return {
|
||||
Connected = true,
|
||||
Disconnect = function(self: Connection)
|
||||
if not self.Connected then
|
||||
return
|
||||
end
|
||||
self.Connected = false
|
||||
local idx = table.find(eventListeners, detail)
|
||||
if idx then
|
||||
table.remove(eventListeners, idx)
|
||||
end
|
||||
end,
|
||||
} :: Connection
|
||||
local detail = {
|
||||
i = Identifier.get_id(remoteName),
|
||||
c = fn,
|
||||
}
|
||||
table.insert(eventListeners, detail)
|
||||
return {
|
||||
Connected = true,
|
||||
Disconnect = function(self: Connection)
|
||||
if not self.Connected then
|
||||
return
|
||||
end
|
||||
self.Connected = false
|
||||
local idx = table.find(eventListeners, detail)
|
||||
if idx then
|
||||
table.remove(eventListeners, idx)
|
||||
end
|
||||
end,
|
||||
} :: Connection
|
||||
end
|
||||
|
||||
--@remoteName string
|
||||
--@fn function
|
||||
-- Similar to :Connect but automatically disconnects after the first firing.
|
||||
Server.Once = function(remoteName: string, fn: (...any?) -> ()): Connection
|
||||
local connection
|
||||
connection = Server.Connect(remoteName, function(...: any?)
|
||||
if connection then
|
||||
connection:Disconnect()
|
||||
end
|
||||
fn(...)
|
||||
end)
|
||||
return connection
|
||||
local connection
|
||||
connection = Server.Connect(remoteName, function(...: any?)
|
||||
if connection then
|
||||
connection:Disconnect()
|
||||
end
|
||||
fn(...)
|
||||
end)
|
||||
return connection
|
||||
end
|
||||
|
||||
--@remoteName string
|
||||
-- Wait for an event to be triggered. Yields the current thread.
|
||||
Server.Wait = function(remoteName: string): (number, ...any?)
|
||||
local thread, t = coroutine.running(), os.clock()
|
||||
Server.Once(remoteName, function(...: any?)
|
||||
task.spawn(thread, os.clock() - t, ...)
|
||||
end)
|
||||
return coroutine.yield()
|
||||
local thread, t = coroutine.running(), os.clock()
|
||||
Server.Once(remoteName, function(...: any?)
|
||||
task.spawn(thread, os.clock() - t, ...)
|
||||
end)
|
||||
return coroutine.yield()
|
||||
end
|
||||
|
||||
--@remoteName string
|
||||
-- Disconnect all connections for a specific event.
|
||||
Server.DisconnectAll = function(remoteName: string)
|
||||
local id = Identifier.get_id(remoteName)
|
||||
if not id then
|
||||
return
|
||||
end
|
||||
for idx = #eventListeners, 1, -1 do
|
||||
if eventListeners[idx].i == id then
|
||||
table.remove(eventListeners, idx)
|
||||
end
|
||||
end
|
||||
local id = Identifier.get_id(remoteName)
|
||||
if not id then
|
||||
return
|
||||
end
|
||||
for idx = #eventListeners, 1, -1 do
|
||||
if eventListeners[idx].i == id then
|
||||
table.remove(eventListeners, idx)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--@remoteName string
|
||||
|
|
@ -124,23 +124,23 @@ Server.Destroy = Server.DisconnectAll
|
|||
--@player Player
|
||||
-- Fire an event to a specific player.
|
||||
Server.Fire = function(remoteName: string, reliable: boolean, player: Player, ...: any?)
|
||||
local targetQueue = reliable and queueEvent or queueUnreliableEvent
|
||||
if not targetQueue[player] then
|
||||
targetQueue[player] = {} :: any
|
||||
end
|
||||
table.insert(targetQueue[player], {
|
||||
Identifier.get_id(remoteName),
|
||||
{ ... } :: any,
|
||||
})
|
||||
local targetQueue = reliable and queueEvent or queueUnreliableEvent
|
||||
if not targetQueue[player] then
|
||||
targetQueue[player] = {} :: any
|
||||
end
|
||||
table.insert(targetQueue[player], {
|
||||
Identifier.get_id(remoteName),
|
||||
{ ... } :: any,
|
||||
})
|
||||
end
|
||||
|
||||
--@remoteName string
|
||||
--@reliable boolean
|
||||
-- Fire an event to all connected players.
|
||||
Server.Fires = function(remoteName: string, reliable: boolean, ...: any?)
|
||||
for _, player: Player in players_ready do
|
||||
Server.Fire(remoteName, reliable, player, ...)
|
||||
end
|
||||
for _, player: Player in players_ready do
|
||||
Server.Fire(remoteName, reliable, player, ...)
|
||||
end
|
||||
end
|
||||
|
||||
--@remoteName string
|
||||
|
|
@ -148,10 +148,10 @@ end
|
|||
--@except { Player }
|
||||
-- Fire an event to all players except specified ones.
|
||||
Server.FireExcept = function(remoteName: string, reliable: boolean, except: { Player }, ...: any?)
|
||||
for _, player: Player in players_ready do
|
||||
if table.find(except, player) then continue end
|
||||
Server.Fire(remoteName, reliable, player, ...)
|
||||
end
|
||||
for _, player: Player in players_ready do
|
||||
if table.find(except, player) then continue end
|
||||
Server.Fire(remoteName, reliable, player, ...)
|
||||
end
|
||||
end
|
||||
|
||||
--@remoteName string
|
||||
|
|
@ -159,172 +159,174 @@ end
|
|||
--@timeout number?
|
||||
-- Invoke a client with timeout support. Yields the current thread. Returns nil if timeout occurs.
|
||||
Server.Invoke = function(remoteName: string, player: Player, timeout: number?, ...: any?): ...any?
|
||||
invokeId += 1
|
||||
local reqId, thread = `{invokeId}`, coroutine.running()
|
||||
invokeId += 1
|
||||
local reqId, thread = `{invokeId}`, coroutine.running()
|
||||
|
||||
pendingInvokes[reqId] = thread
|
||||
task.delay(timeout or 2, function()
|
||||
local pending = pendingInvokes[reqId]
|
||||
if not pending then
|
||||
return
|
||||
end
|
||||
task.spawn(pending, nil)
|
||||
pendingInvokes[reqId] = nil
|
||||
end)
|
||||
if not queueEvent[player] then
|
||||
queueEvent[player] = {} :: any
|
||||
end
|
||||
table.insert(queueEvent[player], {
|
||||
0,
|
||||
{ Identifier.get_id(remoteName), reqId :: any, { ... } :: any } :: any,
|
||||
})
|
||||
return coroutine.yield()
|
||||
pendingInvokes[reqId] = thread
|
||||
task.delay(timeout or 2, function()
|
||||
local pending = pendingInvokes[reqId]
|
||||
if not pending then
|
||||
return
|
||||
end
|
||||
task.spawn(pending, nil)
|
||||
pendingInvokes[reqId] = nil
|
||||
end)
|
||||
if not queueEvent[player] then
|
||||
queueEvent[player] = {} :: any
|
||||
end
|
||||
table.insert(queueEvent[player], {
|
||||
0,
|
||||
{ Identifier.get_id(remoteName), reqId :: any, { ... } :: any } :: any,
|
||||
})
|
||||
return coroutine.yield()
|
||||
end
|
||||
|
||||
if RunService:IsServer() then
|
||||
local function processIncoming(player: Player, b: buffer, ref: { Instance }?, handleInvokes: boolean)
|
||||
if type(b) ~= "buffer" then
|
||||
return
|
||||
end
|
||||
local bytes: number = (player_bytes[player] or 0) + math.max(buffer.len(b), 800)
|
||||
if bytes > 8e3 then return end
|
||||
player_bytes[player] = bytes
|
||||
|
||||
local contents = Buffer.readEvents(b, ref, eventSchemas)
|
||||
for _, content in contents do
|
||||
local remote = content[1]
|
||||
local content = content[2]
|
||||
if handleInvokes then
|
||||
if remote == 1 then
|
||||
local id = content[1]
|
||||
local results = content[2]
|
||||
local pending = pendingInvokes[id]
|
||||
if pending then
|
||||
task.spawn(pending :: any, table.unpack(results))
|
||||
pendingInvokes[id] = nil
|
||||
end
|
||||
continue
|
||||
end
|
||||
if remote == 0 then
|
||||
if #eventListeners == 0 then
|
||||
continue
|
||||
end
|
||||
local remoteName = content[1]
|
||||
local id = content[2]
|
||||
local args = content[3]
|
||||
for _, connection in eventListeners do
|
||||
if connection.i == remoteName then
|
||||
Thread(function()
|
||||
local results = { connection.c(player, table.unpack(args)) }
|
||||
if not queueEvent[player] then
|
||||
queueEvent[player] = {} :: any
|
||||
end
|
||||
table.insert(queueEvent[player], {
|
||||
0,
|
||||
{ id, results } :: any,
|
||||
})
|
||||
end)
|
||||
break
|
||||
end
|
||||
end
|
||||
continue
|
||||
end
|
||||
end
|
||||
if #eventListeners == 0 then
|
||||
continue
|
||||
end
|
||||
for _, connection in eventListeners do
|
||||
if connection.i ~= remote then
|
||||
continue
|
||||
end
|
||||
Thread(connection.c, player, table.unpack(content))
|
||||
end
|
||||
end
|
||||
end
|
||||
local function processIncoming(player: Player, b: buffer, ref: { Instance }?, handleInvokes: boolean)
|
||||
if type(b) ~= "buffer" then
|
||||
return
|
||||
end
|
||||
if not RunService:IsStudio() then
|
||||
local bytes: number = (player_bytes[player] or 0) + math.max(buffer.len(b), 800)
|
||||
if bytes > 8e3 then return end
|
||||
player_bytes[player] = bytes
|
||||
end
|
||||
|
||||
Event.OnServerEvent:Connect(function(player: Player, b: buffer, ref: { Instance }?)
|
||||
processIncoming(player, b, ref, true)
|
||||
end)
|
||||
local contents = Buffer.readEvents(b, ref, eventSchemas)
|
||||
for _, content in contents do
|
||||
local remote = content[1]
|
||||
local content = content[2]
|
||||
if handleInvokes then
|
||||
if remote == 1 then
|
||||
local id = content[1]
|
||||
local results = content[2]
|
||||
local pending = pendingInvokes[id]
|
||||
if pending then
|
||||
task.spawn(pending :: any, table.unpack(results))
|
||||
pendingInvokes[id] = nil
|
||||
end
|
||||
continue
|
||||
end
|
||||
if remote == 0 then
|
||||
if #eventListeners == 0 then
|
||||
continue
|
||||
end
|
||||
local remoteName = content[1]
|
||||
local id = content[2]
|
||||
local args = content[3]
|
||||
for _, connection in eventListeners do
|
||||
if connection.i == remoteName then
|
||||
Thread(function()
|
||||
local results = { connection.c(player, table.unpack(args)) }
|
||||
if not queueEvent[player] then
|
||||
queueEvent[player] = {} :: any
|
||||
end
|
||||
table.insert(queueEvent[player], {
|
||||
0,
|
||||
{ id, results } :: any,
|
||||
})
|
||||
end)
|
||||
break
|
||||
end
|
||||
end
|
||||
continue
|
||||
end
|
||||
end
|
||||
if #eventListeners == 0 then
|
||||
continue
|
||||
end
|
||||
for _, connection in eventListeners do
|
||||
if connection.i ~= remote then
|
||||
continue
|
||||
end
|
||||
Thread(connection.c, player, table.unpack(content))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
UnreliableEvent.OnServerEvent:Connect(function(player: Player, b: buffer, ref: { Instance }?)
|
||||
processIncoming(player, b, ref, false)
|
||||
end)
|
||||
Event.OnServerEvent:Connect(function(player: Player, b: buffer, ref: { Instance }?)
|
||||
processIncoming(player, b, ref, true)
|
||||
end)
|
||||
|
||||
RunService.PostSimulation:Connect(function(d: number)
|
||||
deltaT += d
|
||||
if deltaT < cycle then
|
||||
return
|
||||
end
|
||||
deltaT = 0
|
||||
UnreliableEvent.OnServerEvent:Connect(function(player: Player, b: buffer, ref: { Instance }?)
|
||||
processIncoming(player, b, ref, false)
|
||||
end)
|
||||
|
||||
-- reliable
|
||||
for player: Player, content in queueEvent do
|
||||
if #content == 0 or player.Parent ~= Players then
|
||||
continue
|
||||
end
|
||||
Buffer.writeEvents(writer, content, eventSchemas)
|
||||
do
|
||||
local buf, ref = Buffer.buildWithRefs(writer)
|
||||
Buffer.reset(writer)
|
||||
if not ref or #ref == 0 then
|
||||
Event:FireClient(player, buf)
|
||||
else
|
||||
Event:FireClient(player, buf, ref)
|
||||
end
|
||||
end
|
||||
player_bytes[player] = 0
|
||||
table.clear(queueEvent[player])
|
||||
end
|
||||
-- unreliable
|
||||
for player: Player, content in queueUnreliableEvent do
|
||||
if #content == 0 or player.Parent ~= Players then
|
||||
continue
|
||||
end
|
||||
Buffer.writeEvents(writer, content, eventSchemas)
|
||||
do
|
||||
local buf, ref = Buffer.buildWithRefs(writer)
|
||||
Buffer.reset(writer)
|
||||
if not ref or #ref == 0 then
|
||||
UnreliableEvent:FireClient(player, buf)
|
||||
else
|
||||
UnreliableEvent:FireClient(player, buf, ref)
|
||||
end
|
||||
end
|
||||
table.clear(player_bytes)
|
||||
table.clear(queueUnreliableEvent[player])
|
||||
end
|
||||
end)
|
||||
RunService.PostSimulation:Connect(function(d: number)
|
||||
deltaT += d
|
||||
if deltaT < cycle then
|
||||
return
|
||||
end
|
||||
deltaT = 0
|
||||
|
||||
local function onAdded(player: Player)
|
||||
if not table.find(players_ready, player) then
|
||||
table.insert(players_ready, player)
|
||||
end
|
||||
if not queueEvent[player] then
|
||||
queueEvent[player] = {} :: any
|
||||
end
|
||||
if not queueUnreliableEvent[player] then
|
||||
queueUnreliableEvent[player] = {} :: any
|
||||
end
|
||||
end
|
||||
Players.PlayerAdded:Connect(onAdded)
|
||||
Players.PlayerRemoving:Connect(function(player: Player)
|
||||
Replication.remove(player)
|
||||
table.remove(players_ready, table.find(players_ready, player))
|
||||
if queueEvent[player] then
|
||||
table.clear(queueEvent[player])
|
||||
queueEvent[player] = nil
|
||||
end
|
||||
if player_bytes[player] then
|
||||
player_bytes[player] = nil
|
||||
end
|
||||
if queueUnreliableEvent[player] then
|
||||
table.clear(queueUnreliableEvent[player])
|
||||
queueUnreliableEvent[player] = nil
|
||||
end
|
||||
end)
|
||||
for _, player: Player in ipairs(Players:GetPlayers()) do
|
||||
onAdded(player)
|
||||
end
|
||||
-- reliable
|
||||
for player: Player, content in queueEvent do
|
||||
if #content == 0 or player.Parent ~= Players then
|
||||
continue
|
||||
end
|
||||
Buffer.writeEvents(writer, content, eventSchemas)
|
||||
do
|
||||
local buf, ref = Buffer.buildWithRefs(writer)
|
||||
Buffer.reset(writer)
|
||||
if not ref or #ref == 0 then
|
||||
Event:FireClient(player, buf)
|
||||
else
|
||||
Event:FireClient(player, buf, ref)
|
||||
end
|
||||
end
|
||||
player_bytes[player] = 0
|
||||
table.clear(queueEvent[player])
|
||||
end
|
||||
-- unreliable
|
||||
for player: Player, content in queueUnreliableEvent do
|
||||
if #content == 0 or player.Parent ~= Players then
|
||||
continue
|
||||
end
|
||||
Buffer.writeEvents(writer, content, eventSchemas)
|
||||
do
|
||||
local buf, ref = Buffer.buildWithRefs(writer)
|
||||
Buffer.reset(writer)
|
||||
if not ref or #ref == 0 then
|
||||
UnreliableEvent:FireClient(player, buf)
|
||||
else
|
||||
UnreliableEvent:FireClient(player, buf, ref)
|
||||
end
|
||||
end
|
||||
table.clear(player_bytes)
|
||||
table.clear(queueUnreliableEvent[player])
|
||||
end
|
||||
end)
|
||||
|
||||
local function onAdded(player: Player)
|
||||
if not table.find(players_ready, player) then
|
||||
table.insert(players_ready, player)
|
||||
end
|
||||
if not queueEvent[player] then
|
||||
queueEvent[player] = {} :: any
|
||||
end
|
||||
if not queueUnreliableEvent[player] then
|
||||
queueUnreliableEvent[player] = {} :: any
|
||||
end
|
||||
end
|
||||
Players.PlayerAdded:Connect(onAdded)
|
||||
Players.PlayerRemoving:Connect(function(player: Player)
|
||||
Replication.remove(player)
|
||||
table.remove(players_ready, table.find(players_ready, player))
|
||||
if queueEvent[player] then
|
||||
table.clear(queueEvent[player])
|
||||
queueEvent[player] = nil
|
||||
end
|
||||
if player_bytes[player] then
|
||||
player_bytes[player] = nil
|
||||
end
|
||||
if queueUnreliableEvent[player] then
|
||||
table.clear(queueUnreliableEvent[player])
|
||||
queueUnreliableEvent[player] = nil
|
||||
end
|
||||
end)
|
||||
for _, player: Player in ipairs(Players:GetPlayers()) do
|
||||
onAdded(player)
|
||||
end
|
||||
end
|
||||
|
||||
--[[
|
||||
|
|
|
|||
Loading…
Reference in a new issue