mirror of
https://github.com/imezx/Warp.git
synced 2025-04-24 23:20:02 +00:00
Compare commits
6 commits
Author | SHA1 | Date | |
---|---|---|---|
|
0b1304f4c5 | ||
|
d8526c7e25 | ||
|
d065bc2e50 | ||
|
925df47d4c | ||
|
f3b674b377 | ||
|
677d3fa675 |
10 changed files with 128 additions and 55 deletions
BIN
Warp.rbxm
BIN
Warp.rbxm
Binary file not shown.
|
@ -230,20 +230,18 @@ function ClientProcess.start()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
local function onClientNetworkReceive(Identifier: buffer | string, data: buffer)
|
local function onClientNetworkReceive(Identifier: buffer | string, data: buffer, ref: { any }?)
|
||||||
if not Identifier or not data then return end
|
if not Identifier or typeof(Identifier) ~= "buffer" or not data or typeof(data) ~= "buffer" then return end
|
||||||
Identifier = Buffer.convert(Identifier :: buffer)
|
Identifier = Buffer.convert(Identifier)
|
||||||
local read = Buffer.read(data)
|
if not registeredIdentifier[Identifier :: string] then return end
|
||||||
|
local read = Buffer.read(data, ref)
|
||||||
if not read then return end
|
if not read then return end
|
||||||
for idx: string in registeredIdentifier do
|
local callback = clientCallback[Identifier :: string]
|
||||||
if idx ~= Identifier then continue end
|
if not callback then return end
|
||||||
local callback = clientCallback[idx] or nil
|
|
||||||
if not callback then continue end
|
|
||||||
for _, fn: any in callback do
|
for _, fn: any in callback do
|
||||||
Spawn(fn, table.unpack(read))
|
Spawn(fn, table.unpack(read))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
ReliableEvent.OnClientEvent:Connect(onClientNetworkReceive)
|
ReliableEvent.OnClientEvent:Connect(onClientNetworkReceive)
|
||||||
UnreliableEvent.OnClientEvent:Connect(onClientNetworkReceive)
|
UnreliableEvent.OnClientEvent:Connect(onClientNetworkReceive)
|
||||||
RequestEvent.OnClientEvent:Connect(function(Identifier: any, action: string, data)
|
RequestEvent.OnClientEvent:Connect(function(Identifier: any, action: string, data)
|
||||||
|
|
|
@ -49,12 +49,13 @@ local ReliableEvent = Event.Reliable
|
||||||
local UnreliableEvent = Event.Unreliable
|
local UnreliableEvent = Event.Unreliable
|
||||||
local RequestEvent = Event.Request
|
local RequestEvent = Event.Request
|
||||||
|
|
||||||
|
RateLimit.Protect()
|
||||||
|
|
||||||
local function initializeEachPlayer(player: Player)
|
local function initializeEachPlayer(player: Player)
|
||||||
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 registeredIdentifier 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
|
||||||
|
@ -84,6 +85,29 @@ local function initializeEachPlayer(player: Player)
|
||||||
end
|
end
|
||||||
|
|
||||||
Players.PlayerAdded:Connect(initializeEachPlayer)
|
Players.PlayerAdded:Connect(initializeEachPlayer)
|
||||||
|
Players.PlayerRemoving:Connect(function(player: Player)
|
||||||
|
if not player then return end
|
||||||
|
if queueOut[player] then
|
||||||
|
queueOut[player] = nil
|
||||||
|
end
|
||||||
|
for _, map in { serverQueue, unreliableServerQueue, serverRequestQueue } do
|
||||||
|
for Identifier: string in map do
|
||||||
|
map[Identifier][player] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for i=1,2 do
|
||||||
|
for Identifier: string in queueInRequest[i] do
|
||||||
|
if queueInRequest[i][Identifier][player] then
|
||||||
|
queueInRequest[i][Identifier][player] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for Identifier: string in queueOutRequest[i] do
|
||||||
|
if queueOutRequest[i][Identifier][player] then
|
||||||
|
queueOutRequest[i][Identifier][player] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
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
|
||||||
|
@ -303,20 +327,18 @@ function ServerProcess.start()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
local function onServerNetworkReceive(player: Player, Identifier: buffer | string, data: buffer)
|
local function onServerNetworkReceive(player: Player, Identifier: buffer | string, data: buffer, ref: { any }?)
|
||||||
if not Identifier or not data then return end
|
if not Identifier or typeof(Identifier) ~= "buffer" or not data or typeof(data) ~= "buffer" then return end
|
||||||
Identifier = Buffer.convert(Identifier :: buffer)
|
Identifier = Buffer.convert(Identifier :: buffer)
|
||||||
local read = Buffer.read(data)
|
if not registeredIdentifier[Identifier :: string] then return end
|
||||||
|
local read = Buffer.read(data, ref)
|
||||||
if not read then return end
|
if not read then return end
|
||||||
for idx: string in registeredIdentifier do
|
local callback = serverCallback[Identifier :: string]
|
||||||
if idx ~= Identifier then continue end
|
if not callback then return end
|
||||||
local callback = serverCallback[idx] or nil
|
|
||||||
if not callback then continue end
|
|
||||||
for _, fn: any in callback do
|
for _, fn: any in callback do
|
||||||
Spawn(fn, player, table.unpack(read))
|
Spawn(fn, player, table.unpack(read))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
ReliableEvent.OnServerEvent:Connect(onServerNetworkReceive)
|
ReliableEvent.OnServerEvent:Connect(onServerNetworkReceive)
|
||||||
UnreliableEvent.OnServerEvent:Connect(onServerNetworkReceive)
|
UnreliableEvent.OnServerEvent:Connect(onServerNetworkReceive)
|
||||||
RequestEvent.OnServerEvent:Connect(function(player: Player, Identifier: any, action: string, data: any)
|
RequestEvent.OnServerEvent:Connect(function(player: Player, Identifier: any, action: string, data: any)
|
||||||
|
|
|
@ -36,7 +36,7 @@ function DedicatedBuffer.alloc(self: any, byte: number)
|
||||||
local b: buffer = self.buffer
|
local b: buffer = self.buffer
|
||||||
|
|
||||||
while self.next + byte >= size do
|
while self.next + byte >= size do
|
||||||
size = math.floor(size * 1.2)
|
size = math.floor(size * 1.25) -- +25% increase
|
||||||
end
|
end
|
||||||
local newBuffer: buffer = create(size)
|
local newBuffer: buffer = create(size)
|
||||||
copy(newBuffer, 0, b)
|
copy(newBuffer, 0, b)
|
||||||
|
@ -56,13 +56,15 @@ function DedicatedBuffer.build(self: any): buffer
|
||||||
return build
|
return build
|
||||||
end
|
end
|
||||||
|
|
||||||
function DedicatedBuffer.buildAndRemove(self: any): buffer
|
function DedicatedBuffer.buildAndRemove(self: any): (buffer, (any)?)
|
||||||
local p: number = self.next > self.point and self.next or self.point
|
local p: number = self.next > self.point and self.next or self.point
|
||||||
local build: buffer = create(p)
|
local build: buffer = create(p)
|
||||||
|
local ref = #self.ref > 0 and table.clone(self.ref) or nil
|
||||||
|
|
||||||
copy(build, 0, self.buffer, 0, p)
|
copy(build, 0, self.buffer, 0, p)
|
||||||
|
|
||||||
self:remove()
|
self:remove()
|
||||||
return build
|
return build, ref
|
||||||
end
|
end
|
||||||
|
|
||||||
function DedicatedBuffer.wi8(self: any, val: number, alloc: number?)
|
function DedicatedBuffer.wi8(self: any, val: number, alloc: number?)
|
||||||
|
@ -124,14 +126,21 @@ function DedicatedBuffer.wType(self: any, ref: number)
|
||||||
self.point += 1
|
self.point += 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function DedicatedBuffer.wRef(self: any, value: any, alloc: number?)
|
||||||
|
if not value then return end
|
||||||
|
self:alloc(alloc or 1)
|
||||||
|
table.insert(self.ref, value)
|
||||||
|
local index = #self.ref
|
||||||
|
writeu8(self.buffer, self.point, index)
|
||||||
|
self.point += 1
|
||||||
|
end
|
||||||
|
|
||||||
function DedicatedBuffer.pack(self: any, data: {any})
|
function DedicatedBuffer.pack(self: any, data: {any})
|
||||||
if typeof(data) == "nil" then
|
if typeof(data) == "nil" then
|
||||||
self:wi8(0)
|
self:wi8(0)
|
||||||
elseif typeof(data) == "Instance" then
|
elseif typeof(data) == "Instance" then
|
||||||
self:wi8(-1) -- Instance marker
|
self:wi8(-1) -- Instance marker
|
||||||
self:pack(data.ClassName) -- Serialize ClassName
|
self:wRef(data)
|
||||||
self:pack(data.Name) -- Serialize Name
|
|
||||||
self:pack(data:GetAttributes())
|
|
||||||
elseif typeof(data) == "table" then
|
elseif typeof(data) == "table" then
|
||||||
--local isArray = (next(data) ~= nil and #data > 0) and true or false
|
--local isArray = (next(data) ~= nil and #data > 0) and true or false
|
||||||
local isArray = true
|
local isArray = true
|
||||||
|
@ -232,6 +241,7 @@ function DedicatedBuffer.flush(self: any)
|
||||||
self.next = default.next
|
self.next = default.next
|
||||||
self.size = default.size
|
self.size = default.size
|
||||||
self.buffer = create(default.bufferSize)
|
self.buffer = create(default.bufferSize)
|
||||||
|
table.clear(self.ref)
|
||||||
end
|
end
|
||||||
|
|
||||||
function DedicatedBuffer.new()
|
function DedicatedBuffer.new()
|
||||||
|
@ -239,7 +249,8 @@ function DedicatedBuffer.new()
|
||||||
point = default.point,
|
point = default.point,
|
||||||
next = default.next,
|
next = default.next,
|
||||||
size = default.size,
|
size = default.size,
|
||||||
buffer = create(default.bufferSize)
|
buffer = create(default.bufferSize),
|
||||||
|
ref = {},
|
||||||
}, DedicatedBuffer)
|
}, DedicatedBuffer)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -18,28 +18,27 @@ local readf64 = buffer.readf64
|
||||||
local readstring = buffer.readstring
|
local readstring = buffer.readstring
|
||||||
local len = buffer.len
|
local len = buffer.len
|
||||||
|
|
||||||
local function readValue(b: buffer, position: number): (any, number)
|
local function readValue(b: buffer, position: number, ref: { any }?): (any, number)
|
||||||
local typeByte = readi8(b, position)
|
local typeByte = readi8(b, position)
|
||||||
position += 1
|
position += 1
|
||||||
if typeByte == 0 then -- nil
|
if typeByte == 0 then -- nil
|
||||||
return nil, position
|
return nil, position
|
||||||
elseif typeByte == -1 then -- Instance
|
elseif typeByte == -1 then -- Instance
|
||||||
local className, position1 = readValue(b, position)
|
if not ref or #ref == 0 then
|
||||||
local name, position2 = readValue(b, position1)
|
return nil, position + 1
|
||||||
local properties, position3 = readValue(b, position2)
|
|
||||||
local instance: Instance = Instance.new(className)
|
|
||||||
instance.Name = name
|
|
||||||
for key, value in properties do
|
|
||||||
instance:SetAttribute(key, value)
|
|
||||||
end
|
end
|
||||||
return instance, position3
|
local value = ref[readu8(b, position)]
|
||||||
|
if typeof(value) == "Instance" then
|
||||||
|
return value, position + 1
|
||||||
|
end
|
||||||
|
return nil, position + 1
|
||||||
elseif typeByte == -2 then -- array
|
elseif typeByte == -2 then -- array
|
||||||
local length = readu16(b, position)
|
local length = readu16(b, position)
|
||||||
position += 2
|
position += 2
|
||||||
local array = {}
|
local array = {}
|
||||||
for _ = 1, length do
|
for _ = 1, length do
|
||||||
local value
|
local value
|
||||||
value, position = readValue(b, position)
|
value, position = readValue(b, position, ref)
|
||||||
table.insert(array, value)
|
table.insert(array, value)
|
||||||
end
|
end
|
||||||
return array, position
|
return array, position
|
||||||
|
@ -49,8 +48,8 @@ local function readValue(b: buffer, position: number): (any, number)
|
||||||
local dict = {}
|
local dict = {}
|
||||||
for _ = 1, length do
|
for _ = 1, length do
|
||||||
local key, value
|
local key, value
|
||||||
key, position = readValue(b, position)
|
key, position = readValue(b, position, ref)
|
||||||
value, position = readValue(b, position)
|
value, position = readValue(b, position, ref)
|
||||||
dict[key] = value
|
dict[key] = value
|
||||||
end
|
end
|
||||||
return dict, position
|
return dict, position
|
||||||
|
@ -129,20 +128,21 @@ function Buffer.revert(s: string): buffer
|
||||||
return fromstring(s)
|
return fromstring(s)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Buffer.write(data: { any }): buffer
|
function Buffer.write(data: { any }): (buffer, (any)?)
|
||||||
local newBuffer = Dedicated()
|
local newBuffer = Dedicated()
|
||||||
newBuffer:pack(data)
|
newBuffer:pack(data)
|
||||||
return newBuffer:buildAndRemove()
|
return newBuffer:buildAndRemove()
|
||||||
end
|
end
|
||||||
|
|
||||||
function Buffer.read(b: buffer): any?
|
function Buffer.read(b: buffer, ref: { any }?): any?
|
||||||
local position = 0
|
local position = 0
|
||||||
local result = {}
|
local result = {}
|
||||||
while position < len(b) do
|
while position < len(b) do
|
||||||
local value
|
local value
|
||||||
value, position = readValue(b, position)
|
value, position = readValue(b, position, ref)
|
||||||
table.insert(result, value)
|
table.insert(result, value)
|
||||||
end
|
end
|
||||||
|
ref = nil
|
||||||
return table.unpack(result)
|
return table.unpack(result)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -4,21 +4,51 @@ local RateLimit = {}
|
||||||
|
|
||||||
local RunService = game:GetService("RunService")
|
local RunService = game:GetService("RunService")
|
||||||
local Assert = require(script.Parent.Assert)
|
local Assert = require(script.Parent.Assert)
|
||||||
local Event = require(script.Parent.Parent.Event).Reliable
|
local Events = require(script.Parent.Parent.Event)
|
||||||
|
local Reliable, Unreliable, Request = Events.Reliable, Events.Unreliable, Events.Request
|
||||||
|
local Signal = require(script.Parent.Parent.Signal)("Warp_OnSpamSignal")
|
||||||
|
|
||||||
|
local map, activity, meta = {}, {}, {}
|
||||||
|
setmetatable(meta , {
|
||||||
|
__index = map,
|
||||||
|
__newindex = function(self, key, value)
|
||||||
|
if not activity[key] then
|
||||||
|
activity[key] = os.clock()
|
||||||
|
end
|
||||||
|
if (os.clock()-activity[key]) >= 1 then
|
||||||
|
activity[key] = os.clock()
|
||||||
|
map[key] = 1
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if value >= 1e2 then -- 100
|
||||||
|
Signal:Fire(key)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
map[key] = value
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
local function onReceived(player: Player)
|
||||||
|
if not meta[player] then
|
||||||
|
meta[player] = 1
|
||||||
|
return
|
||||||
|
end
|
||||||
|
meta[player] += 1
|
||||||
|
end
|
||||||
|
|
||||||
function RateLimit.create(Identifier: string, entrance: number?, interval: number?)
|
function RateLimit.create(Identifier: string, entrance: number?, interval: number?)
|
||||||
Assert(typeof(Identifier) == "string", "Identifier must a string type.")
|
Assert(typeof(Identifier) == "string", "Identifier must a string type.")
|
||||||
if RunService:IsServer() then
|
if RunService:IsServer() then
|
||||||
Assert(typeof(entrance) == "number", "entrance must a number type.")
|
Assert(typeof(entrance) == "number", "entrance must a number type.")
|
||||||
Assert(entrance :: number > 0, "entrance must above 0.")
|
Assert(entrance :: number > 0, "entrance must above 0.")
|
||||||
Event:SetAttribute(Identifier.."_ent", entrance)
|
Reliable:SetAttribute(Identifier.."_ent", entrance)
|
||||||
Event:SetAttribute(Identifier.."_int", interval)
|
Reliable:SetAttribute(Identifier.."_int", interval)
|
||||||
else
|
else
|
||||||
while (not Event:GetAttribute(Identifier.."_ent")) or (not Event:GetAttribute(Identifier.."_int")) do
|
while (not Reliable:GetAttribute(Identifier.."_ent")) or (not Reliable:GetAttribute(Identifier.."_int")) do
|
||||||
task.wait(0.25)
|
task.wait(0.1)
|
||||||
end
|
end
|
||||||
entrance = tonumber(Event:GetAttribute(Identifier.."_ent"))
|
entrance = tonumber(Reliable:GetAttribute(Identifier.."_ent"))
|
||||||
interval = tonumber(Event:GetAttribute(Identifier.."_int"))
|
interval = tonumber(Reliable:GetAttribute(Identifier.."_int"))
|
||||||
end
|
end
|
||||||
local entrances: number = 0
|
local entrances: number = 0
|
||||||
return function(incoming: number?): boolean
|
return function(incoming: number?): boolean
|
||||||
|
@ -32,4 +62,14 @@ function RateLimit.create(Identifier: string, entrance: number?, interval: numbe
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function RateLimit.Protect()
|
||||||
|
if not RunService:IsServer() or Reliable:GetAttribute("Protected") or Unreliable:GetAttribute("Protected") or Request:GetAttribute("Protected") then return end
|
||||||
|
Reliable:SetAttribute("Protected", true)
|
||||||
|
Unreliable:SetAttribute("Protected", true)
|
||||||
|
Request:SetAttribute("Protected", true)
|
||||||
|
Reliable.OnServerEvent:Connect(onReceived)
|
||||||
|
Unreliable.OnServerEvent:Connect(onReceived)
|
||||||
|
Request.OnServerEvent:Connect(onReceived)
|
||||||
|
end
|
||||||
|
|
||||||
return RateLimit :: typeof(RateLimit)
|
return RateLimit :: typeof(RateLimit)
|
|
@ -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.25) do -- let it loop for yields!
|
while coroutine.status(cancel) ~= "dead" and task.wait(0.04) do -- let it loop for yields! 1/24
|
||||||
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))
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
-- Warp Library (@Eternity_Devs)
|
-- Warp Library (@Eternity_Devs)
|
||||||
-- version 1.0.13
|
-- version 1.0.14
|
||||||
--!strict
|
--!strict
|
||||||
--!native
|
--!native
|
||||||
--!optimize 2
|
--!optimize 2
|
||||||
|
@ -11,6 +11,8 @@ return {
|
||||||
fromServerArray = Index.fromServerArray,
|
fromServerArray = Index.fromServerArray,
|
||||||
fromClientArray = Index.fromClientArray,
|
fromClientArray = Index.fromClientArray,
|
||||||
|
|
||||||
|
OnSpamSignal = Index.OnSpamSignal,
|
||||||
|
|
||||||
Signal = Index.Signal,
|
Signal = Index.Signal,
|
||||||
fromSignalArray = Index.fromSignalArray,
|
fromSignalArray = Index.fromSignalArray,
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "imezx/warp"
|
name = "imezx/warp"
|
||||||
version = "1.0.13"
|
version = "1.0.14"
|
||||||
registry = "https://github.com/UpliftGames/wally-index"
|
registry = "https://github.com/UpliftGames/wally-index"
|
||||||
realm = "shared"
|
realm = "shared"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
Loading…
Reference in a new issue