Hey guys!
So I’ve been working on this gamecode system for some time. The last problem I’m having is the fact that the values I save when the player leaves the game keep resetting for some reason. Because when I join back, the ‘Uses’ of said key are back to what it was. Despite the fact that whatever was saved did change. (Tested it by printing the values before stopping the test run, which gave the correct values. But when I pressed play solo again the values reset to the original values)
When I join
When I leave
When I join again
ServerScript
local RS = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local MarketplaceService = game:GetService("MarketplaceService")
local Variables = require(RS:WaitForChild("Modules"):WaitForChild("KeyCodes"):WaitForChild("Variables"))
local KeyCodeModule = require(ServerStorage:WaitForChild("Modules"):WaitForChild("Codes"):WaitForChild("KeyCodes"))
local DS = game:GetService("DataStoreService")
local KeyDS = DS:GetDataStore("SomeOtherSortOfDataStore")
local BoughtKeyDS = DS:GetDataStore("SomeSortOfDataStore")
local PurchaseHistory = DS:GetDataStore("PurchaseHistory")
local CurrentValue
game.Players.PlayerAdded:connect(function(Player)
local UserTemplate = script.Data.UserTemplate:Clone()
UserTemplate.Name = "Player_"..Player.userId
UserTemplate.Parent = game:GetService("ServerStorage").GameCodes
local Data = BoughtKeyDS:GetAsync(Player.userId.."_Keys");
if typeof(Data) == "table" then
for i,key in pairs(Data) do
for y,v in pairs(key) do
print(i,key,y,v)
end
local KeyTemplate = script.Data.KeyTemplate:Clone()
KeyTemplate.Name = i.."-GameCode"
KeyTemplate.Duration.Value = key.Duration
KeyTemplate.Owner.Value = key.Owner
KeyTemplate.KeyName.Value = key.KeyName
KeyTemplate.Uses.Value = key.Uses
KeyTemplate.Parent = UserTemplate
if key.Uses > 0 and key.Duration > tick() then
local LoggedKey = script.GUIs.KeyTemplate:Clone()
LoggedKey.Key.Text = key.KeyName
LoggedKey.Nr.Text = key.Uses.."U"
LoggedKey.Name = key.Uses.."GameKey"
LoggedKey.Parent = Player.PlayerGui:WaitForChild("KeyMenu"):FindFirstChild("KeyLog", true)
end
end
else
BoughtKeyDS:SetAsync(Player.userId.."_Keys", {})
end
local ActiveKey = UserTemplate.ActiveKey
ActiveKey.CurrentTime.Value = tick()
ActiveKey.Changed:connect(function()
CurrentValue = ActiveKey.Value
repeat
ActiveKey.CurrentTime.Value = ActiveKey.CurrentTime.Value + 0.001
wait(0.001)
until ActiveKey.CurrentTime.Value > ActiveKey.Duration.Value or ActiveKey.Value ~= CurrentValue
Player.PlayerGui.KeyMenu.Enabled = true
end)
end)
game.Players.PlayerRemoving:connect(function(Player)
local KeyData = game:GetService("ServerStorage").GameCodes["Player_"..Player.userId]
local KeyTable = {}
for i,key in pairs(KeyData:GetChildren()) do
if key:IsA("Folder") then
table.insert(KeyTable, {
["Duration"] = key.Duration.Value;
["KeyName"] = key.KeyName.Value;
["Owner"] = key.Owner.Value;
["Uses"] = key.Uses.Value;
})
end
end
for i,key in pairs(KeyTable) do
for y,v in pairs(key) do
print(i,key,y,v)
end
end
BoughtKeyDS:SetAsync(Player.userId.."_Keys", KeyTable)
KeyData:Destroy()
end)
local function Redeem(Player, SubmittedKeyCode)
local Data = {
["Generated"] = KeyDS:GetAsync(SubmittedKeyCode);
["Purchased"] = game:GetService("ServerStorage").GameCodes["Player_"..Player.userId];
}
if not string.match(SubmittedKeyCode, "PAIDKEY") then
if SubmittedKeyCode == Data["Generated"].KeyName then
if Data["Generated"].Duration > tick() then
if Data["Generated"].Uses > 0 then
KeyCodeModule.EditCodeData(SubmittedKeyCode, false)
print(Player.Name .. " has redeemed key '" .. Data["Generated"].KeyName .. "', which expires after: " .. Data["Generated"].Duration)
return "Redeemed"
else
return "Depleted"
end
else
return "Expired"
end
else
return false
end
elseif string.match(SubmittedKeyCode, "PAIDKEY") then
for _,KeyData in pairs(Data["Purchased"]:GetChildren()) do
if KeyData:IsA("Folder") then
if SubmittedKeyCode == KeyData.KeyName.Value then
if KeyData.Duration.Value > tick() then
if KeyData.Uses.Value > 0 then
KeyData.Uses.Value = KeyData.Uses.Value-1
Data["Purchased"].ActiveKey.Value = SubmittedKeyCode
Data["Purchased"].ActiveKey.Duration.Value = KeyData.Duration.Value
print(KeyData.Owner.Value .. " has redeemed key '" .. KeyData.KeyName.Value .. "', which expires after: " .. KeyData.Duration.Value .. " and has " .. KeyData.Uses.Value .. " uses left.")
return "Redeemed"
else
return "Depleted"
end
else
return "Expired"
end
end
end
end
return false
end
end
Variables.Remotes["EnteredKey"].OnServerInvoke = Redeem
local Products = {
["1 hour access"] = 165213438;
["8 hours access"] = 165213642;
["12 hours access"] = 165213776;
["168 hours access"] = 165214319;
["336 hours access"] = 165214425;
}
MarketplaceService.ProcessReceipt = function(receiptInfo)
local info = game:GetService("MarketplaceService"):GetProductInfo(receiptInfo.ProductId, Enum.InfoType.Product)
for i, Player in ipairs(game.Players:GetPlayers()) do
if Player.userId == receiptInfo.PlayerId then
if receiptInfo.ProductId == Products[info.Name] then
local KeyNumber = math.random(1, 100000)
local KeyData = game:GetService("ServerStorage").GameCodes["Player_"..Player.userId]
local NewKey = script.Data.KeyTemplate:Clone()
NewKey.Name = #KeyData:GetChildren().."-GameCode"
NewKey.Duration.Value = tick() + (string.gsub(string.gsub(info.Name, "%D+", ""), "%D+", "") * 3600)
NewKey.Owner.Value = Player.userId
NewKey.KeyName.Value = "PAIDKEY-" .. KeyNumber
NewKey.Uses.Value = 2
NewKey.Parent = KeyData
local KeyTable = {}
for i,key in pairs(KeyData:GetChildren()) do
if key:IsA("Folder") then
table.insert(KeyTable, {
["Duration"] = key.Duration.Value;
["KeyName"] = key.KeyName.Value;
["Owner"] = key.Owner.Value;
["Uses"] = key.Uses.Value;
})
end
end
for i,v in ipairs(KeyTable) do
print(i, v)
end
BoughtKeyDS:SetAsync(Player.userId.."_Keys", KeyTable)
Variables.Remotes["KeyPurchase"]:FireClient(Player, "PAIDKEY-" .. KeyNumber)
end
end
end
local PlayerProductKey = "Player_" .. receiptInfo.PlayerId .. "_purchase_" .. receiptInfo.ProductId
PurchaseHistory:IncrementAsync(PlayerProductKey, 1)
return Enum.ProductPurchaseDecision.PurchaseGranted
end
LocalScript
local RS = game:GetService("ReplicatedStorage")
local MarketplaceService = game:GetService("MarketplaceService")
local StarterGui = game:GetService("StarterGui")
local Variables = require(RS:WaitForChild("Modules"):WaitForChild("KeyCodes"):WaitForChild("Variables"))
local Player = script.Parent.Parent.Parent.Parent.Parent
local MainGUI = Player:WaitForChild("PlayerGui"):WaitForChild("KeyMenu");
local Input = MainGUI:FindFirstChild("KeyBox", true)
local Purchase = MainGUI:FindFirstChild("Purchase", true)
local Debounce = false
if game.Players.LocalPlayer.UserId ~= 416387433 then
StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.All, false)
Player:WaitForChild("PlayerGui"):SetTopbarTransparency(0)
MainGUI.Enabled = true
end
Purchase.MouseButton1Click:Connect(function()
MainGUI.Main.Body.Visible = false
MainGUI.Main.Shop.Visible = true
end)
for _,button in pairs(MainGUI.Main.Shop.Main:GetDescendants()) do
if button:IsA("GuiButton") then
button.MouseButton1Click:connect(function()
if Debounce == false then
Debounce = true
if string.gsub(button.Parent.Name, "%D+", "") == "1" then
MarketplaceService:PromptProductPurchase(game.Players.LocalPlayer, 165213438)
elseif string.gsub(button.Parent.Name, "%D+", "") == "8" then
MarketplaceService:PromptProductPurchase(game.Players.LocalPlayer, 165213642)
elseif string.gsub(button.Parent.Name, "%D+", "") == "12" then
MarketplaceService:PromptProductPurchase(game.Players.LocalPlayer, 165213776)
elseif string.gsub(button.Parent.Name, "%D+", "") == "168" then
MarketplaceService:PromptProductPurchase(game.Players.LocalPlayer, 165214319)
elseif string.gsub(button.Parent.Name, "%D+", "") == "336" then
MarketplaceService:PromptProductPurchase(game.Players.LocalPlayer, 165214425)
end
Debounce = false
end
end)
end
end
Input.FocusLost:Connect(function(enterPressed)
if enterPressed == true then
if Debounce == false then
if Input.Text ~= "" then
Debounce = true
local KeyCheck = Variables.Remotes["EnteredKey"]:InvokeServer(string.gsub(Input.Text, "%s+", "N/A"):sub(1,40))
if KeyCheck == "Redeemed" then
Input.Text = ""
Input.PlaceholderText = "Redeemed!"
wait(1)
MainGUI.Enabled = false
Player.PlayerGui:SetTopbarTransparency(0.4)
StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.All, true)
elseif KeyCheck == "Expired" then
Input.Text = ""
Input.PlaceholderText = "This key has expired; sorry!"
elseif KeyCheck == "Depleted" then
Input.Text = ""
Input.PlaceholderText = "This code has been depleted! Please, try another."
elseif KeyCheck == "Not Owner" then
Input.Text = ""
Input.PlaceholderText = "This is not your code!"
elseif KeyCheck == false then
Input.Text = ""
Input.PlaceholderText = "This key is invalid! Please check your spelling and try again."
end
Debounce = false
end
end
end
end)
Variables.Remotes["KeyPurchase"].OnClientEvent:Connect(function(Key)
MainGUI.Main.Shop.Visible = false
MainGUI.Main.Body.Visible = true
local LoggedKey = script.KeyTemplate:Clone()
LoggedKey.Key.Text = Key
LoggedKey.Nr.Text = "2U"
LoggedKey.Parent = MainGUI:FindFirstChild("KeyLog", true)
LoggedKey.Name = "2GameKey"
end)
What am I doing wrong?