Compare commits

...

6 commits

Author SHA1 Message Date
EternityDev
0b1304f4c5 v1.0.14 2024-12-02 14:37:46 +07:00
EternityDev
d8526c7e25 pre v1.0.14 2024-12-01 21:10:56 +07:00
EternityDev
d065bc2e50 oops 2024-11-30 23:55:07 +07:00
EternityDev
925df47d4c improvements 2024-11-30 23:49:37 +07:00
EternityDev
f3b674b377 rewrite buffer instance type serialization for fix issues 2024-11-23 19:51:14 +07:00
EternityDev
677d3fa675 rewrite buffer instance type serialization for fix issues 2024-11-23 19:50:06 +07:00
10 changed files with 128 additions and 55 deletions

BIN
Warp.rbxm

Binary file not shown.

View file

@ -230,20 +230,18 @@ function ClientProcess.start()
end
end
end)
local function onClientNetworkReceive(Identifier: buffer | string, data: buffer)
if not Identifier or not data then return end
Identifier = Buffer.convert(Identifier :: buffer)
local read = Buffer.read(data)
local function onClientNetworkReceive(Identifier: buffer | string, data: buffer, ref: { any }?)
if not Identifier or typeof(Identifier) ~= "buffer" or not data or typeof(data) ~= "buffer" then return end
Identifier = Buffer.convert(Identifier)
if not registeredIdentifier[Identifier :: string] then return end
local read = Buffer.read(data, ref)
if not read then return end
for idx: string in registeredIdentifier do
if idx ~= Identifier then continue end
local callback = clientCallback[idx] or nil
if not callback then continue end
local callback = clientCallback[Identifier :: string]
if not callback then return end
for _, fn: any in callback do
Spawn(fn, table.unpack(read))
end
end
end
ReliableEvent.OnClientEvent:Connect(onClientNetworkReceive)
UnreliableEvent.OnClientEvent:Connect(onClientNetworkReceive)
RequestEvent.OnClientEvent:Connect(function(Identifier: any, action: string, data)

View file

@ -49,12 +49,13 @@ local ReliableEvent = Event.Reliable
local UnreliableEvent = Event.Unreliable
local RequestEvent = Event.Request
RateLimit.Protect()
local function initializeEachPlayer(player: Player)
if not player then return end
if not queueOut[player] then
queueOut[player] = {}
end
for Identifier: string in registeredIdentifier do
if not player then break end
if not queueOut[player][Identifier] then
@ -84,6 +85,29 @@ local function initializeEachPlayer(player: Player)
end
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)
if not reliable then
@ -303,20 +327,18 @@ function ServerProcess.start()
end
end
end)
local function onServerNetworkReceive(player: Player, Identifier: buffer | string, data: buffer)
if not Identifier or not data then return end
local function onServerNetworkReceive(player: Player, Identifier: buffer | string, data: buffer, ref: { any }?)
if not Identifier or typeof(Identifier) ~= "buffer" or not data or typeof(data) ~= "buffer" then return end
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
for idx: string in registeredIdentifier do
if idx ~= Identifier then continue end
local callback = serverCallback[idx] or nil
if not callback then continue end
local callback = serverCallback[Identifier :: string]
if not callback then return end
for _, fn: any in callback do
Spawn(fn, player, table.unpack(read))
end
end
end
ReliableEvent.OnServerEvent:Connect(onServerNetworkReceive)
UnreliableEvent.OnServerEvent:Connect(onServerNetworkReceive)
RequestEvent.OnServerEvent:Connect(function(player: Player, Identifier: any, action: string, data: any)

View file

@ -36,7 +36,7 @@ function DedicatedBuffer.alloc(self: any, byte: number)
local b: buffer = self.buffer
while self.next + byte >= size do
size = math.floor(size * 1.2)
size = math.floor(size * 1.25) -- +25% increase
end
local newBuffer: buffer = create(size)
copy(newBuffer, 0, b)
@ -56,13 +56,15 @@ function DedicatedBuffer.build(self: any): buffer
return build
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 build: buffer = create(p)
local ref = #self.ref > 0 and table.clone(self.ref) or nil
copy(build, 0, self.buffer, 0, p)
self:remove()
return build
return build, ref
end
function DedicatedBuffer.wi8(self: any, val: number, alloc: number?)
@ -124,14 +126,21 @@ function DedicatedBuffer.wType(self: any, ref: number)
self.point += 1
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})
if typeof(data) == "nil" then
self:wi8(0)
elseif typeof(data) == "Instance" then
self:wi8(-1) -- Instance marker
self:pack(data.ClassName) -- Serialize ClassName
self:pack(data.Name) -- Serialize Name
self:pack(data:GetAttributes())
self:wRef(data)
elseif typeof(data) == "table" then
--local isArray = (next(data) ~= nil and #data > 0) and true or false
local isArray = true
@ -232,6 +241,7 @@ function DedicatedBuffer.flush(self: any)
self.next = default.next
self.size = default.size
self.buffer = create(default.bufferSize)
table.clear(self.ref)
end
function DedicatedBuffer.new()
@ -239,7 +249,8 @@ function DedicatedBuffer.new()
point = default.point,
next = default.next,
size = default.size,
buffer = create(default.bufferSize)
buffer = create(default.bufferSize),
ref = {},
}, DedicatedBuffer)
end

