Securing my data without using dataStore2

This is my data store script. Basically, I’m not using datastore 2 for now since I don’t really need it for now. I need some suggestions and constructive feed back on how I can improve my script.

Logically, I think my script is good enough as I’m using game:BindToClose(), and repeat as well as some other good practices but still, who knows.

local DataStoreService = game:GetService("DataStoreService")
local PlayerDataStore = DataStoreService:GetDataStore("PlayerDataStore")

local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")

local ReplicatedFirst = game:GetService("ReplicatedFirst")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local dataFolder = ReplicatedFirst:WaitForChild("DataFolder")
local leaderstatsFolder = ReplicatedFirst:WaitForChild("leaderstats")
local remoteEventsFolder = ReplicatedStorage:WaitForChild("RemoteEvents")

local GET_DATA_INTERVAL = 3

local DISTRIBUTE_DATA_INTERVAL = 3

local function setPlayerDataFolder(Player)
	if Player then
		local newDataFolder = dataFolder:Clone()
		local newLeaderstatsFolder = leaderstatsFolder:Clone()
		
		newDataFolder.Name = Player.Name
		newDataFolder.Parent = ServerStorage
		newLeaderstatsFolder.Parent = Player
	end
end

local function setPlayer(Player)
	if Player then
		local character = Player.Character or Player.CharacterAdded:Wait()
		local nameTag = ServerStorage.NameTag:Clone()
		nameTag.User.Text = Player.Name
		nameTag.Parent = character.Head
	end
end

    local function WriteData(Player)
	
	if Player then
	
	setPlayer(Player)
	setPlayerDataFolder(Player)
	
	local playerKey = "-ValuesData" .. Player.UserId
	
	local data = { 
		["Points"] = Player.leaderstats.Points.Value,
		["Level"] = Player.leaderstats.Level.Value,
	}
	
	local Player_Data
	
	repeat
		
	local success, errormessage = pcall(function()
		Player_Data = PlayerDataStore:GetAsync(playerKey)
	end)
		
	GET_DATA_INTERVAL = GET_DATA_INTERVAL + 1	
		
	if success then	
		data = Player_Data
		
	    Player.leaderstats.Points.Value = data.Points
		Player.leaderstats.Level.Value = data.Level
    else
        remoteEventsFolder.DataWarning:FireClient()				
		warn(errormessage)
	end
		
	until GET_DATA_INTERVAL >= 3 or success
	end
end

    local function distributeData(player)
	
	if player then
		
	ServerStorage[player.Name]:Destroy()
		
	local playerKey = "-ValuesData" .. player.UserId
	
	local data = { 
	    ["Points"] = player.leaderstats.Points.Value,
		["Level"] = player.leaderstats.Level.Value,
	}
	
	repeat 
	
	local success, errormessage = pcall(function()
		PlayerDataStore:SetAsync(playerKey, data)
	end)
		
	if success then
		print(player.Name .. " 's data successfully saved")
	else
		warn(errormessage)
	end
		
	DISTRIBUTE_DATA_INTERVAL = DISTRIBUTE_DATA_INTERVAL + 1	
		
	until DISTRIBUTE_DATA_INTERVAL >= 3 or success
		
	end
end
	
Players.PlayerAdded:Connect(WriteData)
Players.PlayerRemoving:Connect(distributeData) 

game:BindToClose(function()
	for _, player in ipairs(Players:GetPlayers()) do
	   distributeData(player)
	end
end)

I’m all ears.

Instead of kicking the player when data fails to load, I’d retry until it works and give the player a warning that data is taking longer to load than usual.

2 Likes

That’s a really nice idea. I’ll keep that in mind.

1 Like

I’m guessing you want to write your own data store code while learning how to handle DataStoreService calls properly?

You don’t have to use this module, but I think it would be really worthwhile to check out saving data with ProfileService - whether you choose to use the module or not, you will still learn a bit about proper data control practices. A video has been made for it recently:

2 Likes