I need help with Code System

Hello! I made codes system and I want save already used codes by player in datastore! How I can make this? I must use RemoteEvent/Function?

You need metatables for that, that’s what I know.

You don’t… just simply create table in datastore and insert the used code there and then before giving the award in the server check if the code isn’t already in the saved table…

I have this script (it’s just a line)

experienceStore:SetAsync(Codes[Box.Text], true)

But I can’t use DataStore in LocalScript
Zrzut ekranu 2021-06-2 o 22.02.09

You have to call DataStores on the server, the more easier approach would be is to just use a PlayerAdded event, & set up your DataStores from there

Yes, you can use a RemoteEvent to call from the client/server in order to save the data properly that way, you can pass the Codes[Box.Text] & the bool value over for the server to receive and call SetAsync that way

1 Like

You’d want to fire a RemoteEvent to the server with the Text included in the TextBox, then create an if statement to check if the code is right and has been used using DataStore:GetAsync(userId).

If the code’s right and wasn’t used, create a DataStore:UpdateAsync(userId, function(oldValue)) to update the table by adding in the code in the table (returning the value to add for the oldValue). Here’s a sample on how this works:

local codes = {"code1", "code2", "code3"}
RemoteEvent.OnServerEvent:Connect(function(plr, text)
    if not table.find(codes, text) or DataStore:GetAsync(plr.UserId)[text] then
    return end
    DataStore:UpdateAsync(plr.UserId, function(oldValue) --{"code1", "code2"}
        table.insert(oldValue, code) --inserting "code3" (example)
        return oldValue --returning the table with the new value
    end)
end)
1 Like

Ok, I paste this example script but game think:

All codes are expired! (I made notification system for codes)

Do you want all scripts?

Sure, I’ll troubleshoot the issue in the code - I haven’t tested mine yet, so it could be the case, but I’ll see the source.

Scripts:


CodesHandler.lua (LocalScript)

local Codes = {
	["babyshark"] = 50,
	["CONSOLE"] = 343,
	["Jarro"] = 300,
	["alpha"] = 1000,
	["devs"] = 2000,
	["kromkowo.pl"] = 100000,
	["Eurovision2021"] = 2021,
	["ILikeDiscoteque"] = 2153,
	["kasjmirr"] = 9000,
	["kasjmirrhouse1_50Visits"] = 50,
	["party"] = 984,
	["watermelon"] = 5000
}



local Box = script.Parent.MainHandlerCode.TextBox
local code = Box.Text
local btn = script.Parent.MainHandlerCode.TextButton
local Value = game.Players.LocalPlayer.PlayerData.Credits -- I used this for example :D
btn.MouseButton1Up:Connect(function(player)
	if Box.Text == Codes[Box.Text] then
		local text = Box.Text
		Value.Value += Codes[Box.Text]
		btn.TextLabel.Text = "Successfully redeemed code ".. Box.Text .."!"
		local Redeem = game.ReplicatedStorage.RedemCode
		Redeem:FireServer(player, text)
		local sgui = game.StarterGui
		local textTit = "+".. Codes[Box.Text] .." Kas$"
		sgui:SetCore("SendNotification", {
			Title = textTit,
			Text = "Redeemed code " .. Box.Text,
			Duration = 2.5
		}
		)
		wait(0.5)
		btn.TextLabel.Text = "Redeem"

		else
		local sgui = game.StarterGui
		local textTit = "Unable to reddem code ".. Box.Text
		sgui:SetCore("SendNotification", {
			Title = textTit,
			Text = "Code " .. Box.Text .. " is expired or don't exist",
			Duration = 2.5
		}
		)
	end
end)

RedeemCode.lua (Server Script for Remote Event)

local RemoteEvent = game.ReplicatedStorage.RedemCode
local codes = {"codes"}
local DataStore = game:GetService("DataStoreService")
RemoteEvent.OnServerEvent:Connect(function(plr, text)
	local userId = plr.UserId
	if not table.find(codes, text) or DataStore:GetAsync(plr.UserId)[text] then
		return end
	DataStore:UpdateAsync(userId, function(oldValue) --{"code1", "code2"}
		table.insert(oldValue, codes) --inserting "code3" (example)
		return oldValue --returning the table with the new value
	end)
end)
local dds = game:GetService("DataStoreService") --this is a service for DataStores
local DataStore = dds:GetDataStore("Codes") --DataStore is needed

You don’t have to define the userId - instead, use plr.UserId in both of the parameters

DataStore:UpdateAsync(plr.UserId, function(oldValue)
DataStore:GetAsync(plr.UserId)[text]

Don’t increase the value (award) for the player in LocalScript - they’re exploitable and will cause security flaws. Instead, update (add) their value in the Script. Don’t check for the code in LocalScript either, as you’re leaking them (seen by exploiters), and they’re already being checked in the Script.

In what script I must paste this?

Above:

local codes = {"code1", "code2", "code3"}
1 Like

Zrzut ekranu 2021-06-2 o 22.37.05

Still game don’t want redeem code

Is there an error in the output? Are API services enabled in the game settings?

No errors, and I have enabled API Service

--Script in ServerScriptService
local dds = game:GetService("DataStoreService")
local DataStore = dds:GetDataStore("Codes")
local rep = game:GetService("ReplicatedStorage")
local RemoteEvent = rep.RemoteEventName --replace "RemoteEventName"

local codes = {
	["code1"] = 50,
	["code2"] = 100,
	["code3"] = 150
}

RemoteEvent.OnServerEvent:Connect(function(plr, text)
	local hasRedeemed
	local success, failed = pcall(function()
		hasRedeemed = DataStore:GetAsync(plr.UserId)[text] or false
	end)
	
	if not codes[text] then --if code doesn't exist then
		RemoteEvent:FireClient(plr, "invalid"); print("invalid"); return
	elseif hasRedeemed then --if used then
		RemoteEvent:FireClient(plr, "used"); print("used"); return
	end
	--if code is in table and hasn't been used then
	plr.leaderstats.Points.Value += codes[text]
	RemoteEvent:FireClient(plr, "redeemed"); print("redeemed")
	--[ updating data ]
	DataStore:UpdateAsync(plr.UserId, function(oldValue) --{"code1", "code2"}
		if oldValue == nil then oldValue = {} end --if they're new then create a table
		oldValue[text] = codes[text] --saves the code (with the value of points earned)
        return oldValue --returning the table with the new value
    end)
end)

With this script, you can use RemoteEvents, locally (listening to :FireClient(msg)), with these messages in the parameter (msg):

  • “invalid” - the code isn’t in the table,
  • “used” - the code was already used by the player,
  • “redeemed” - successfully redeemed.
RemoteEvent.OnClientEvent:Connect(function(msg)
    print(msg)
    if msg == "redeemed" then
        print("the code was redeemed as well!")
        --SetCore stuff
    end
end)
1 Like

Working! Thanks for help @Doqee!

1 Like