View file

@ -18,28 +18,27 @@ local readf64 = buffer.readf64
local readstring = buffer.readstring
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)
position += 1
if typeByte == 0 then -- nil
return nil, position
elseif typeByte == -1 then -- Instance
local className, position1 = readValue(b, position)
local name, position2 = readValue(b, position1)
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)
if not ref or #ref == 0 then
return nil, position + 1
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
local length = readu16(b, position)
position += 2
local array = {}
for _ = 1, length do
local value
value, position = readValue(b, position)
value, position = readValue(b, position, ref)
table.insert(array, value)
end
return array, position
@ -49,8 +48,8 @@ local function readValue(b: buffer, position: number): (any, number)
local dict = {}
for _ = 1, length do
local key, value
key, position = readValue(b, position)
value, position = readValue(b, position)
key, position = readValue(b, position, ref)
value, position = readValue(b, position, ref)
dict[key] = value
end
return dict, position
@ -129,20 +128,21 @@ function Buffer.revert(s: string): buffer
return fromstring(s)
end
function Buffer.write(data: { any }): buffer
function Buffer.write(data: { any }): (buffer, (any)?)
local newBuffer = Dedicated()
newBuffer:pack(data)
return newBuffer:buildAndRemove()
end
function Buffer.read(b: buffer): any?
function Buffer.read(b: buffer, ref: { any }?): any?
local position = 0
local result = {}
while position < len(b) do
local value
value, position = readValue(b, position)
value, position = readValue(b, position, ref)
table.insert(result, value)
end
ref = nil
return table.unpack(result)
end

View file

@ -4,21 +4,51 @@ local RateLimit = {}
local RunService = game:GetService("RunService")
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?)
Assert(typeof(Identifier) == "string", "Identifier must a string type.")
if RunService:IsServer() then
Assert(typeof(entrance) == "number", "entrance must a number type.")
Assert(entrance :: number > 0, "entrance must above 0.")
Event:SetAttribute(Identifier.."_ent", entrance)
Event:SetAttribute(Identifier.."_int", interval)
Reliable:SetAttribute(Identifier.."_ent", entrance)
Reliable:SetAttribute(Identifier.."_int", interval)
else
while (not Event:GetAttribute(Identifier.."_ent")) or (not Event:GetAttribute(Identifier.."_int")) do
task.wait(0.25)
while (not Reliable:GetAttribute(Identifier.."_ent")) or (not Reliable:GetAttribute(Identifier.."_int")) do
task.wait(0.1)
end
entrance = tonumber(Event:GetAttribute(Identifier.."_ent"))
interval = tonumber(Event:GetAttribute(Identifier.."_int"))
entrance = tonumber(Reliable:GetAttribute(Identifier.."_ent"))
interval = tonumber(Reliable:GetAttribute(Identifier.."_int"))
end
local entrances: number = 0
return function(incoming: number?): boolean
@ -32,4 +62,14 @@ function RateLimit.create(Identifier: string, entrance: number?, interval: numbe
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)

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)
end)
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
task.cancel(cancel)
task.spawn(yieldThread, Event:GetAttribute(Identifier))

View file

@ -1,5 +1,5 @@
-- Warp Library (@Eternity_Devs)
-- version 1.0.13
-- version 1.0.14
--!strict
--!native
--!optimize 2
@ -11,6 +11,8 @@ return {
fromServerArray = Index.fromServerArray,
fromClientArray = Index.fromClientArray,
OnSpamSignal = Index.OnSpamSignal,
Signal = Index.Signal,
fromSignalArray = Index.fromSignalArray,

View file

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