mirror of
https://github.com/imezx/Warp.git
synced 2025-04-24 15:10:03 +00:00
v1.0.11
This commit is contained in:
parent
44fa07df85
commit
aa693aee4f
10 changed files with 284 additions and 208 deletions
BIN
Warp.rbxm
BIN
Warp.rbxm
Binary file not shown.
|
@ -13,8 +13,10 @@ When creating a event on Server, you can add second argument (optional) as table
|
|||
-- Server
|
||||
-- Let's make the event have ratelimit with max 50 entrance for 2 seconds.
|
||||
local Remote = Warp.Server("Remote1", {
|
||||
rateLimit = {
|
||||
maxEntrance = 50, -- maximum 50 fires.
|
||||
interval = 2, -- 2 seconds
|
||||
}
|
||||
})
|
||||
-- Now the Event RateLimit is configured, and ready to use.
|
||||
-- No need anything to adds on client side.
|
||||
|
|
|
@ -36,12 +36,16 @@ Create new Warp events with array.
|
|||
```lua [Example]
|
||||
local Events = Warp.fromServerArray({
|
||||
["Remote1"] = {
|
||||
rateLimit = {
|
||||
maxEntrance: 50,
|
||||
interval: 1,
|
||||
}
|
||||
}, -- with rateLimit configuration
|
||||
"Remote2", -- without rateLimit configuration
|
||||
["Remote3"] = {
|
||||
rateLimit = {
|
||||
maxEntrance: 10,
|
||||
}
|
||||
}, -- with rateLimit configuration
|
||||
})
|
||||
|
||||
|
|
|
@ -102,7 +102,23 @@ Signal1:DisconnectAll()
|
|||
|
||||
## `:Fire`
|
||||
|
||||
Fire the signal.
|
||||
Fire the signal (Immediate)
|
||||
|
||||
::: code-group
|
||||
```lua [Variable]
|
||||
(
|
||||
...: any
|
||||
)
|
||||
```
|
||||
|
||||
```lua [Example]
|
||||
Signal1:Fire("Hello World!")
|
||||
```
|
||||
:::
|
||||
|
||||
## `:DeferFire`
|
||||
|
||||
Fire the signal (Deferred)
|
||||
|
||||
::: code-group
|
||||
```lua [Variable]
|
||||
|
@ -122,7 +138,7 @@ This uses `pcall`, which means it never error (safe-mode, sacrificed debugging),
|
|||
|
||||
## `:FireTo`
|
||||
|
||||
Fire to other signal, this also use `:Fire`.
|
||||
Fire to other signal, this uses `:Fire`.
|
||||
|
||||
::: code-group
|
||||
```lua [Variable]
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
::: code-group
|
||||
```toml [wally.toml]
|
||||
[dependencies]
|
||||
warp = "imezx/warp@1.0.5"
|
||||
warp = "imezx/warp@1.0.11"
|
||||
```
|
||||
|
||||
3. Run `wally install` in command.
|
||||
|
|
|
@ -19,6 +19,7 @@ local clientQueue: Type.QueueMap = {}
|
|||
local unreliableClientQueue: Type.QueueMap = {}
|
||||
local clientCallback: Type.CallbackMap = {}
|
||||
local clientRequestQueue: Type.QueueMap = {}
|
||||
local registeredIdentifier: { string } = {}
|
||||
|
||||
local queueIn: {
|
||||
[string]: {any}
|
||||
|
@ -37,11 +38,6 @@ local queueOutRequest: {
|
|||
}
|
||||
}
|
||||
} = {}
|
||||
local incoming_cache: {
|
||||
[string]: {
|
||||
any
|
||||
}
|
||||
} = {}
|
||||
local logger: {
|
||||
[string]: boolean
|
||||
} = {}
|
||||
|
@ -86,7 +82,9 @@ function ClientProcess.insertRequest(Identifier: string, timeout: number, ...: a
|
|||
end
|
||||
|
||||
function ClientProcess.add(Identifier: any, originId: string, conf: Type.ClientConf)
|
||||
if not clientQueue[Identifier] then
|
||||
if not table.find(registeredIdentifier, Identifier) then
|
||||
table.insert(registeredIdentifier, Identifier)
|
||||
|
||||
if conf.logging then
|
||||
ClientProcess.logger(Identifier, conf.logging.store, conf.logging.opt)
|
||||
end
|
||||
|
@ -149,7 +147,13 @@ end
|
|||
|
||||
function ClientProcess.start()
|
||||
debug.setmemorycategory("Warp")
|
||||
local clock_limit = 1/60
|
||||
local past_clock = os.clock()
|
||||
|
||||
RunService.PostSimulation:Connect(function()
|
||||
if (os.clock()-past_clock) >= (clock_limit - 0.006) then -- less potential to skip frames
|
||||
past_clock = os.clock()
|
||||
-- Unreliable
|
||||
for Identifier: string, data: any in unreliableClientQueue do
|
||||
if #data == 0 then continue end
|
||||
if clientRatelimit[Identifier](#data) then
|
||||
|
@ -160,8 +164,8 @@ function ClientProcess.start()
|
|||
end
|
||||
unreliableClientQueue[Identifier] = nil
|
||||
end
|
||||
-- Reliable
|
||||
for Identifier: string, data: any in clientQueue do
|
||||
local callback = clientCallback[Identifier] or nil
|
||||
if #data > 0 then
|
||||
if clientRatelimit[Identifier](#data) then
|
||||
ReliableEvent:FireServer(Buffer.revert(Identifier), data)
|
||||
|
@ -171,6 +175,28 @@ function ClientProcess.start()
|
|||
end
|
||||
clientQueue[Identifier] = nil
|
||||
end
|
||||
end
|
||||
-- Sent new invokes
|
||||
for Identifier: string, requestsData in queueOutRequest[1] do
|
||||
if #requestsData == 0 then continue end
|
||||
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
|
||||
end
|
||||
-- Sent returning invokes
|
||||
for Identifier: string, toReturnDatas in queueOutRequest[2] do
|
||||
if #toReturnDatas == 0 then continue end
|
||||
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
|
||||
end
|
||||
end
|
||||
|
||||
for _, Identifier: string in registeredIdentifier do
|
||||
if clientRequestQueue[Identifier] then
|
||||
for _, requestData in clientRequestQueue[Identifier] do
|
||||
if not requestData[3] then continue end
|
||||
|
@ -179,20 +205,12 @@ function ClientProcess.start()
|
|||
end
|
||||
table.insert(queueOutRequest[1][Identifier], { requestData[1], requestData[3] })
|
||||
end
|
||||
clientRequestQueue[Identifier] = nil
|
||||
end
|
||||
if callback then
|
||||
if incoming_cache[Identifier] then
|
||||
for _, packet in incoming_cache[Identifier] do
|
||||
if #packet == 0 then continue end
|
||||
for _, fn: any in callback do
|
||||
for i=1,#packet do
|
||||
Spawn(fn, table.unpack(packet[i] or {}))
|
||||
end
|
||||
end
|
||||
end
|
||||
incoming_cache[Identifier] = nil
|
||||
end
|
||||
|
||||
-- Unreliable & Reliable
|
||||
local callback = clientCallback[Identifier] or nil
|
||||
if not callback then continue end
|
||||
|
||||
if queueIn[Identifier] then
|
||||
for _, packedDatas: any in queueIn[Identifier] do
|
||||
if #packedDatas == 0 then continue end
|
||||
|
@ -204,25 +222,32 @@ function ClientProcess.start()
|
|||
end
|
||||
queueIn[Identifier] = nil
|
||||
end
|
||||
|
||||
-- Return Invoke
|
||||
if queueInRequest[1][Identifier] then
|
||||
for _, packetDatas: any in queueInRequest[1][Identifier] 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
|
||||
if not packetDatas[i] then continue end
|
||||
local packetData1 = packetDatas[i][1]
|
||||
local packetData2 = packetDatas[i][2]
|
||||
Spawn(function()
|
||||
local requestReturn = { fn(table.unpack(packetData[2])) }
|
||||
local requestReturn = { fn(table.unpack(packetData1)) }
|
||||
if not queueOutRequest[2][Identifier] then
|
||||
queueOutRequest[2][Identifier] = {}
|
||||
end
|
||||
table.insert(queueOutRequest[2][Identifier], { packetData[1], requestReturn })
|
||||
table.insert(queueOutRequest[2][Identifier], { packetData2, requestReturn })
|
||||
packetData1 = nil
|
||||
packetData2 = nil
|
||||
end)
|
||||
end
|
||||
end
|
||||
end
|
||||
queueInRequest[1][Identifier] = nil
|
||||
end
|
||||
|
||||
-- Call to Invoke
|
||||
if queueInRequest[2][Identifier] then
|
||||
if clientRequestQueue[Identifier] then
|
||||
for _, packetDatas: any in queueInRequest[2][Identifier] do
|
||||
|
@ -243,23 +268,6 @@ function ClientProcess.start()
|
|||
queueInRequest[2][Identifier] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
for Identifier: string, requestsData in queueOutRequest[1] do
|
||||
if #requestsData == 0 then continue end
|
||||
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
|
||||
end
|
||||
for Identifier: string, toReturnDatas in queueOutRequest[2] do
|
||||
if #toReturnDatas == 0 then continue end
|
||||
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
|
||||
end
|
||||
end)
|
||||
local function onClientNetworkReceive(Identifier: any, data: any)
|
||||
if not Identifier or not data then return end
|
||||
|
@ -267,16 +275,6 @@ function ClientProcess.start()
|
|||
if not queueIn[Identifier] then
|
||||
queueIn[Identifier] = {}
|
||||
end
|
||||
if not clientCallback[Identifier] then
|
||||
if not incoming_cache[Identifier] then
|
||||
incoming_cache[Identifier] = {}
|
||||
end
|
||||
table.insert(incoming_cache[Identifier], data)
|
||||
if logger[Identifier] then
|
||||
task.defer(Logger.write, Identifier, `state: cache -> net -> {#data} data.`)
|
||||
end
|
||||
return
|
||||
end
|
||||
table.insert(queueIn[Identifier], data)
|
||||
if logger[Identifier] then
|
||||
task.defer(Logger.write, Identifier, `state: in -> net -> {#data} data.`)
|
||||
|
|
|
@ -72,12 +72,21 @@ local function initializeEachPlayer(player: Player)
|
|||
if not queueOut[player][Identifier] then
|
||||
queueOut[player][Identifier] = {}
|
||||
end
|
||||
if not serverRequestQueue[Identifier] then
|
||||
serverRequestQueue[Identifier] = {}
|
||||
end
|
||||
if not serverRequestQueue[Identifier][player] then
|
||||
serverRequestQueue[Identifier][player] = {}
|
||||
end
|
||||
if not queueIn[Identifier][player] then
|
||||
queueIn[Identifier][player] = {}
|
||||
end
|
||||
if not queueOutRequest[1][Identifier] then
|
||||
queueOutRequest[1][Identifier] = {}
|
||||
end
|
||||
if not queueOutRequest[2][Identifier] then
|
||||
queueOutRequest[2][Identifier] = {}
|
||||
end
|
||||
if not queueInRequest[1][Identifier][player] then
|
||||
queueInRequest[1][Identifier][player] = {}
|
||||
queueInRequest[2][Identifier][player] = {}
|
||||
|
@ -93,12 +102,18 @@ Players.PlayerAdded:Connect(initializeEachPlayer)
|
|||
|
||||
function ServerProcess.insertQueue(Identifier: string, reliable: boolean, player: Player, ...: any)
|
||||
if not reliable then
|
||||
if not unreliableServerQueue[Identifier] then
|
||||
unreliableServerQueue[Identifier] = {}
|
||||
end
|
||||
if not unreliableServerQueue[Identifier][player] then
|
||||
unreliableServerQueue[Identifier][player] = {}
|
||||
end
|
||||
table.insert(unreliableServerQueue[Identifier][player], { ... })
|
||||
return
|
||||
end
|
||||
if not serverQueue[Identifier] then
|
||||
serverQueue[Identifier] = {}
|
||||
end
|
||||
if not serverQueue[Identifier][player] then
|
||||
serverQueue[Identifier][player] = {}
|
||||
end
|
||||
|
@ -106,12 +121,12 @@ function ServerProcess.insertQueue(Identifier: string, reliable: boolean, player
|
|||
end
|
||||
|
||||
function ServerProcess.insertRequest(Identifier: string, timeout: number, player: Player, ...: any)
|
||||
if not serverQueue[Identifier][player] then
|
||||
serverQueue[Identifier][player] = {}
|
||||
end
|
||||
if not serverRequestQueue[Identifier] then
|
||||
serverRequestQueue[Identifier] = {}
|
||||
end
|
||||
if not serverRequestQueue[Identifier][player] then
|
||||
serverRequestQueue[Identifier][player] = {}
|
||||
end
|
||||
local yieldThread: thread, start = coroutine.running(), os.clock()
|
||||
local cancel = task.delay(timeout, function()
|
||||
task.spawn(yieldThread, nil)
|
||||
|
@ -127,7 +142,9 @@ end
|
|||
function ServerProcess.add(Identifier: string, originId: string, conf: Type.ServerConf)
|
||||
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)
|
||||
|
||||
if conf.logging then
|
||||
ServerProcess.logger(Identifier, conf.logging.store, conf.logging.opt)
|
||||
end
|
||||
|
@ -191,7 +208,13 @@ end
|
|||
|
||||
function ServerProcess.start()
|
||||
debug.setmemorycategory("Warp")
|
||||
local clock_limit = 1/60
|
||||
local past_clock = os.clock()
|
||||
|
||||
RunService.PostSimulation:Connect(function()
|
||||
if (os.clock()-past_clock) >= (clock_limit - 0.006) then -- less potential to skip frames
|
||||
past_clock = os.clock()
|
||||
-- Unreliable
|
||||
for Identifier: string, players in unreliableServerQueue do
|
||||
for player: Player, content: any in players do
|
||||
if #content == 0 then continue end
|
||||
|
@ -201,11 +224,21 @@ function ServerProcess.start()
|
|||
end
|
||||
unreliableServerQueue[Identifier][player] = nil
|
||||
end
|
||||
unreliableServerQueue[Identifier] = nil
|
||||
end
|
||||
|
||||
-- Reliable
|
||||
for Identifier: string, contents: { [Player]: { any } } in serverQueue do
|
||||
|
||||
for player: Player, requestsData: any in queueOutRequest[1][Identifier] do
|
||||
for player, content: any in contents do
|
||||
if #content > 0 and queueOut[player] then
|
||||
ReliableEvent:FireClient(player, Buffer.revert(Identifier), content)
|
||||
end
|
||||
serverQueue[Identifier][player] = nil
|
||||
end
|
||||
serverQueue[Identifier] = nil
|
||||
end
|
||||
-- Sent new invokes
|
||||
for Identifier: string, contents in queueOutRequest[1] do
|
||||
for player: Player, requestsData: any in contents do
|
||||
if #requestsData > 0 then
|
||||
RequestEvent:FireClient(player, Buffer.revert(Identifier), "\1", requestsData)
|
||||
if logger[Identifier] then
|
||||
|
@ -214,8 +247,11 @@ function ServerProcess.start()
|
|||
end
|
||||
queueOutRequest[1][Identifier][player] = nil
|
||||
end
|
||||
|
||||
for player: Player, toReturnDatas: any in queueOutRequest[2][Identifier] do
|
||||
queueOutRequest[1][Identifier] = nil
|
||||
end
|
||||
-- Sent returning invokes
|
||||
for Identifier: string, contents in queueOutRequest[2] do
|
||||
for player: Player, toReturnDatas: any in contents do
|
||||
if #toReturnDatas > 0 then
|
||||
RequestEvent:FireClient(player, Buffer.revert(Identifier), "\0", toReturnDatas)
|
||||
if logger[Identifier] then
|
||||
|
@ -224,66 +260,79 @@ function ServerProcess.start()
|
|||
end
|
||||
queueOutRequest[2][Identifier][player] = nil
|
||||
end
|
||||
|
||||
local callback = serverCallback[Identifier] or nil
|
||||
for player, content: any in contents do
|
||||
if #content > 0 and queueOut[player] then
|
||||
ReliableEvent:FireClient(player, Buffer.revert(Identifier), content)
|
||||
queueOutRequest[2][Identifier] = nil
|
||||
end
|
||||
end
|
||||
serverQueue[Identifier][player] = nil
|
||||
|
||||
if serverRequestQueue[Identifier][player] then
|
||||
for _, requestData in serverRequestQueue[Identifier][player] do
|
||||
for _, Identifier: string in registeredIdentifier do
|
||||
if serverRequestQueue[Identifier] then
|
||||
for player, content in serverRequestQueue[Identifier] do
|
||||
for _, requestData in content do
|
||||
if not requestData[3] then continue end
|
||||
if not queueOutRequest[1][Identifier] then
|
||||
queueOutRequest[1][Identifier] = {}
|
||||
end
|
||||
if not queueOutRequest[1][Identifier][player] then
|
||||
queueOutRequest[1][Identifier][player] = {}
|
||||
end
|
||||
table.insert(queueOutRequest[1][Identifier][player], { requestData[1], requestData[3] })
|
||||
end
|
||||
serverRequestQueue[Identifier][player] = nil
|
||||
end
|
||||
end
|
||||
|
||||
if callback then
|
||||
local requestIn1: any = queueInRequest[1][Identifier][player]
|
||||
local requestIn2: any = queueInRequest[2][Identifier][player]
|
||||
local incoming: any = queueIn[Identifier][player]
|
||||
local callback = serverCallback[Identifier] or nil
|
||||
if not callback then continue end
|
||||
|
||||
if incoming then
|
||||
for _, packedDatas: any in incoming do
|
||||
if #packedDatas == 0 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,#packedDatas do
|
||||
Spawn(fn, player, table.unpack(packedDatas[i] or {}))
|
||||
for i=1,#incoming do
|
||||
Spawn(fn, player, table.unpack(incoming[i] or {}))
|
||||
end
|
||||
end
|
||||
end
|
||||
incoming = nil
|
||||
queueIn[Identifier][player] = nil
|
||||
end
|
||||
if requestIn1 then
|
||||
for _, packetDatas: any in requestIn1 do
|
||||
|
||||
-- Return Invoke
|
||||
for player, content in queueInRequest[1][Identifier] do
|
||||
if not callback then break end
|
||||
for _, packetDatas in content do
|
||||
if not callback then break end
|
||||
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
|
||||
if not packetDatas[i] then continue end
|
||||
local packetData1 = packetDatas[i][1]
|
||||
local packetData2 = packetDatas[i][2]
|
||||
Spawn(function()
|
||||
local requestReturn = { fn(player, table.unpack(packetData[2])) }
|
||||
local state = queueOutRequest[2][Identifier][player]
|
||||
local requestReturn = { fn(player, table.unpack(packetData2)) }
|
||||
if not queueOutRequest[2][Identifier] then
|
||||
queueOutRequest[2][Identifier] = {}
|
||||
end
|
||||
if not queueOutRequest[2][Identifier][player] then
|
||||
queueOutRequest[2][Identifier][player] = {}
|
||||
end
|
||||
table.insert(queueOutRequest[2][Identifier][player], { packetData[1], requestReturn })
|
||||
table.insert(queueOutRequest[2][Identifier][player], { packetData1, requestReturn })
|
||||
packetData1 = nil
|
||||
packetData2 = nil
|
||||
end)
|
||||
end
|
||||
end
|
||||
end
|
||||
requestIn1 = nil
|
||||
queueInRequest[1][Identifier][player] = nil
|
||||
end
|
||||
if requestIn2 then
|
||||
for _, packetDatas: any in requestIn2 do
|
||||
|
||||
-- Call to Invoke
|
||||
for player, content in queueInRequest[2][Identifier] do
|
||||
if not callback then break end
|
||||
for _, packetDatas in content do
|
||||
for _, packetData in packetDatas do
|
||||
if not callback then break end
|
||||
if #packetData == 1 then continue end
|
||||
local data = serverRequestQueue[Identifier][player]
|
||||
for i=1,#data do
|
||||
|
@ -297,10 +346,8 @@ function ServerProcess.start()
|
|||
end
|
||||
end
|
||||
end
|
||||
requestIn2 = nil
|
||||
queueInRequest[2][Identifier][player] = nil
|
||||
end
|
||||
end
|
||||
serverRequestQueue[Identifier] = nil
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
@ -330,6 +377,9 @@ function ServerProcess.start()
|
|||
queueInRequest[1][Identifier][player] = {}
|
||||
queueInRequest[2][Identifier][player] = {}
|
||||
end
|
||||
if not serverQueue[Identifier] then
|
||||
serverQueue[Identifier] = {}
|
||||
end
|
||||
if not serverQueue[Identifier][player] then
|
||||
serverQueue[Identifier][player] = {}
|
||||
end
|
||||
|
|
|
@ -53,6 +53,12 @@ function Signal:Wait(): number
|
|||
return coroutine.yield()
|
||||
end
|
||||
|
||||
function Signal:DeferFire(...: any): ()
|
||||
for _, handle in self do
|
||||
task.defer(handle.fn, ...)
|
||||
end
|
||||
end
|
||||
|
||||
function Signal:Fire(...: any): ()
|
||||
for _, handle in self do
|
||||
task.spawn(handle.fn, ...)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
-- Warp Library (@Eternity_Devs)
|
||||
-- version 1.0.10
|
||||
-- version 1.0.11
|
||||
--!strict
|
||||
--!native
|
||||
--!optimize 2
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "imezx/warp"
|
||||
version = "1.0.10"
|
||||
version = "1.0.11"
|
||||
registry = "https://github.com/UpliftGames/wally-index"
|
||||
realm = "shared"
|
||||
license = "MIT"
|
||||
|
|
Loading…
Reference in a new issue