add gs
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
local UserInputService = game:GetService("UserInputService")
|
||||
|
||||
local join = require(script.Parent.join)
|
||||
|
||||
--[[
|
||||
CLILUACORE-318: Revisit this approach and evaluate if it adequately
|
||||
addresses existing or future scams
|
||||
]]
|
||||
local ClickScamDetector = {}
|
||||
ClickScamDetector.__index = ClickScamDetector
|
||||
|
||||
--[[
|
||||
Create a new scam detector with the specified options
|
||||
|
||||
This object will track any clicks or confirm button presses that occur
|
||||
during its lifetime and attempt to determine whether the player is
|
||||
being asked to spam clicks or button presses. When processing an action,
|
||||
users of this object can abort their behavior if calling isClickValid
|
||||
returns false.
|
||||
]]
|
||||
function ClickScamDetector.new(options)
|
||||
--[[
|
||||
Overwrite default values with provided options
|
||||
]]
|
||||
options = join({
|
||||
-- The number of clicks within the window that is interpreted as a scam
|
||||
clickSpeedThreshold = 3,
|
||||
-- The window in which to measure clicks
|
||||
clickTimeWindow = 1,
|
||||
-- A delay to allow clicks to stack up and prevent immediate clicks
|
||||
initialDelay = 1,
|
||||
-- Allow a button input to be associated with this click detection
|
||||
buttonInput = nil,
|
||||
}, options)
|
||||
|
||||
local self = {
|
||||
_inputConnection = nil,
|
||||
|
||||
_clickCount = 0,
|
||||
_startTime = tick(),
|
||||
_options = options,
|
||||
}
|
||||
|
||||
setmetatable(self, ClickScamDetector)
|
||||
|
||||
self._inputConnection = UserInputService.InputBegan:Connect(function(input)
|
||||
self:_onInput(input)
|
||||
end)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--[[
|
||||
Track mouse inputs, counting the number that occurred in the last
|
||||
CLICK_TIME_WINDOW duration
|
||||
|
||||
Includes touch inputs and pressing the A button on a gamepad
|
||||
]]
|
||||
function ClickScamDetector:_onInput(input)
|
||||
local inputType = input.UserInputType
|
||||
|
||||
local isGamepad = self._options.buttonInput ~= nil and input.KeyCode == self._options.buttonInput
|
||||
|
||||
local isMouseOrTouch = inputType == Enum.UserInputType.MouseButton1
|
||||
or inputType == Enum.UserInputType.Touch
|
||||
|
||||
if isGamepad or isMouseOrTouch then
|
||||
self._clickCount = self._clickCount + 1
|
||||
|
||||
delay(self._options.clickTimeWindow, function()
|
||||
self._clickCount = self._clickCount - 1
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
--[[
|
||||
Determine whether or not there's a possibility of a scam occurring
|
||||
and return whether or not we believe the click to be valid
|
||||
]]
|
||||
function ClickScamDetector:isClickValid()
|
||||
--[[
|
||||
If the mouse behavior is locked by dev-facing APIs, clicks are not valid
|
||||
]]
|
||||
if UserInputService.MouseBehavior == Enum.MouseBehavior.LockCurrentPosition then
|
||||
return false
|
||||
end
|
||||
|
||||
--[[
|
||||
Don't allow any clicks until the initial delay has passed;
|
||||
]]
|
||||
if tick() - self._startTime < self._options.initialDelay then
|
||||
return false
|
||||
end
|
||||
|
||||
return self._clickCount / self._options.clickTimeWindow < self._options.clickSpeedThreshold
|
||||
end
|
||||
|
||||
--[[
|
||||
Cleanup connection to InputService; should be called when
|
||||
the UI element using this object is destroyed
|
||||
]]
|
||||
function ClickScamDetector:destroy()
|
||||
self._inputConnection:Disconnect()
|
||||
end
|
||||
|
||||
return ClickScamDetector
|
||||
Reference in New Issue
Block a user