local x={}x.__index=x function x.CheckRate(t,x)local Z=t._sources local o=os.clock()local b=Z[x]if b~=nil then b=math.max(o,b+t._rate_period)if b-o<1 then Z[x]=b return true else return false end else if typeof(x)=="\073\110\115\116\097\110\099\101"and(x:IsA("\080\108\097\121\101\114")and PlayerReference[x]==nil)then return false end Z[x]=o+t._rate_period return true end end function x.CleanSource(t,x)t._sources[x]=nil end function x.Cleanup(x)x._sources={}end function x.Destroy(x)RateLimiters[x]=nil end
-- RateLimiter object:
local RateLimiterObject = {
	--[[
		_sources = {},
		_rate_period = 0,
	--]]
}
RateLimiterObject.__index = RateLimiterObject

function RateLimiterObject:CheckRate(source) --> is_to_be_processed [bool] -- Whether event should be processed
	local sources = self._sources
	local os_clock = os.clock()

	local rate_time = sources[source]
	if rate_time ~= nil then
		rate_time = math.max(os_clock, rate_time + self._rate_period)
		if rate_time - os_clock < 1 then
			sources[source] = rate_time
			return true
		else
			return false
		end
	else
		-- Preventing from remembering players that already left:
		if typeof(source) == "Instance" and source:IsA("Player") and PlayerReference[source] == nil then
			return false
		end
		sources[source] = os_clock + self._rate_period
		return true
	end
end

function RateLimiterObject:CleanSource(source) -- Forgets about the source - must be called for any object that
	self._sources[source] = nil
end

function RateLimiterObject:Cleanup() -- Forgets all sources
	self._sources = {}
end

function RateLimiterObject:Destroy() -- Make the RateLimiter module forget about this RateLimiter object
	RateLimiters[self] = nil
end
