[Help] Working DataStore, how can I make it more secure? [Script]

Hello, for my game I made (by combining several youtube videos and a little, too little knowledge) a DataStore Script for my game. The script works well and the data is saved. However my script is basic and I wonder if you could give me some tips or more, to make this script more optimal. Thanks

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local DataStoreService = game:GetService("DataStoreService")
local SaveData = DataStoreService:GetDataStore("Creatvurceslflfdfffdgfvfll")

game.Players.PlayerAdded:Connect(function(plr)
	local creatures = Instance.new("Folder")
	creatures.Name = "Creatures"
	creatures.Parent = plr
	local donation = Instance.new("BoolValue")
	donation.Name = "Donator"
	donation.Parent = plr

	local data = SaveData:GetAsync("CreaturesData-"..plr.UserId)
	local donator = SaveData:GetAsync(plr.UserId)

	if data then 
		for _, creature in pairs(data) do
			if workspace.Creatures:FindFirstChild(creature) then
				local bool = Instance.new("BoolValue")
				bool.Name = creature
				bool.Parent = creatures
				for i,v in pairs(game.Workspace.Creatures:GetChildren()) do
					v.CanTouch = true
				end
			end
		end
		if donator then
			donation.Value = donator
			for i,v in pairs(game.Workspace.Creatures:GetChildren()) do
				v.CanTouch = true
			end
		end
	else
		for i,v in pairs(game.Workspace.Creatures:GetChildren()) do
			v.CanTouch = true
			print("Nodata") -- If the script comes here it is because no Data has been found.
		end
	end
end)

 --As soon as the player makes an important action, the data is saved
game.ReplicatedStorage.Nametag.OnServerEvent:Connect(function(plr)
	wait(1)
	local CreaturesName = {}
	local DonatorSave = {}
	for _, creature in pairs(plr.Creatures:GetChildren()) do
		table.insert(CreaturesName, creature.Name)
	end
	table.insert(DonatorSave, plr.Donator.Value)
	SaveData:SetAsync("CreaturesData-"..plr.UserId, CreaturesName)
	SaveData:SetAsync(plr.UserId, DonatorSave)
end)


game.Players.PlayerRemoving:Connect(function(plr)
	local CreaturesName = {}
	local DonatorSave = {}
	for _, creature in pairs(plr.Creatures:GetChildren()) do
		table.insert(CreaturesName, creature.Name)
	end
	table.insert(DonatorSave, plr.Donator.Value)
	SaveData:SetAsync("CreaturesData-"..plr.UserId, CreaturesName)
	SaveData:SetAsync(plr.UserId, DonatorSave)
end)


game:BindToClose(function()
	for _, plr in pairs(game.Players:GetPlayers()) do	
		local CreaturesName = {}
		local DonatorSave = {}
		for _, creature in pairs(plr.Creatures:GetChildren()) do
			table.insert(CreaturesName, creature.Name)
		end
		table.insert(DonatorSave, plr.Donator.Value)
		SaveData:SetAsync("CreaturesData-"..plr.UserId, CreaturesName)
		SaveData:SetAsync(plr.UserId, DonatorSave)
	end
end)

This looks very good and isn’t much improvement needed.

Except with the RemoteEvent part

it would be advisable to add some sort of remote security since an exploiter could spam the event and crash your datastore.

A simple method to combat this would be to have a table full of players and whether their remote is on cooldown.

A little example


local cooldown = 8
local cooldowns = {}

event.OnServerEvent:Connect(function(player : Player)

  if cooldowns[player.UserId] then return end -- dont save if player is still on cooldown

  cooldowns[player.UserId] = true -- set the players coodown

  -- normal code here

  task.wait(cooldown) -- wait for the cooldown to end

  cooldowns[player.UserId] = nil -- remove player from cooldown
end
1 Like

Hello, thank you very much for this information and for this script already made, it is very generous. Indeed even on my game I regularly have people cheating by exploiting this same RemoteEvent (which is connected to the game objectives). Thanks a lot for this i like

1 Like