mirror of
				https://github.com/imezx/Warp.git
				synced 2025-11-03 19:49:16 +00:00 
			
		
		
		
	v1.0.13
This commit is contained in:
		
							parent
							
								
									a377788f22
								
							
						
					
					
						commit
						22996c9357
					
				
					 15 changed files with 242 additions and 294 deletions
				
			
		| 
						 | 
					@ -1,37 +0,0 @@
 | 
				
			||||||
--!strict
 | 
					 | 
				
			||||||
--!optimize 2
 | 
					 | 
				
			||||||
local Logger = {}
 | 
					 | 
				
			||||||
local Logs: {
 | 
					 | 
				
			||||||
	[string]: {
 | 
					 | 
				
			||||||
		[string]: string
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
} = {}
 | 
					 | 
				
			||||||
local logging: {
 | 
					 | 
				
			||||||
	[string]: boolean
 | 
					 | 
				
			||||||
} = {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
local now = tick()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function Logger.write(Identifier: string, text: string, log: boolean?)
 | 
					 | 
				
			||||||
	if not Logs[Identifier] then
 | 
					 | 
				
			||||||
		Logs[Identifier] = {}
 | 
					 | 
				
			||||||
	end
 | 
					 | 
				
			||||||
	if log ~= nil then
 | 
					 | 
				
			||||||
		logging[Identifier] = log
 | 
					 | 
				
			||||||
	end
 | 
					 | 
				
			||||||
	now = tick()
 | 
					 | 
				
			||||||
	Logs[Identifier][tostring(now)] = text
 | 
					 | 
				
			||||||
	if logging[Identifier] then
 | 
					 | 
				
			||||||
		print(`[{now}] ->`, text)
 | 
					 | 
				
			||||||
	end
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function Logger.read(Identifier: string)
 | 
					 | 
				
			||||||
	return Logs[Identifier]
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function Logger.clear(Identifier: string)
 | 
					 | 
				
			||||||
	Logs[Identifier] = nil
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
return Logger :: typeof(Logger)
 | 
					 | 
				
			||||||
| 
						 | 
					@ -12,18 +12,14 @@ local Spawn = require(Util.Spawn)
 | 
				
			||||||
local Key = require(Util.Key)
 | 
					local Key = require(Util.Key)
 | 
				
			||||||
local RateLimit = require(Util.RateLimit)
 | 
					local RateLimit = require(Util.RateLimit)
 | 
				
			||||||
local Buffer = require(Util.Buffer)
 | 
					local Buffer = require(Util.Buffer)
 | 
				
			||||||
local Logger = require(script.Logger)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
local clientRatelimit: Type.StoredRatelimit = {}
 | 
					local clientRatelimit: Type.StoredRatelimit = {}
 | 
				
			||||||
local clientQueue: Type.QueueMap = {}
 | 
					local clientQueue: Type.QueueMap = {}
 | 
				
			||||||
local unreliableClientQueue: Type.QueueMap = {}
 | 
					local unreliableClientQueue: Type.QueueMap = {}
 | 
				
			||||||
local clientCallback: Type.CallbackMap = {}
 | 
					local clientCallback: Type.CallbackMap = {}
 | 
				
			||||||
local clientRequestQueue: Type.QueueMap = {}
 | 
					local clientRequestQueue: Type.QueueMap = {}
 | 
				
			||||||
local registeredIdentifier: { string } = {}
 | 
					local registeredIdentifier: { [string]: boolean } = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
local queueIn: {
 | 
					 | 
				
			||||||
	[string]: {any}
 | 
					 | 
				
			||||||
} = {}
 | 
					 | 
				
			||||||
local queueInRequest: {
 | 
					local queueInRequest: {
 | 
				
			||||||
	[number]: {
 | 
						[number]: {
 | 
				
			||||||
		[string]: {
 | 
							[string]: {
 | 
				
			||||||
| 
						 | 
					@ -38,9 +34,6 @@ local queueOutRequest: {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
} = {}
 | 
					} = {}
 | 
				
			||||||
local logger: {
 | 
					 | 
				
			||||||
	[string]: boolean
 | 
					 | 
				
			||||||
} = {}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
queueInRequest[1] = {}
 | 
					queueInRequest[1] = {}
 | 
				
			||||||
queueInRequest[2] = {}
 | 
					queueInRequest[2] = {}
 | 
				
			||||||
| 
						 | 
					@ -82,12 +75,9 @@ function ClientProcess.insertRequest(Identifier: string, timeout: number, ...: a
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function ClientProcess.add(Identifier: any, originId: string, conf: Type.ClientConf)
 | 
					function ClientProcess.add(Identifier: any, originId: string, conf: Type.ClientConf)
 | 
				
			||||||
	if not table.find(registeredIdentifier, Identifier) then
 | 
						if not registeredIdentifier[Identifier] then
 | 
				
			||||||
		table.insert(registeredIdentifier, Identifier)
 | 
							registeredIdentifier[Identifier] = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if conf.logging then
 | 
					 | 
				
			||||||
			ClientProcess.logger(Identifier, conf.logging.store, conf.logging.opt)
 | 
					 | 
				
			||||||
		end
 | 
					 | 
				
			||||||
		if not clientRatelimit[Identifier] then
 | 
							if not clientRatelimit[Identifier] then
 | 
				
			||||||
			clientRatelimit[Identifier] = RateLimit.create(originId)
 | 
								clientRatelimit[Identifier] = RateLimit.create(originId)
 | 
				
			||||||
		end
 | 
							end
 | 
				
			||||||
| 
						 | 
					@ -116,15 +106,12 @@ function ClientProcess.add(Identifier: any, originId: string, conf: Type.ClientC
 | 
				
			||||||
		if not queueInRequest[2][Identifier] then
 | 
							if not queueInRequest[2][Identifier] then
 | 
				
			||||||
			queueInRequest[2][Identifier] = {}
 | 
								queueInRequest[2][Identifier] = {}
 | 
				
			||||||
		end
 | 
							end
 | 
				
			||||||
		if not queueIn[Identifier] then
 | 
					 | 
				
			||||||
			queueIn[Identifier] = {}
 | 
					 | 
				
			||||||
		end
 | 
					 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function ClientProcess.remove(Identifier: string)
 | 
					function ClientProcess.remove(Identifier: string)
 | 
				
			||||||
	if not table.find(registeredIdentifier, Identifier) then return end
 | 
						if not registeredIdentifier[Identifier] then return end
 | 
				
			||||||
	table.remove(registeredIdentifier, table.find(registeredIdentifier, Identifier))
 | 
						registeredIdentifier[Identifier] = nil
 | 
				
			||||||
	clientQueue[Identifier] = nil
 | 
						clientQueue[Identifier] = nil
 | 
				
			||||||
	unreliableClientQueue[Identifier] = nil
 | 
						unreliableClientQueue[Identifier] = nil
 | 
				
			||||||
	clientRequestQueue[Identifier] = nil
 | 
						clientRequestQueue[Identifier] = nil
 | 
				
			||||||
| 
						 | 
					@ -134,31 +121,14 @@ function ClientProcess.remove(Identifier: string)
 | 
				
			||||||
	queueOutRequest[2][Identifier] = nil
 | 
						queueOutRequest[2][Identifier] = nil
 | 
				
			||||||
	queueInRequest[1][Identifier] = nil
 | 
						queueInRequest[1][Identifier] = nil
 | 
				
			||||||
	queueInRequest[2][Identifier] = nil
 | 
						queueInRequest[2][Identifier] = nil
 | 
				
			||||||
	queueIn[Identifier] = nil
 | 
					 | 
				
			||||||
	Logger.clear(Identifier)
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function ClientProcess.logger(Identifier: string, store: boolean, log: boolean)
 | 
					 | 
				
			||||||
	logger[Identifier] = store
 | 
					 | 
				
			||||||
	Logger.write(Identifier, `state: change -> {log == true and "enabled" or "disabled"} logger.`, log)
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function ClientProcess.getlogs(Identifier: string)
 | 
					 | 
				
			||||||
	return Logger.read(Identifier)
 | 
					 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function ClientProcess.addCallback(Identifier: string, key: string, callback)
 | 
					function ClientProcess.addCallback(Identifier: string, key: string, callback)
 | 
				
			||||||
	clientCallback[Identifier][key] = callback
 | 
						clientCallback[Identifier][key] = callback
 | 
				
			||||||
	if logger[Identifier] then
 | 
					 | 
				
			||||||
		task.defer(Logger.write, Identifier, `state: change -> new callback added.`)
 | 
					 | 
				
			||||||
	end
 | 
					 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function ClientProcess.removeCallback(Identifier: string, key: string)
 | 
					function ClientProcess.removeCallback(Identifier: string, key: string)
 | 
				
			||||||
	clientCallback[Identifier][key] = nil
 | 
						clientCallback[Identifier][key] = nil
 | 
				
			||||||
	if logger[Identifier] then
 | 
					 | 
				
			||||||
		task.defer(Logger.write, Identifier, `state: change -> removed a callback.`)
 | 
					 | 
				
			||||||
	end
 | 
					 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function ClientProcess.start()
 | 
					function ClientProcess.start()
 | 
				
			||||||
| 
						 | 
					@ -168,9 +138,8 @@ function ClientProcess.start()
 | 
				
			||||||
		for Identifier: string, data: any in unreliableClientQueue do
 | 
							for Identifier: string, data: any in unreliableClientQueue do
 | 
				
			||||||
			if #data == 0 then continue end
 | 
								if #data == 0 then continue end
 | 
				
			||||||
			if clientRatelimit[Identifier](#data) then
 | 
								if clientRatelimit[Identifier](#data) then
 | 
				
			||||||
				UnreliableEvent:FireServer(Buffer.revert(Identifier), data)
 | 
									for _, unpacked in data do
 | 
				
			||||||
				if logger[Identifier] then
 | 
										UnreliableEvent:FireServer(Buffer.write(unpacked))
 | 
				
			||||||
					task.defer(Logger.write, Identifier, `state: out -> unreliable -> {#data} data.`)
 | 
					 | 
				
			||||||
				end
 | 
									end
 | 
				
			||||||
			end
 | 
								end
 | 
				
			||||||
			unreliableClientQueue[Identifier] = nil
 | 
								unreliableClientQueue[Identifier] = nil
 | 
				
			||||||
| 
						 | 
					@ -179,9 +148,8 @@ function ClientProcess.start()
 | 
				
			||||||
		for Identifier: string, data: any in clientQueue do
 | 
							for Identifier: string, data: any in clientQueue do
 | 
				
			||||||
			if #data > 0 then
 | 
								if #data > 0 then
 | 
				
			||||||
				if clientRatelimit[Identifier](#data) then
 | 
									if clientRatelimit[Identifier](#data) then
 | 
				
			||||||
					ReliableEvent:FireServer(Buffer.revert(Identifier), data)
 | 
										for _, unpacked in data do
 | 
				
			||||||
					if logger[Identifier] then
 | 
											ReliableEvent:FireServer(Buffer.write(unpacked))
 | 
				
			||||||
						task.defer(Logger.write, Identifier, `state: out -> reliable -> {#data} data.`)
 | 
					 | 
				
			||||||
					end
 | 
										end
 | 
				
			||||||
				end
 | 
									end
 | 
				
			||||||
				clientQueue[Identifier] = nil
 | 
									clientQueue[Identifier] = nil
 | 
				
			||||||
| 
						 | 
					@ -191,22 +159,16 @@ function ClientProcess.start()
 | 
				
			||||||
		for Identifier: string, requestsData in queueOutRequest[1] do
 | 
							for Identifier: string, requestsData in queueOutRequest[1] do
 | 
				
			||||||
			if #requestsData == 0 then continue end
 | 
								if #requestsData == 0 then continue end
 | 
				
			||||||
			RequestEvent:FireServer(Buffer.revert(Identifier), "\1", requestsData)
 | 
								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
 | 
								queueOutRequest[1][Identifier] = nil
 | 
				
			||||||
		end
 | 
							end
 | 
				
			||||||
		-- Sent returning invokes
 | 
							-- Sent returning invokes
 | 
				
			||||||
		for Identifier: string, toReturnDatas in queueOutRequest[2] do
 | 
							for Identifier: string, toReturnDatas in queueOutRequest[2] do
 | 
				
			||||||
			if #toReturnDatas == 0 then continue end
 | 
								if #toReturnDatas == 0 then continue end
 | 
				
			||||||
			RequestEvent:FireServer(Buffer.revert(Identifier), "\0", toReturnDatas)
 | 
								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
 | 
								queueOutRequest[2][Identifier] = nil
 | 
				
			||||||
		end
 | 
							end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for _, Identifier: string in registeredIdentifier do
 | 
							for Identifier: string in registeredIdentifier do
 | 
				
			||||||
			if clientRequestQueue[Identifier] then
 | 
								if clientRequestQueue[Identifier] then
 | 
				
			||||||
				for _, requestData in clientRequestQueue[Identifier] do
 | 
									for _, requestData in clientRequestQueue[Identifier] do
 | 
				
			||||||
					if not requestData[3] then continue end
 | 
										if not requestData[3] then continue end
 | 
				
			||||||
| 
						 | 
					@ -222,18 +184,6 @@ function ClientProcess.start()
 | 
				
			||||||
			local callback = clientCallback[Identifier] or nil
 | 
								local callback = clientCallback[Identifier] or nil
 | 
				
			||||||
			if not callback then continue end
 | 
								if not callback then continue end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if queueIn[Identifier] then
 | 
					 | 
				
			||||||
				for _, packedDatas: any in queueIn[Identifier] do
 | 
					 | 
				
			||||||
					if #packedDatas == 0 then continue end
 | 
					 | 
				
			||||||
					for _, fn: any in callback do
 | 
					 | 
				
			||||||
						for i=1,#packedDatas do
 | 
					 | 
				
			||||||
							Spawn(fn, table.unpack(packedDatas[i] or {}))
 | 
					 | 
				
			||||||
						end
 | 
					 | 
				
			||||||
					end
 | 
					 | 
				
			||||||
				end
 | 
					 | 
				
			||||||
				queueIn[Identifier] = nil
 | 
					 | 
				
			||||||
			end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			-- Return Invoke
 | 
								-- Return Invoke
 | 
				
			||||||
			if queueInRequest[1][Identifier] then
 | 
								if queueInRequest[1][Identifier] then
 | 
				
			||||||
				for _, packetDatas: any in queueInRequest[1][Identifier] do
 | 
									for _, packetDatas: any in queueInRequest[1][Identifier] do
 | 
				
			||||||
| 
						 | 
					@ -280,15 +230,16 @@ function ClientProcess.start()
 | 
				
			||||||
			end
 | 
								end
 | 
				
			||||||
		end
 | 
							end
 | 
				
			||||||
	end)
 | 
						end)
 | 
				
			||||||
	local function onClientNetworkReceive(Identifier: any, data: any)
 | 
						local function onClientNetworkReceive(data: buffer)
 | 
				
			||||||
		if not Identifier or not data then return end
 | 
							if not data then return end
 | 
				
			||||||
		Identifier = Buffer.convert(Identifier)
 | 
							local read = Buffer.read(data)
 | 
				
			||||||
		if not queueIn[Identifier] then
 | 
							if not read then return end
 | 
				
			||||||
			queueIn[Identifier] = {}
 | 
							for Identifier: string in registeredIdentifier do
 | 
				
			||||||
 | 
								local callback = clientCallback[Identifier] or nil
 | 
				
			||||||
 | 
								if not callback then continue end
 | 
				
			||||||
 | 
								for _, fn: any in callback do
 | 
				
			||||||
 | 
									Spawn(fn, table.unpack(read))
 | 
				
			||||||
			end
 | 
								end
 | 
				
			||||||
		table.insert(queueIn[Identifier], data)
 | 
					 | 
				
			||||||
		if logger[Identifier] then
 | 
					 | 
				
			||||||
			task.defer(Logger.write, Identifier, `state: in -> net -> {#data} data.`)
 | 
					 | 
				
			||||||
		end
 | 
							end
 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
	ReliableEvent.OnClientEvent:Connect(onClientNetworkReceive)
 | 
						ReliableEvent.OnClientEvent:Connect(onClientNetworkReceive)
 | 
				
			||||||
| 
						 | 
					@ -307,9 +258,6 @@ function ClientProcess.start()
 | 
				
			||||||
			end
 | 
								end
 | 
				
			||||||
			table.insert(queueInRequest[2][Identifier], data)
 | 
								table.insert(queueInRequest[2][Identifier], data)
 | 
				
			||||||
		end
 | 
							end
 | 
				
			||||||
		if logger[Identifier] then
 | 
					 | 
				
			||||||
			task.defer(Logger.write, Identifier, `state: in -> request -> {#data} data.`)
 | 
					 | 
				
			||||||
		end
 | 
					 | 
				
			||||||
	end)
 | 
						end)
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,17 +24,12 @@ function Client.new(Identifier: string, conf: Type.ClientConf?)
 | 
				
			||||||
	self._conf = table.freeze(conf or {})
 | 
						self._conf = table.freeze(conf or {})
 | 
				
			||||||
	self.IsConnected = false
 | 
						self.IsConnected = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ClientProcess.add(self.id, Identifier, conf or { yieldWait = 10, logging = { store = false, opt = false } })
 | 
						ClientProcess.add(self.id, Identifier, conf or { yieldWait = 10 })
 | 
				
			||||||
	self._buffer:remove()
 | 
						self._buffer:remove()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return self
 | 
						return self
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function Client:logs()
 | 
					 | 
				
			||||||
	Assert(self._conf.logging, "[Client]: Event is not configured with logging.")
 | 
					 | 
				
			||||||
	return ClientProcess.getlogs(self.id)
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function Client:Fire(reliable: boolean,...: any)
 | 
					function Client:Fire(reliable: boolean,...: any)
 | 
				
			||||||
	ClientProcess.insertQueue(self.id, reliable, ...)
 | 
						ClientProcess.insertQueue(self.id, reliable, ...)
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,11 +30,6 @@ function Server.new(Identifier: string, conf: Type.ServerConf?)
 | 
				
			||||||
	return self
 | 
						return self
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function Server:logs()
 | 
					 | 
				
			||||||
	Assert(self._conf.logging, "[Server]: Event is not configured with logging.")
 | 
					 | 
				
			||||||
	return ServerProcess.getlogs(self.id)
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function Server:Fire(reliable: boolean, player: Player, ...: any)
 | 
					function Server:Fire(reliable: boolean, player: Player, ...: any)
 | 
				
			||||||
	ServerProcess.insertQueue(self.id, reliable, player, ...)
 | 
						ServerProcess.insertQueue(self.id, reliable, player, ...)
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,37 +0,0 @@
 | 
				
			||||||
--!strict
 | 
					 | 
				
			||||||
--!optimize 2
 | 
					 | 
				
			||||||
local Logger = {}
 | 
					 | 
				
			||||||
local Logs: {
 | 
					 | 
				
			||||||
	[string]: {
 | 
					 | 
				
			||||||
		[string]: string
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
} = {}
 | 
					 | 
				
			||||||
local logging: {
 | 
					 | 
				
			||||||
	[string]: boolean
 | 
					 | 
				
			||||||
} = {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
local now = tick()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function Logger.write(Identifier: string, text: string, log: boolean?)
 | 
					 | 
				
			||||||
	if not Logs[Identifier] then
 | 
					 | 
				
			||||||
		Logs[Identifier] = {}
 | 
					 | 
				
			||||||
	end
 | 
					 | 
				
			||||||
	if log ~= nil then
 | 
					 | 
				
			||||||
		logging[Identifier] = log
 | 
					 | 
				
			||||||
	end
 | 
					 | 
				
			||||||
	now = tick()
 | 
					 | 
				
			||||||
	Logs[Identifier][tostring(now)] = text
 | 
					 | 
				
			||||||
	if logging[Identifier] then
 | 
					 | 
				
			||||||
		print(`[{now}] ->`, text)
 | 
					 | 
				
			||||||
	end
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function Logger.read(Identifier: string)
 | 
					 | 
				
			||||||
	return Logs[Identifier]
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function Logger.clear(Identifier: string)
 | 
					 | 
				
			||||||
	Logs[Identifier] = nil
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
return Logger :: typeof(Logger)
 | 
					 | 
				
			||||||
| 
						 | 
					@ -13,24 +13,18 @@ local Spawn = require(Util.Spawn)
 | 
				
			||||||
local Key = require(Util.Key)
 | 
					local Key = require(Util.Key)
 | 
				
			||||||
local RateLimit = require(Util.RateLimit)
 | 
					local RateLimit = require(Util.RateLimit)
 | 
				
			||||||
local Buffer = require(Util.Buffer)
 | 
					local Buffer = require(Util.Buffer)
 | 
				
			||||||
local Logger = require(script.Logger)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
local serverQueue: Type.QueueMap = {}
 | 
					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 registeredIdentifier: { [string]: boolean } = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
local queueOut: {
 | 
					local queueOut: {
 | 
				
			||||||
	[Player]: {
 | 
						[Player]: {
 | 
				
			||||||
		[string]: {any},
 | 
							[string]: {any},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
} = {}
 | 
					} = {}
 | 
				
			||||||
local queueIn: {
 | 
					 | 
				
			||||||
	[string]: {
 | 
					 | 
				
			||||||
		[Player]: {any},
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
} = {}
 | 
					 | 
				
			||||||
local queueInRequest: {
 | 
					local queueInRequest: {
 | 
				
			||||||
	[number]: {
 | 
						[number]: {
 | 
				
			||||||
		[string]: {
 | 
							[string]: {
 | 
				
			||||||
| 
						 | 
					@ -45,12 +39,6 @@ local queueOutRequest: {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
} = {}
 | 
					} = {}
 | 
				
			||||||
local logger: {
 | 
					 | 
				
			||||||
	[string]: boolean
 | 
					 | 
				
			||||||
} = {}
 | 
					 | 
				
			||||||
local players: {
 | 
					 | 
				
			||||||
	Player
 | 
					 | 
				
			||||||
} = {}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
queueInRequest[1] = {}
 | 
					queueInRequest[1] = {}
 | 
				
			||||||
queueInRequest[2] = {}
 | 
					queueInRequest[2] = {}
 | 
				
			||||||
| 
						 | 
					@ -78,9 +66,6 @@ local function initializeEachPlayer(player: Player)
 | 
				
			||||||
		if not serverRequestQueue[Identifier][player] then
 | 
							if not serverRequestQueue[Identifier][player] then
 | 
				
			||||||
			serverRequestQueue[Identifier][player] = {}
 | 
								serverRequestQueue[Identifier][player] = {}
 | 
				
			||||||
		end
 | 
							end
 | 
				
			||||||
		if not queueIn[Identifier][player] then
 | 
					 | 
				
			||||||
			queueIn[Identifier][player] = {}
 | 
					 | 
				
			||||||
		end
 | 
					 | 
				
			||||||
		if not queueOutRequest[1][Identifier] then
 | 
							if not queueOutRequest[1][Identifier] then
 | 
				
			||||||
			queueOutRequest[1][Identifier] = {}
 | 
								queueOutRequest[1][Identifier] = {}
 | 
				
			||||||
		end
 | 
							end
 | 
				
			||||||
| 
						 | 
					@ -140,14 +125,11 @@ 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 table.find(registeredIdentifier, Identifier) then
 | 
						if not registeredIdentifier[Identifier] then
 | 
				
			||||||
		table.insert(registeredIdentifier, Identifier)
 | 
							registeredIdentifier[Identifier] = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		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
 | 
					 | 
				
			||||||
			ServerProcess.logger(Identifier, conf.logging.store, conf.logging.opt)
 | 
					 | 
				
			||||||
		end
 | 
					 | 
				
			||||||
		if not serverQueue[Identifier] then
 | 
							if not serverQueue[Identifier] then
 | 
				
			||||||
			serverQueue[Identifier] = {}
 | 
								serverQueue[Identifier] = {}
 | 
				
			||||||
		end
 | 
							end
 | 
				
			||||||
| 
						 | 
					@ -161,9 +143,6 @@ function ServerProcess.add(Identifier: string, originId: string, conf: Type.Serv
 | 
				
			||||||
			unreliableServerQueue[Identifier] = {}
 | 
								unreliableServerQueue[Identifier] = {}
 | 
				
			||||||
		end
 | 
							end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if not queueIn[Identifier] then
 | 
					 | 
				
			||||||
			queueIn[Identifier] = {}
 | 
					 | 
				
			||||||
		end
 | 
					 | 
				
			||||||
		if not queueInRequest[1][Identifier] then
 | 
							if not queueInRequest[1][Identifier] then
 | 
				
			||||||
			queueInRequest[1][Identifier] = {}
 | 
								queueInRequest[1][Identifier] = {}
 | 
				
			||||||
		end
 | 
							end
 | 
				
			||||||
| 
						 | 
					@ -184,41 +163,24 @@ function ServerProcess.add(Identifier: string, originId: string, conf: Type.Serv
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function ServerProcess.remove(Identifier: string)
 | 
					function ServerProcess.remove(Identifier: string)
 | 
				
			||||||
	if not table.find(registeredIdentifier, Identifier) then return end
 | 
						if not registeredIdentifier[Identifier] then return end
 | 
				
			||||||
	table.remove(registeredIdentifier, table.find(registeredIdentifier, Identifier))
 | 
						registeredIdentifier[Identifier] = nil
 | 
				
			||||||
	serverQueue[Identifier] = nil
 | 
						serverQueue[Identifier] = nil
 | 
				
			||||||
	serverRequestQueue[Identifier] = nil
 | 
						serverRequestQueue[Identifier] = nil
 | 
				
			||||||
	serverCallback[Identifier] = nil
 | 
						serverCallback[Identifier] = nil
 | 
				
			||||||
	unreliableServerQueue[Identifier] = nil
 | 
						unreliableServerQueue[Identifier] = nil
 | 
				
			||||||
	queueIn[Identifier] = nil
 | 
					 | 
				
			||||||
	queueInRequest[1][Identifier] = nil
 | 
						queueInRequest[1][Identifier] = nil
 | 
				
			||||||
	queueInRequest[2][Identifier] = nil
 | 
						queueInRequest[2][Identifier] = nil
 | 
				
			||||||
	queueOutRequest[1][Identifier] = nil
 | 
						queueOutRequest[1][Identifier] = nil
 | 
				
			||||||
	queueOutRequest[2][Identifier] = nil
 | 
						queueOutRequest[2][Identifier] = nil
 | 
				
			||||||
	Logger.clear(Identifier)
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function ServerProcess.logger(Identifier: string, store: boolean, log: boolean)
 | 
					 | 
				
			||||||
	logger[Identifier] = store
 | 
					 | 
				
			||||||
	Logger.write(Identifier, `state: change -> {log == true and "enabled" or "disabled"} logger.`, log)
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function ServerProcess.getlogs(Identifier: string)
 | 
					 | 
				
			||||||
	return Logger.read(Identifier)
 | 
					 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function ServerProcess.addCallback(Identifier: string, key: string, callback)
 | 
					function ServerProcess.addCallback(Identifier: string, key: string, callback)
 | 
				
			||||||
	serverCallback[Identifier][key] = callback
 | 
						serverCallback[Identifier][key] = callback
 | 
				
			||||||
	if logger[Identifier] then
 | 
					 | 
				
			||||||
		task.defer(Logger.write, Identifier, `state: change -> new callback added.`)
 | 
					 | 
				
			||||||
	end
 | 
					 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function ServerProcess.removeCallback(Identifier: string, key: string)
 | 
					function ServerProcess.removeCallback(Identifier: string, key: string)
 | 
				
			||||||
	serverCallback[Identifier][key] = nil
 | 
						serverCallback[Identifier][key] = nil
 | 
				
			||||||
	if logger[Identifier] then
 | 
					 | 
				
			||||||
		task.defer(Logger.write, Identifier, `state: change -> removed a callback.`)
 | 
					 | 
				
			||||||
	end
 | 
					 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function ServerProcess.start()
 | 
					function ServerProcess.start()
 | 
				
			||||||
| 
						 | 
					@ -228,9 +190,8 @@ function ServerProcess.start()
 | 
				
			||||||
		for Identifier: string, players in unreliableServerQueue do
 | 
							for Identifier: string, players in unreliableServerQueue do
 | 
				
			||||||
			for player: Player, content: any in players do
 | 
								for player: Player, content: any in players do
 | 
				
			||||||
				if #content == 0 then continue end
 | 
									if #content == 0 then continue end
 | 
				
			||||||
				UnreliableEvent:FireClient(player, Buffer.revert(Identifier), content)
 | 
									for _, unpacked in content do
 | 
				
			||||||
				if logger[Identifier] then
 | 
										UnreliableEvent:FireClient(player, Buffer.write(unpacked))
 | 
				
			||||||
					task.defer(Logger.write, Identifier, `state: out -> unreliable -> {#content} data.`)
 | 
					 | 
				
			||||||
				end
 | 
									end
 | 
				
			||||||
				unreliableServerQueue[Identifier][player] = nil
 | 
									unreliableServerQueue[Identifier][player] = nil
 | 
				
			||||||
			end
 | 
								end
 | 
				
			||||||
| 
						 | 
					@ -240,7 +201,9 @@ function ServerProcess.start()
 | 
				
			||||||
		for Identifier: string, contents: { [Player]: { any } } in serverQueue do
 | 
							for Identifier: string, contents: { [Player]: { any } } in serverQueue do
 | 
				
			||||||
			for player, content: any in contents do
 | 
								for player, content: any in contents do
 | 
				
			||||||
				if #content > 0 and queueOut[player] then
 | 
									if #content > 0 and queueOut[player] then
 | 
				
			||||||
					ReliableEvent:FireClient(player, Buffer.revert(Identifier), content)
 | 
										for _, unpacked in content do
 | 
				
			||||||
 | 
											ReliableEvent:FireClient(player, Buffer.write(unpacked))
 | 
				
			||||||
 | 
										end
 | 
				
			||||||
				end
 | 
									end
 | 
				
			||||||
				serverQueue[Identifier][player] = nil
 | 
									serverQueue[Identifier][player] = nil
 | 
				
			||||||
			end
 | 
								end
 | 
				
			||||||
| 
						 | 
					@ -251,9 +214,6 @@ function ServerProcess.start()
 | 
				
			||||||
			for player: Player, requestsData: any in contents do
 | 
								for player: Player, requestsData: any in contents do
 | 
				
			||||||
				if #requestsData > 0 then
 | 
									if #requestsData > 0 then
 | 
				
			||||||
					RequestEvent:FireClient(player, Buffer.revert(Identifier), "\1", requestsData)
 | 
										RequestEvent:FireClient(player, Buffer.revert(Identifier), "\1", requestsData)
 | 
				
			||||||
					if logger[Identifier] then
 | 
					 | 
				
			||||||
						task.defer(Logger.write, Identifier, `state: out -> request -> {#requestsData} data.`)
 | 
					 | 
				
			||||||
					end
 | 
					 | 
				
			||||||
				end
 | 
									end
 | 
				
			||||||
				queueOutRequest[1][Identifier][player] = nil
 | 
									queueOutRequest[1][Identifier][player] = nil
 | 
				
			||||||
			end
 | 
								end
 | 
				
			||||||
| 
						 | 
					@ -264,16 +224,13 @@ function ServerProcess.start()
 | 
				
			||||||
			for player: Player, toReturnDatas: any in contents do
 | 
								for player: Player, toReturnDatas: any in contents do
 | 
				
			||||||
				if #toReturnDatas > 0 then
 | 
									if #toReturnDatas > 0 then
 | 
				
			||||||
					RequestEvent:FireClient(player, Buffer.revert(Identifier), "\0", toReturnDatas)
 | 
										RequestEvent:FireClient(player, Buffer.revert(Identifier), "\0", toReturnDatas)
 | 
				
			||||||
					if logger[Identifier] then
 | 
					 | 
				
			||||||
						task.defer(Logger.write, Identifier, `state: out -> return request -> {#toReturnDatas} data.`)
 | 
					 | 
				
			||||||
					end
 | 
					 | 
				
			||||||
				end
 | 
									end
 | 
				
			||||||
				queueOutRequest[2][Identifier][player] = nil
 | 
									queueOutRequest[2][Identifier][player] = nil
 | 
				
			||||||
			end
 | 
								end
 | 
				
			||||||
			queueOutRequest[2][Identifier] = nil
 | 
								queueOutRequest[2][Identifier] = nil
 | 
				
			||||||
		end
 | 
							end
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		for _, Identifier: string in registeredIdentifier do
 | 
							for Identifier: string in registeredIdentifier do
 | 
				
			||||||
			if serverRequestQueue[Identifier] then
 | 
								if serverRequestQueue[Identifier] then
 | 
				
			||||||
				for player, content in serverRequestQueue[Identifier] do
 | 
									for player, content in serverRequestQueue[Identifier] do
 | 
				
			||||||
					if #content == 0 then serverRequestQueue[Identifier][player] = nil continue end
 | 
										if #content == 0 then serverRequestQueue[Identifier][player] = nil continue end
 | 
				
			||||||
| 
						 | 
					@ -294,21 +251,6 @@ function ServerProcess.start()
 | 
				
			||||||
			local callback = serverCallback[Identifier] or nil
 | 
								local callback = serverCallback[Identifier] or nil
 | 
				
			||||||
			if not callback then continue end
 | 
								if not callback 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,#incoming do
 | 
					 | 
				
			||||||
							Spawn(fn, player, table.unpack(incoming[i] or {}))
 | 
					 | 
				
			||||||
						end
 | 
					 | 
				
			||||||
					end
 | 
					 | 
				
			||||||
				end
 | 
					 | 
				
			||||||
				queueIn[Identifier][player] = nil
 | 
					 | 
				
			||||||
			end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			-- Return Invoke
 | 
								-- Return Invoke
 | 
				
			||||||
			for player, content in queueInRequest[1][Identifier] do
 | 
								for player, content in queueInRequest[1][Identifier] do
 | 
				
			||||||
				if not callback then break end
 | 
									if not callback then break end
 | 
				
			||||||
| 
						 | 
					@ -361,22 +303,17 @@ function ServerProcess.start()
 | 
				
			||||||
			end
 | 
								end
 | 
				
			||||||
		end
 | 
							end
 | 
				
			||||||
	end)
 | 
						end)
 | 
				
			||||||
	local function onServerNetworkReceive(player: Player, Identifier: any, data: any)
 | 
						local function onServerNetworkReceive(player: Player, data: buffer)
 | 
				
			||||||
		if not Identifier or not data then return end
 | 
							if not data then return end
 | 
				
			||||||
		Identifier = Buffer.convert(Identifier)
 | 
							local read = Buffer.read(data)
 | 
				
			||||||
		if not serverQueue[Identifier] then
 | 
							if not read then return end
 | 
				
			||||||
			serverQueue[Identifier] = {}
 | 
							for Identifier: string in registeredIdentifier do
 | 
				
			||||||
 | 
								local callback = serverCallback[Identifier] or nil
 | 
				
			||||||
 | 
								if not callback then continue end
 | 
				
			||||||
 | 
								for _, fn: any in callback do
 | 
				
			||||||
 | 
									Spawn(fn, player, table.unpack(read))
 | 
				
			||||||
			end
 | 
								end
 | 
				
			||||||
		if not serverQueue[Identifier][player] then
 | 
					 | 
				
			||||||
			serverQueue[Identifier][player] = {}
 | 
					 | 
				
			||||||
		end
 | 
							end
 | 
				
			||||||
		if not queueIn[Identifier][player] then
 | 
					 | 
				
			||||||
			queueIn[Identifier][player] = {}
 | 
					 | 
				
			||||||
		end
 | 
					 | 
				
			||||||
		if logger[Identifier] then
 | 
					 | 
				
			||||||
			task.defer(Logger.write, Identifier, `state: in -> net -> {#data} data.`)
 | 
					 | 
				
			||||||
		end
 | 
					 | 
				
			||||||
		table.insert(queueIn[Identifier][player], data)
 | 
					 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
	ReliableEvent.OnServerEvent:Connect(onServerNetworkReceive)
 | 
						ReliableEvent.OnServerEvent:Connect(onServerNetworkReceive)
 | 
				
			||||||
	UnreliableEvent.OnServerEvent:Connect(onServerNetworkReceive)
 | 
						UnreliableEvent.OnServerEvent:Connect(onServerNetworkReceive)
 | 
				
			||||||
| 
						 | 
					@ -400,9 +337,6 @@ function ServerProcess.start()
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			table.insert(queueInRequest[2][Identifier][player], data)
 | 
								table.insert(queueInRequest[2][Identifier][player], data)
 | 
				
			||||||
		end
 | 
							end
 | 
				
			||||||
		if logger[Identifier] then
 | 
					 | 
				
			||||||
			task.defer(Logger.write, Identifier, `state: in -> request -> {#data} data.`)
 | 
					 | 
				
			||||||
		end
 | 
					 | 
				
			||||||
	end)
 | 
						end)
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,7 +3,6 @@
 | 
				
			||||||
--!optimize 2
 | 
					--!optimize 2
 | 
				
			||||||
local Signal = {}
 | 
					local Signal = {}
 | 
				
			||||||
Signal.__index = Signal
 | 
					Signal.__index = Signal
 | 
				
			||||||
Signal.ClassName = "Signal"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
local DedicatedSignal = require(script.Dedicated)
 | 
					local DedicatedSignal = require(script.Dedicated)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,19 +4,12 @@ type rateLimitArg = {
 | 
				
			||||||
	interval: number?,
 | 
						interval: number?,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type logging = {
 | 
					 | 
				
			||||||
	store: boolean,
 | 
					 | 
				
			||||||
	opt: boolean,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export type ServerConf = {
 | 
					export type ServerConf = {
 | 
				
			||||||
	rateLimit: rateLimitArg?,
 | 
						rateLimit: rateLimitArg?,
 | 
				
			||||||
	logging: logging?,
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type ClientConf = {
 | 
					export type ClientConf = {
 | 
				
			||||||
	yieldWait: number?,
 | 
						yieldWait: number?,
 | 
				
			||||||
	logging: logging?,
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type Middleware = {
 | 
					export type Middleware = {
 | 
				
			||||||
| 
						 | 
					@ -34,7 +27,6 @@ export type Client = {
 | 
				
			||||||
	DisconnectAll: (self: Client) -> (),
 | 
						DisconnectAll: (self: Client) -> (),
 | 
				
			||||||
	Wait: (self: Client) -> number,
 | 
						Wait: (self: Client) -> number,
 | 
				
			||||||
	Destroy: (self: Client) -> (),
 | 
						Destroy: (self: Client) -> (),
 | 
				
			||||||
	logs: (self: Client) -> any,
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type Server = {
 | 
					export type Server = {
 | 
				
			||||||
| 
						 | 
					@ -47,7 +39,6 @@ export type Server = {
 | 
				
			||||||
	DisconnectAll: (self: Server) -> (),
 | 
						DisconnectAll: (self: Server) -> (),
 | 
				
			||||||
	Wait: (self: Server) -> number,
 | 
						Wait: (self: Server) -> number,
 | 
				
			||||||
	Destroy: (self: Server) -> (),
 | 
						Destroy: (self: Server) -> (),
 | 
				
			||||||
	logs: (self: Server) -> any,
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type Signal = {
 | 
					export type Signal = {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,11 +16,11 @@ local writef32 = buffer.writef32
 | 
				
			||||||
local writef64 = buffer.writef64
 | 
					local writef64 = buffer.writef64
 | 
				
			||||||
local writestring = buffer.writestring
 | 
					local writestring = buffer.writestring
 | 
				
			||||||
 | 
					
 | 
				
			||||||
local default = {
 | 
					local default: { [string]: number } = {
 | 
				
			||||||
	point = 0,
 | 
						point = 0,
 | 
				
			||||||
	next = 0,
 | 
						next = 0,
 | 
				
			||||||
	size = 128,
 | 
						size = 32,
 | 
				
			||||||
	bufferSize = 128,
 | 
						bufferSize = 32,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function DedicatedBuffer.copy(self: any, offset: number, b: buffer?, src: buffer?, srcOffset: number?, count: number?)
 | 
					function DedicatedBuffer.copy(self: any, offset: number, b: buffer?, src: buffer?, srcOffset: number?, count: number?)
 | 
				
			||||||
| 
						 | 
					@ -35,17 +35,16 @@ function DedicatedBuffer.alloc(self: any, byte: number)
 | 
				
			||||||
	local size: number = self.size
 | 
						local size: number = self.size
 | 
				
			||||||
	local b: buffer = self.buffer
 | 
						local b: buffer = self.buffer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while self.next + byte >= size do
 | 
				
			||||||
	while self.point + byte >= size do
 | 
							size = math.floor(size * 1.2)
 | 
				
			||||||
		size = math.floor(size * 1.5)
 | 
					 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
 | 
					 | 
				
			||||||
	local newBuffer: buffer = create(size)
 | 
						local newBuffer: buffer = create(size)
 | 
				
			||||||
	copy(newBuffer, 0, b)
 | 
						copy(newBuffer, 0, b)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	b = newBuffer
 | 
						b = newBuffer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	self.point  = self.next
 | 
						self.point  = self.next
 | 
				
			||||||
 | 
						self.buffer = b
 | 
				
			||||||
	self.next += byte
 | 
						self.next += byte
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -57,6 +56,15 @@ function DedicatedBuffer.build(self: any): buffer
 | 
				
			||||||
	return build
 | 
						return build
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function DedicatedBuffer.buildAndRemove(self: any): buffer
 | 
				
			||||||
 | 
						local p: number = self.next > self.point and self.next or self.point
 | 
				
			||||||
 | 
						local build: buffer = create(p)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						copy(build, 0, self.buffer, 0, p)
 | 
				
			||||||
 | 
						self:remove()
 | 
				
			||||||
 | 
						return build
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function DedicatedBuffer.wi8(self: any, val: number)
 | 
					function DedicatedBuffer.wi8(self: any, val: number)
 | 
				
			||||||
	if not val then return end
 | 
						if not val then return end
 | 
				
			||||||
	self:alloc(1)
 | 
						self:alloc(1)
 | 
				
			||||||
| 
						 | 
					@ -111,6 +119,85 @@ function DedicatedBuffer.wstring(self: any, val: string)
 | 
				
			||||||
	writestring(self.buffer, self.point, val)
 | 
						writestring(self.buffer, self.point, val)
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function DedicatedBuffer.wType(self: any, typeByte: number)
 | 
				
			||||||
 | 
						self:alloc(1)
 | 
				
			||||||
 | 
						writeu8(self.buffer, self.point, typeByte)
 | 
				
			||||||
 | 
						self.point += 1
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function DedicatedBuffer.pack(self: any, data: {any})
 | 
				
			||||||
 | 
						if typeof(data) == "number" then
 | 
				
			||||||
 | 
							if math.floor(data) == data then -- Integer
 | 
				
			||||||
 | 
								if data >= 0 and data <= 255 then
 | 
				
			||||||
 | 
									self:wi8(1) -- u8 marker
 | 
				
			||||||
 | 
									self:wu8(data)
 | 
				
			||||||
 | 
								elseif data >= -32768 and data <= 32767 then
 | 
				
			||||||
 | 
									self:wi8(2) -- i16 marker
 | 
				
			||||||
 | 
									self:wi16(data)
 | 
				
			||||||
 | 
								elseif data >= -2147483647 and data <= 2147483647 then
 | 
				
			||||||
 | 
									self:wi8(3) -- i32 marker
 | 
				
			||||||
 | 
									self:wi32(data)
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									self:wi8(4) -- f64 marker
 | 
				
			||||||
 | 
									self:wf64(data)
 | 
				
			||||||
 | 
								end
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								self:wi8(4) -- f64 marker
 | 
				
			||||||
 | 
								self:wf64(data)
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
						elseif typeof(data) == "boolean" then
 | 
				
			||||||
 | 
							self:wi8(5) -- boolean marker
 | 
				
			||||||
 | 
							self:wu8(data and 1 or 0)
 | 
				
			||||||
 | 
						elseif typeof(data) == "string" then
 | 
				
			||||||
 | 
							self:wi8(6) -- string marker
 | 
				
			||||||
 | 
							local length = #data
 | 
				
			||||||
 | 
							if length < 255 then
 | 
				
			||||||
 | 
								--self:wi8(7) -- small string marker
 | 
				
			||||||
 | 
								self:wu8(length) -- use 1 byte for length if small
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								--self:wi8(8) -- large string marker
 | 
				
			||||||
 | 
								self:wi32(length) -- 32-bit for larger strings
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
							self:wstring(data)
 | 
				
			||||||
 | 
						elseif typeof(data) == "Vector3" then
 | 
				
			||||||
 | 
							self:wi8(7) -- Vector3 marker
 | 
				
			||||||
 | 
							self:wf32(data.X)
 | 
				
			||||||
 | 
							self:wf32(data.Y)
 | 
				
			||||||
 | 
							self:wf32(data.Z)
 | 
				
			||||||
 | 
						elseif typeof(data) == "CFrame" then
 | 
				
			||||||
 | 
							self:wi8(8) -- CFrame marker
 | 
				
			||||||
 | 
							for _, v in {data:GetComponents()} do
 | 
				
			||||||
 | 
								self:wf32(v)
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
						elseif typeof(data) == "table" then
 | 
				
			||||||
 | 
							--local isArray = (next(data) ~= nil and #data > 0) and true or false
 | 
				
			||||||
 | 
							local isArray = true
 | 
				
			||||||
 | 
							local count = 0
 | 
				
			||||||
 | 
							for k in data do
 | 
				
			||||||
 | 
								count += 1
 | 
				
			||||||
 | 
								if typeof(k) ~= "number" or math.floor(k) ~= k then
 | 
				
			||||||
 | 
									isArray = false
 | 
				
			||||||
 | 
								end
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
							if isArray then
 | 
				
			||||||
 | 
								self:wi8(9) -- array marker
 | 
				
			||||||
 | 
								self:wi32(count) -- use 32-bit length
 | 
				
			||||||
 | 
								for _, v in data do
 | 
				
			||||||
 | 
									self:pack(v)
 | 
				
			||||||
 | 
								end
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								self:wi8(10) -- dictionary marker
 | 
				
			||||||
 | 
								self:wi32(count) -- number of key-value pairs
 | 
				
			||||||
 | 
								for k, v in data do
 | 
				
			||||||
 | 
									self:pack(k) -- pack the key
 | 
				
			||||||
 | 
									self:pack(v) -- pack the value
 | 
				
			||||||
 | 
								end
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							error("Unsupported data type: " .. typeof(data))
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function DedicatedBuffer.flush(self: any)
 | 
					function DedicatedBuffer.flush(self: any)
 | 
				
			||||||
	self.point = default.point
 | 
						self.point = default.point
 | 
				
			||||||
	self.next = default.next
 | 
						self.next = default.next
 | 
				
			||||||
| 
						 | 
					@ -128,8 +215,11 @@ function DedicatedBuffer.new()
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function DedicatedBuffer.remove(self: any)
 | 
					function DedicatedBuffer.remove(self: any)
 | 
				
			||||||
 | 
						self:flush()
 | 
				
			||||||
	table.clear(self)
 | 
						table.clear(self)
 | 
				
			||||||
	setmetatable(self, nil)
 | 
						setmetatable(self, nil)
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type DedicatedType = typeof(DedicatedBuffer.new())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
return DedicatedBuffer.new :: typeof(DedicatedBuffer.new)
 | 
					return DedicatedBuffer.new :: typeof(DedicatedBuffer.new)
 | 
				
			||||||
| 
						 | 
					@ -8,8 +8,84 @@ local Dedicated = require(script.Dedicated)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
local tostring = buffer.tostring
 | 
					local tostring = buffer.tostring
 | 
				
			||||||
local fromstring = buffer.fromstring
 | 
					local fromstring = buffer.fromstring
 | 
				
			||||||
 | 
					local readu8 = buffer.readu8
 | 
				
			||||||
 | 
					local readi8 = buffer.readi8
 | 
				
			||||||
 | 
					local readu16 = buffer.readu16
 | 
				
			||||||
 | 
					local readi16 = buffer.readi16
 | 
				
			||||||
 | 
					local readi32 = buffer.readi32
 | 
				
			||||||
 | 
					local readf32 = buffer.readf32
 | 
				
			||||||
 | 
					local readf64 = buffer.readf64
 | 
				
			||||||
 | 
					local readstring = buffer.readstring
 | 
				
			||||||
 | 
					local len = buffer.len
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function Buffer.new()
 | 
					local function readValue(b: buffer, position: number): (any, number)
 | 
				
			||||||
 | 
						local typeByte = readu8(b, position)
 | 
				
			||||||
 | 
						position += 1
 | 
				
			||||||
 | 
						if typeByte == 1 then -- u8
 | 
				
			||||||
 | 
							local value = readu8(b, position)
 | 
				
			||||||
 | 
							return value, position + 1
 | 
				
			||||||
 | 
						elseif typeByte == 2 then -- i16
 | 
				
			||||||
 | 
							local value = readi16(b, position)
 | 
				
			||||||
 | 
							return value, position + 2
 | 
				
			||||||
 | 
						elseif typeByte == 3 then -- i32
 | 
				
			||||||
 | 
							local value = readi32(b, position)
 | 
				
			||||||
 | 
							return value, position + 4
 | 
				
			||||||
 | 
						elseif typeByte == 4 then -- f64
 | 
				
			||||||
 | 
							local value = readf64(b, position)
 | 
				
			||||||
 | 
							return value, position + 8
 | 
				
			||||||
 | 
						elseif typeByte == 5 then -- boolean
 | 
				
			||||||
 | 
							local value = readu8(b, position) == 1
 | 
				
			||||||
 | 
							return value, position + 1
 | 
				
			||||||
 | 
						elseif typeByte == 6 then -- string
 | 
				
			||||||
 | 
							local lengthByte = readu8(b, position)
 | 
				
			||||||
 | 
							position += 1
 | 
				
			||||||
 | 
							local value
 | 
				
			||||||
 | 
							if lengthByte < 255 then
 | 
				
			||||||
 | 
								value = readstring(b, position, lengthByte)
 | 
				
			||||||
 | 
								return value, position + lengthByte
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								local length = readi32(b, position)
 | 
				
			||||||
 | 
								position += 4
 | 
				
			||||||
 | 
								value = readstring(b, position, length)
 | 
				
			||||||
 | 
								return value, position + length
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
						elseif typeByte == 7 then -- Vector3
 | 
				
			||||||
 | 
							local x = readf32(b, position)
 | 
				
			||||||
 | 
							local y = readf32(b, position + 4)
 | 
				
			||||||
 | 
							local z = readf32(b, position + 8)
 | 
				
			||||||
 | 
							return Vector3.new(x, y, z), position + 12
 | 
				
			||||||
 | 
						elseif typeByte == 8 then -- CFrame
 | 
				
			||||||
 | 
							local components = {}
 | 
				
			||||||
 | 
							for i = 1, 12 do
 | 
				
			||||||
 | 
								table.insert(components, readf32(b, position + (i - 1) * 4))
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
							return CFrame.new(unpack(components)), position + 48
 | 
				
			||||||
 | 
						elseif typeByte == 9 then -- array
 | 
				
			||||||
 | 
							local length = readi32(b, position)
 | 
				
			||||||
 | 
							position += 4
 | 
				
			||||||
 | 
							local array = {}
 | 
				
			||||||
 | 
							for _ = 1, length do
 | 
				
			||||||
 | 
								local value
 | 
				
			||||||
 | 
								value, position = readValue(b, position)
 | 
				
			||||||
 | 
								table.insert(array, value)
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
							return array, position
 | 
				
			||||||
 | 
						elseif typeByte == 10 then -- dictionary
 | 
				
			||||||
 | 
							local length = readi32(b, position)
 | 
				
			||||||
 | 
							position += 4
 | 
				
			||||||
 | 
							local dict = {}
 | 
				
			||||||
 | 
							for _ = 1, length do
 | 
				
			||||||
 | 
								local key, value
 | 
				
			||||||
 | 
								key, position = readValue(b, position)
 | 
				
			||||||
 | 
								value, position = readValue(b, position)
 | 
				
			||||||
 | 
								dict[key] = value
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
							return dict, position
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
						error(`Unsupported type marker: {typeByte}`)
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function Buffer.new(): Dedicated.DedicatedType
 | 
				
			||||||
	return Dedicated()
 | 
						return Dedicated()
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,4 +97,21 @@ function Buffer.revert(s: string): buffer
 | 
				
			||||||
	return fromstring(s)
 | 
						return fromstring(s)
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function Buffer.write(data: { any }): buffer
 | 
				
			||||||
 | 
						local newBuffer = Dedicated()
 | 
				
			||||||
 | 
						newBuffer:pack(data)
 | 
				
			||||||
 | 
						return newBuffer:buildAndRemove()
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function Buffer.read(b: buffer): any?
 | 
				
			||||||
 | 
						local position = 0
 | 
				
			||||||
 | 
						local result = {}
 | 
				
			||||||
 | 
						while position < len(b) do
 | 
				
			||||||
 | 
							local value
 | 
				
			||||||
 | 
							value, position = readValue(b, position)
 | 
				
			||||||
 | 
							table.insert(result, value)
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
						return table.unpack(result)
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
return Buffer :: typeof(Buffer)
 | 
					return Buffer :: typeof(Buffer)
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,5 @@
 | 
				
			||||||
--!strict
 | 
					--!strict
 | 
				
			||||||
--!optimize 2
 | 
					--!optimize 2
 | 
				
			||||||
return function(): number?
 | 
					return function(): number?
 | 
				
			||||||
	return tonumber(tostring(Random.new():NextNumber()):sub(3, 7)) -- 4-5 digits
 | 
						return tonumber(string.sub(tostring(Random.new():NextNumber()), 3, 8)) -- 6 digits
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
| 
						 | 
					@ -15,7 +15,7 @@ function RateLimit.create(Identifier: string, entrance: number?, interval: numbe
 | 
				
			||||||
		Event:SetAttribute(Identifier.."_int", interval)
 | 
							Event:SetAttribute(Identifier.."_int", interval)
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		while (not Event:GetAttribute(Identifier.."_ent")) or (not Event:GetAttribute(Identifier.."_int")) do
 | 
							while (not Event:GetAttribute(Identifier.."_ent")) or (not Event:GetAttribute(Identifier.."_int")) do
 | 
				
			||||||
			task.wait(0.5)
 | 
								task.wait(0.25)
 | 
				
			||||||
		end
 | 
							end
 | 
				
			||||||
		entrance = tonumber(Event:GetAttribute(Identifier.."_ent"))
 | 
							entrance = tonumber(Event:GetAttribute(Identifier.."_ent"))
 | 
				
			||||||
		interval = tonumber(Event:GetAttribute(Identifier.."_int"))
 | 
							interval = tonumber(Event:GetAttribute(Identifier.."_int"))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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.5) do -- let it loop for yields!
 | 
								while coroutine.status(cancel) ~= "dead" and task.wait(0.25) do -- let it loop for yields!
 | 
				
			||||||
				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))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,43 +2,20 @@
 | 
				
			||||||
--!strict
 | 
					--!strict
 | 
				
			||||||
--!optimize 2
 | 
					--!optimize 2
 | 
				
			||||||
local thread: thread?
 | 
					local thread: thread?
 | 
				
			||||||
local threads: {
 | 
					 | 
				
			||||||
	thread
 | 
					 | 
				
			||||||
} = {}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
local function passer<T...>(func: (T...) -> (), ...: T...): ()
 | 
					local function passer<T...>(func: (T...) -> (), ...: T...): ()
 | 
				
			||||||
	local HoldThread: thread = thread :: thread
 | 
						local HoldThread: thread = thread :: thread
 | 
				
			||||||
	thread = nil
 | 
						thread = nil
 | 
				
			||||||
	func(...)
 | 
						func(...)
 | 
				
			||||||
	if not thread then
 | 
					 | 
				
			||||||
	thread = HoldThread
 | 
						thread = HoldThread
 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	end
 | 
					 | 
				
			||||||
	table.insert(threads, HoldThread)
 | 
					 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
local function yield(): never
 | 
					local function newThread(): ()
 | 
				
			||||||
	while true do
 | 
						thread = coroutine.running()
 | 
				
			||||||
		passer(coroutine.yield())
 | 
						while true do passer(coroutine.yield()) end
 | 
				
			||||||
	end
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
local function createThread(): ()
 | 
					 | 
				
			||||||
	local newThread: thread = coroutine.create(yield)
 | 
					 | 
				
			||||||
	coroutine.resume(newThread, newThread)
 | 
					 | 
				
			||||||
	table.insert(threads, newThread)
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
for _=1,5 do
 | 
					 | 
				
			||||||
	createThread()
 | 
					 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
return function<T...>(func: (T...) -> (), ...: T...): ()
 | 
					return function<T...>(func: (T...) -> (), ...: T...): ()
 | 
				
			||||||
	if not thread then
 | 
						if not thread then task.spawn(newThread) end
 | 
				
			||||||
		if #threads == 0 then
 | 
					 | 
				
			||||||
			createThread()
 | 
					 | 
				
			||||||
		end
 | 
					 | 
				
			||||||
		thread = table.remove(threads, 1)
 | 
					 | 
				
			||||||
	end
 | 
					 | 
				
			||||||
	task.spawn(thread :: thread, func, ...)
 | 
						task.spawn(thread :: thread, func, ...)
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
[package]
 | 
					[package]
 | 
				
			||||||
name = "imezx/warp"
 | 
					name = "imezx/warp"
 | 
				
			||||||
version = "1.0.12"
 | 
					version = "1.0.13"
 | 
				
			||||||
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