Is my script secured enough?

Hey , i dont know but i tried my best to prevent from dataloses but it still happen and yet i dont know how to counter it , heres my scritp

local DataStoreService = game:GetService("DataStoreService")
local DataStore2 = require(script.DataStore2) 
local Ds2Vehicle = "VehicleDataStoreIrfan" -- do not change it
local playerData = DataStoreService:GetDataStore("PlayerData") 

local function CreateCarValue(player, name, value)
	local carValue = player.OwnedCars:FindFirstChild(name)
	if not carValue then
		carValue = Instance.new("BoolValue")
		carValue.Name = name
		carValue.Parent = player.OwnedCars
	end
	carValue.Value = value
	return carValue
end

local function CreateTable(player)
	local playerStats = {}
	for _, stat in pairs(player.OwnedCars:GetChildren()) do
		if stat.Value == true then
			playerStats[stat.Name] = true
		end
	end
	return playerStats
end

-- MOTOR FUNCTION #3
local cars = {
	"HondeEX5",
	"HondeWave100",
	"Kasaki 150sp",
	"Lagenda115zr",
	"Lajak",
	"Rzx Milinium",
	"Wave125i Drag",
	"Light Lz",
	"Yamha Soleriz",
	"Yamha 125rz",
	"Sniper150Drag",
	"Yamha Sniper135 v1",
	"Honde Deo",
	"Honde Nsr500",
	"Icikiwir",
	"Yamha Yzr500",
	"Honde Wave 125r",
	"Kasaki Pdk R1",
	"Dukatti SuperSport S",
	"Kasaki Serpico",
	"Yamha X1r",
	"Vesp 150ss",
	"Dukatti 1299",
	"Yamha Sniper v2",
	"Suzuka Raider 150",
	"Kasaki Ninja H2",
	"Yamha R6 v2",
	"Suzuka Hayabusa Drag",
	"Yamha X1r White",
	"Mz Agusza F4",
	"Honde NR750",
	"Dukatti 1199 Martini"
}


local function VehicleFunction(player)
	local MotorStats = DataStore2(Ds2Vehicle, player)
	local data1 = MotorStats:Get()

	if data1 then
		print("Vehicle data loaded for " .. player.Name)
		for car, value in pairs(data1) do
			if value == true and table.find(cars, car) then
				CreateCarValue(player, car, true)
			end
		end
	else
		local attempt = 1
		local success = nil
		local data = nil

		repeat
			success, data = pcall(function()
				return playerData:GetAsync("Player_" .. player.UserId)
			end)

			attempt += 1
			if not success then
				warn(data)
				wait(1)
			end
		until success or attempt == 5

		if data then
			print("Load old vehicle data for player " .. player.Name)

			for car, value in pairs(data) do
				if value == true and table.find(cars, car) then
					CreateCarValue(player, car, true)
				end
			end

			print("Saving for player " .. player.Name)
			MotorStats:Set(data)
		else
			warn("Unable to get vehicle data for " .. player.UserId)
			player:Kick("Unable to load your data, please wait for 10 seconds and rejoin !")
		end
	end
end

game.Players.PlayerAdded:Connect(function(player)
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "OwnedCars"
	leaderstats.Parent = player

	VehicleFunction(player)
end)

local function SavePlayerData(player)
	local motorStats = CreateTable(player)
	local MotorStats = DataStore2(Ds2Vehicle, player)
	MotorStats:Set(motorStats)
	print("Vehicle data saved for " .. player.Name)

	-- pretty sure it will not damage the data just want to check the amount of booleans
	local numCarsOwned = 0
	for _, value in pairs(motorStats) do
		if value == true then
			numCarsOwned = numCarsOwned + 1
		end
	end
	print("Number of boolean owned by " .. player.Name .. ": " .. numCarsOwned)
end



game.Players.PlayerRemoving:Connect(function(player) -- player leave
	SavePlayerData(player)
end)

game.ReplicatedStorage.DataSave.Event:Connect(function(player) -- everytime player bought vehicle it i will fire
	SavePlayerData(player)
	wait(0.5)
	print("Saved bought from " .. player.Name)
end)

