Specifically they’re spamming GetSortedAsnyc
I’m not sure how they are doing it but I’m guessing they’re spamming the remote events that return the datastore. There are two datastores they could be spamming, one is a list and one is a number. I’ve only ever used datstore2 so I’m not familiar with the intricacies of datastore.
local function returnInventory(player)
local inventoryStore = DataStore2("Inventory", player)
return inventoryStore:Get()
end
--and
local function coinValue(player)
local coinsStore = DataStore2("Coins", player)
return coinsStore:Get()
end
The thing that I’m confused about is since it’s a connected to a remote event, usually when a player spams a remote event there will be a warning like “player appears to be spamming remote events,” but I don’t see that.
This is what I use to kick players when they spam remotes:
Source Code
local TrackRequests = {}
local PLAYER_ERRORS = require(script.Parent.Parent.Admin.PLAYER_ERRORS)
function TrackRequests.new(requestCacheLength : number, maxRequests : number)
local self = {
RequestCacheLength = requestCacheLength or 6,
MaxRequests = maxRequests or 5,
_RequestTracker = {},
}
setmetatable(self, {__index = TrackRequests})
return self
end
function TrackRequests:AddToTrack(plr : Player)
local currentRequestNum = self._RequestTracker[plr.UserId]
local newRequestNum
if currentRequestNum then
newRequestNum = currentRequestNum + 1
else
newRequestNum = 1
end
self._RequestTracker[plr.UserId] = newRequestNum
self:CheckPlayerRequests(plr)
task.delay(self.RequestCacheLength, function()
if not self._RequestTracker[plr.UserId] then
return
end
self._RequestTracker[plr.UserId] -= 1
if self._RequestTracker[plr.UserId] > 0 then
return
end
self._RequestTracker[plr.UserId] = nil
end)
end
function TrackRequests:CheckPlayerRequests(plr : Player)
if not self._RequestTracker[plr.UserId] then
return
end
if self._RequestTracker[plr.UserId] < self.MaxRequests then
return
end
plr:Kick(PLAYER_ERRORS.KickReasons[1])
self._RequestTracker[plr.UserId] = nil
end
return TrackRequests
How To Use
local TrackRequests = require(script.Parent.TrackRequests) -- Whereever your module is located
local TrackRequestHandler = TrackRequests.new(300, 2) -- First parameter is how long you want each paremeter to be tracked for, the second parameter is the request limit b4 the player is kicked
blahblahEvent.OnServerEvent:Connect(function(plr)
TrackRequestHandler:AddToTrack(plr)
Not anything professional or whatever, and probably not that much of use, but felt like it would help you a little bit.
I don’t think that that is a thing by default. I believe you would need some extra code added in order to achieve that.
If you want to limit the number of times that a player can trigger the remote event, you can do something like this
local counts = {}
local function returnInventory(player)
counts[player] = (counts[player] + 1) or 1
if counts[player] > 10 then -- choose a value
player:Kick("Spamming Remotes")
return
end
task.delay(1, function() counts[player] -= 1 end
local inventoryStore = DataStore2("Inventory", player)
return inventoryStore:Get()
end
This checks that they haven’t sent more than 10 calls to returnInventory in the last second, and if they do then it kicks them
Why are you fetching their data every time they ask? You should just load it once on the server, when they first join, and then return that to the player when they fire the remote.
For the leaderboard, just update it every 5 seconds or so on the server, and save it to a value that’s returned when players ask for it.
I’ll implement this @Judgy_Oreo
That’s a good point. I still want to update the inventory datastore every time a player selects something new in their inventory, but I can make a table in that script of the inventory that the remote function will reference that updates when the player changes their inventory.