Currency Conversion Not Saving To Leaderstats

local ChangeLeaderstat = game.ReplicatedStorage.ChangeLeaderstat
local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore("MoneyStats")

game.Players.PlayerAdded:Connect(function(Player)
	local leaderstats = Instance.new("Folder") --Added this part because it gave an error that leaderstats isnt apart of player
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = Player
	local Gems = Instance.new("IntValue")
	Gems.Name = "Gems"
	Gems.Value = 250
	Gems.Parent = leaderstats
	local Coins = Instance.new("IntValue")
	Coins.Name = "Coins"
	Coins.Value = 0
	Coins.Parent = leaderstats
	-- These variables need to be defined when the player joins, because each player has their own unique leaderstats
	local Gems = Player.leaderstats.Gems
	local Coins = Player.leaderstats.Coins

	local Data
	pcall(function()
		Data = DataStore:GetAsync(Player.UserId)
	end)

	if Data then
		Gems.Value = Data["Gems"]
		Coins.Value = Data["Coins"]
	else -- there is no data, which means the player joined for the first time
		Gems.Value = 0 -- Any default value you want
		Coins.Value = 0 -- Any default value you want
	end
end)
game.Players.PlayerRemoving:Connect(function(Player)
	DataStore:SetAsync(Player.UserId, {
		["Gems"] = Player.leaderstats.Gems.Value;
		["Coins"] = Player.leaderstats.Coins.Value;
	})
	ChangeLeaderstat.OnClientEvent:Connect(function(plr, stat, value)
		plr.leaderstats[stat].Value = value
	end)
end)
local ChangeLeaderstat = game.ReplicatedStorage.ChangeLeaderstat
local player = game.Players.LocalPlayer
local coins = player.leaderstats.Coins
local gems = player.leaderstats.Gems
local Amount = script.Parent.Parent.Parent.TypeBar.NumberHere.Text
local confirm = script.Parent.Parent.Yes

script.Parent:GetPropertyChangedSignal("Text"):Connect(function()
	script.Parent.Parent.Parent.TypeBar.NumberHere.Text = script.Parent.Parent.Parent.TypeBar.NumberHere.Text:gsub('%D+', '');  -- Forces only numerical value input
end)

Amount = script.Parent.Parent.Parent.TypeBar.NumberHere.Text

if tonumber(Amount) then
	if gems.Value >= tonumber(Amount) then
		ChangeLeaderstat:FireServer("Coins", coins.Value + Amount * 20)
		ChangeLeaderstat:FireServer("Gems", gems.Value - Amount)

		script.Parent.Parent.Visible = false
		script.Parent.Parent.Parent.Visible = false
		wait(3)
	end
end

I believe it would work, there is just nothing that fires the second script once the button gui is clicked.

Basically the first script is the normal leaderstat script i have

Haha. You havenā€™t read my instructions correctly XD

in step 3 I mentioned to replace everything in the Click() function with that code. So this would be the whole script:

local ChangeLeaderstat = game.ReplicatedStorage.ChangeLeaderstat
local player = game.Players.LocalPlayer
local coins = player.leaderstats.Coins
local gems = player.leaderstats.Gems
local Amount = script.Parent.Parent.Parent.TypeBar.NumberHere.Text
local confirm = script.Parent.Parent.Yes

script.Parent:GetPropertyChangedSignal("Text"):Connect(function()
	script.Parent.Parent.Parent.TypeBar.NumberHere.Text = script.Parent.Parent.Parent.TypeBar.NumberHere.Text:gsub('%D+', '');  -- Forces only numerical value input
end)
function Click(mouse)	--Conversion system
    Amount = script.Parent.Parent.Parent.TypeBar.NumberHere.Text
    if tonumber(Amount) then
	    if gems.Value >= tonumber(Amount) then
		    ChangeLeaderstat:FireServer("Coins", coins.Value + Amount * 20)
		    ChangeLeaderstat:FireServer("Gems", gems.Value - Amount)

		    script.Parent.Parent.Visible = false
		    script.Parent.Parent.Parent.Visible = false
		    wait(3)
	    end
    end
end
confirm.MouseButton1Down:connect(Click)

Oh, geez im clumsy. The button works now, but now no currencies change which is weirdā€¦

You added the ChangeLeaderstat.OnClientEvent inside the PlayerRemoving event.

Which means it wont even check for the event until the player leavesā€¦

Just add the ChangeLeaderstat event function to the end of the script

game.Players.PlayerRemoving:Connect(function(Player)
	DataStore:SetAsync(Player.UserId, {
		["Gems"] = Player.leaderstats.Gems.Value;
		["Coins"] = Player.leaderstats.Coins.Value;
	})

end)

ChangeLeaderstat.OnClientEvent:Connect(function(plr, stat, value)
	plr.leaderstats[stat].Value = value
end)

Did my peanut brain do this correct? If so theres an error.

  20:37:57.713  OnClientEvent can only be used on the client  -  Server - OtherLeaderstats:42
  20:37:57.714  Stack Begin  -  Studio
  20:37:57.714  Script 'ServerScriptService.OtherLeaderstats', Line 42  -  Studio - OtherLeaderstats:42
  20:37:57.714  Stack End  -  Studio

Sorry lol this is my bad its like 3 am and Im not thinking straight myself

replace OnClientEvent with OnServerEvent

XD, you are good. It worked now. Thanks a lot for putting up with me lol

1 Like

Haha, I like to help people, are u sure its all working now? If so, you can mark one of my posts as a solution so people donā€™t have to keep finding it and trying to help further :slight_smile:

1 Like

If I may ask, how can this be prevented?

Yep I am 100% sure, marked as solution.

So lua executors/hacks work like this:

The user basically injects a local script into the game and runs any possible code they want on the client. So they could run something like this:

local value = 9999999999999999999
game.ReplicatedStorage.ChangeLeaderstat:FireServer("Coins", value)
game.ReplicatedStorage.ChangeLeaderstat:FireServer("Gems", value)

-- ez free money

The best way to counter this is by doing the math and checking if the value is valid on the SERVER. This is a rather hard thing to learn and hard to explain so I would recommend this post that explains it well. You could also do some research on how to secure your game better.

As Iā€™ve just mentioned have to warn you though, itā€™s pretty complicated seeing your current level of scripting knowledge, but see what u can do. Itā€™s fine if you donā€™t understand it yet as currently its not the most important thing since you are still learning. But it is important to address security of your future serious projects/games in the future.

2 Likes

Thanks, I will dig deeper into that before the game is completed. Now Iā€™ll do my best just to learn. Mainly what this game is for, learning. :slight_smile:

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.