game.ReplicatedStorage.ManualSave.OnServerEvent:Connect(function(player) -- manual save
	SavePlayerData(player)
	wait(0.5)
	print("Manual data saved" .. player.Name)
end)
1 Like

theres already lots of modules/wrappers you could use to ease your datastore managing; you could use Datastore2 which @bluebxrrybot has mentioned; or you can use ProfileService which has a more robust usage and freedom;

1 Like

Code security-wise, you’re good.
Data loss-wise, you’re… most likely good.
Code writing, you’re not good.

DataStore2 is an option, for your use-case I wouldn’t really say the best option. Especially since you even tell the player to wait before rejoining, which you wouldn’t have issues with if you were using ProfileService, since it has built-in session locking, which it seems your code is not doing at all.

Also, using DataStore2 this way is very not-scalable, but seeing as how this code is written to begin with, scalability seems to not be what you’re aiming for, and a system that just works is what you care about. So, yes. Your code is fine to use.

1 Like

This is datastore2 script… Ok yeah .

1 Like

oh, sorry; didnt see that, i got confused when you have both datastoreservice and datastore2

1 Like

Yeah if player data not found then it will load old data

Thought u gona help me ;-; . Nevermind.

1 Like

Wait, the code you provided seems like it is using Datastore2 so it shouldn’t lose data at all

1 Like

Yeah i have never experienced dataloss , but 2 or ,3 people does . I even tried to experience dataloss but never happen .

Yes i have never experienced dataloss , but some poeple been complain about dataloss , i even communicate with community and they said they never experienced dataloss which is weird . But after i go to my group yes player complain bout it

Im just want to make sure if the script good enough or could go better , so i can proceed for my next project …

I would recommend looking into migrating your DataStore to use ProfileService. It should be way more beneficial for what you’re trying to do. It may look complicated when you first look at it, but it is extremely simple to use.

The way you are saving datastore with the datastore2 module isn’t what I am familiar with, I follow tutorial which doesn’t cause data loss at all:

1 Like

If i change to profile service then i would have 3 data of vehicle. Old data , ds2 , profservice which could even worse.

Ouh? Imma check it out later .

Wait, so you weren’t initially using DataStore2 when you first started your project? Meaning half of your project is using Roblox’s built-in DataStore system, and the other half is using the DataStore2 wrapper?

Please, please, please have a data migration system in place.

Yeah , i thought ds2 is the best way to prevent dataloss . And yes it works for me not sure to other people . Thats why i use ds2

Really the only time data loss occurs in games is simply not enough care into how data is handled, or even data corruption. In the terms of games that use DataStore2, like Dugeon Quest, they don’t experience data loss and instead data duplication since DataStore2 does not have session locking. This is a commonly exploited bug in games with trading economies that use a non-session locking wrapper. Or, your data may be getting overwritten somewhere that you’re just not not expecting it to happen.

When making a project, especially one that you plan on publishing to the public, be it an open sourced resource for people to use or a game for people to play, the “it works for me” or “it works on my computer” is generally a bad response. If players on your game are experiencing data-loss, that is your fault.

Also, you should never be storing multiple different types of datastores unless you really know what you’re doing, and if you do know what you’re doing: you’d probably avoid this to begin with, so you wouldn’t do this.

You should be setting up a migration script to, when a player joins, to migrate their old data into their new data store, confirming the data matches and is the same with a deep search, and then saving their data on the new data system and do not delete the old system, just plan to never use it. Make sure your players know you are migrating their data, and if they lost data during migration, to redo their data migration manually, that is why you should not delete the old system, this is what Parkour did last year. Then, warn players that they only have X amount of time (in days or even months, maybe even years depending on your game’s scale) to migrate their data, that after that time they would have to contact the game’s support team to manually migrate their data afterwards, so you could start focusing on actually making updates using your new system. This is also something the ParkourDev Team did.

2 Likes

Thank you for the information , thats tough for me . seems like my script is kinda good already but having issue when server or computer that the game is running on . [ maybe ? ]
i do ask player how they lossd their data but overall due to computer went off and etc

Exploiters can spam remotes keep that in mind. What im suggesting is that they could trigger datastore rate limit and prevent you from saving data for players in the server. Add some checks for that please.