I dont know if the topic is appropriate to the category but, I have a problem. I want to make a leaderstats that save player data INSIDE server storage. I want to make a leaderboard that cannot be access by clients(I want to make a non seen, secure leaderboard if it’s not clear). I dont know how to make it or if it’s possible because I haven’t got to advanced scripting. Any suggestions in the comments will be accepted.
Create a folder in the ServerStorage called 'PlayerData` (this is where a folder containing the player’s data is going to be made when the data loads from the datastore.)
Create a remote function in the replicated storage called getData this is how the client gets data from the datastore.
local DatastoreService = game:GetService("DataStoreService")
local myDataStore = DatastoreService:GetDataStore("Saves_Version_1")
--this is a list of data that can't be shared with the client
local unsharableData = {"numResets"}
--converts the data to a table to allow it to be saved in the datastore
function serializeData(player)
local data = {}
local playerFolder = game.ServerStorage.PlayerData[player.Name]
for _, child in pairs(playerFolder:GetChildren())do
data[child.Name] = child.Value
end
return data
end
--loads the players data from the datastore
function loadDataFromDatastore(player)
--create a folder/values for the players's data
local playerFolder = Instance.new("Folder")
playerFolder.Name = player.Name
local numResets = Instance.new("IntValue")
numResets.Parent = playerFolder
numResets.Name = "numResets"
local coins = Instance.new("IntValue")
coins.Parent = playerFolder
coins.Name = "Coins"
playerFolder.Parent = game.ServerStorage.PlayerData
-- loadas the players data from datastore
local data
local success, err = pcall(function()
data = myDataStore:GetAsync(player.UserId) or {}
end)
--if the datastore got the data successfully, set the data in the folder to be the data from the datastore
if success then
print("data has successfully loaded for " .. player.Name)
numResets.Value = data.numResets or 0 --if the player hasnt played before, give them the default resets value of zero
coins.Value = data.Coins or 5 --if the player hasnt played before, give them the default coins value of 5
else
warn(err)
end
return playerFolder
end
--when this function is called, it converts the players data to a table and saves that table to the datastore
function saveDataToDatastore(player)
local data = serializeData(player)
local success, err = pcall(function()
myDataStore:SetAsync(player.UserId, data)
end)
if success then
print("data has successfully saved for " .. player.Name)
end
--print out an error if the data didnt save succesfully
assert(success, err)
end
------------------------------------------------------------------------
--loads the players data when they join the game
game.Players.PlayerAdded:Connect(function(player)
local playerFolder = loadDataFromDatastore(player)
end)
--saves the data when the player leaves the game
game.Players.PlayerRemoving:Connect(function(player)
saveDataToDatastore(player)
end)
--save everyones data when the game shuts down
game:BindToClose(function()
for _, player in pairs(game.Players:GetPlayers())do
saveDataToDatastore(player)
end
end)
-- use this remote function to get data from the client.
-- if the data theyre trying to get is not in the `unshareableData` table, then return that data
-- otherwise, return a string that says the data could not be shared.
-- eg, the player can see how many coins they have but they cant see their number of resets
game.ReplicatedStorage.getData.OnServerInvoke = function(player,requestedDataName)
local canShareData = not table.find(unsharableData, requestedDataName)
local playerFolder = game.ServerStorage.PlayerData[player.Name]
if canShareData then
return playerFolder[requestedDataName]
else
return "DATA COULD NOT BE SHARED TO CLIENT " .. requestedDataName
end
end
Comments explain what everything does, but message me if you have any more questions.
Hold on :v
What does this mean? That DataStore is not a good way to store player’s data?.. I dont understand what means “Store data in Server Storage” :v
So… DataStoreService is able to work from LocalSctipts?.. So a player can change the DataStore values as exploit?..
So, I thinks there’s no need for you to find a way to save data inside Server Storage… I don’t even know if saving “tables” or something in there would be a nice idea or possible :v
Well I am making an anti exploit script that if a player got reseted by the server 3 times, they would get kick. If the player have been kick 3 times by the server, they would get ban.
There is some reason why I want it to be in Server Storage. The reason is because I want it to be secure. I’am making this for an anti cheat. I thought about this: “What if exploiter can change the value”. Therefore I need this. They can just change the value so they will NEVER get ban.
oh…, I didn’t think about that. I thought you can change value… Well lesson learn now I’m getting smarter. Thank for the info then I would never know if you can’t change the value.
Sorry, this is really late and may not be helpful anymore, but–
If you want to store client data, it’s a good idea to do it in ServerStorage or ServerScriptService. Do not store it in ReplicatedStorage – clients can access replicated storage, so data can be easily changed there. SS and SSS can only be accessed by the server.
DataStore is also a reliable and secure way to store player data, but it has some limitations. There is a limit to the amount of requests you can send in a certain amount of time, so if you are changing values frequently, it’s better to store the values in SSS and save them to datastore when a player leaves the game.
You may store your data in the replicated storage without having to worry about hackers changing the values. They can view the values but they can’t change it on the server. Your data is safe from hackers either way.