local CodeManager = {}
local codes = {}
local DataStoreService = game:GetService("DataStoreService")
local codeDataStore = DataStoreService:GetDataStore("CodeDataStore")
function CodeManager.AddCode(code, itemID, quantity, creatorUserID)
if code == "" then
warn("Key name can't be empty.")
return
end
codes[code] = {
ItemID = itemID,
Quantity = quantity,
CreatorUserID = creatorUserID,
RedeemerUserID = nil,
RedeemedAt = nil,
}
local success, err = pcall(function()
codeDataStore:SetAsync(code, codes[code])
end)
if not success then
warn("Failed to save code to DataStore:", err)
end
end
function CodeManager.GetCodeInfo(code)
return codes[code]
end
function CodeManager.RedeemCode(code, redeemerUserID)
local codeInfo = codes[code]
if codeInfo and not codeInfo.RedeemerUserID then
codeInfo.RedeemerUserID = redeemerUserID
codeInfo.RedeemedAt = os.time()
local success, err = pcall(function()
codeDataStore:SetAsync(code, codes[code])
end)
if not success then
warn("Failed to save updated code to DataStore:", err)
end
return true
else
return false
end
end
function CodeManager.RemoveCode(code)
codes[code] = nil
local success, err = pcall(function()
codeDataStore:RemoveAsync(code)
end)
if not success then
warn("Failed to remove code from DataStore:", err)
end
end
function CodeManager.LoadCodesFromDataStore()
local success, result = pcall(function()
local keys = codeDataStore:ListKeysAsync():GetCurrentPage()
for _, key in ipairs(keys) do
local success, value = pcall(function()
return codeDataStore:GetAsync(key)
end)
if success then
codes[key] = value
else
warn("Failed to load code from DataStore:", value)
end
end
end)
if not success then
warn("Failed to load codes from DataStore:", result)
end
end
return CodeManager
I’ts not a good idea to load all keys from a datastore and then check whether the “code” exists. It would be better if you tried to :GetAsync(redeemCode) and check if that code is correct.
In your dataStructure for the code item
I see RedeemerUserID - That’s only gonna be working if every code can onlly ne used by one single person! I’d say you create that code item without Redeemer or RedeemedAt and then store the code in the codes datastore, whenever a user tries to redeem a code, check if the code they tried to redeem is in the codes datastore - if it is: check a redeemdatastore for the player and check if the code has already been redeemed by that player:
if table.find(redeemDataStore:GetAsync(player.UserId) , codeTheyRedeemedId) then
print("code alr redeemed")
return
end
local DataStoreService = game:GetService("DataStoreService")
local RedeemDataStore = DataStoreService:GetDataStore("RedeemDataStore")
local CodeDataStore = DataStoreService:GetDataStore("CodeDataStore")
local maxTries = 5
local tryCooldown = 2 --seconds
local CodeManager = {}
local function createCode(codeName,code,INDEX)
if INDEX > maxTries then
warn(tostring(codeName).." could not be saved!")
return
end
local success = pcall(function()
CodeDataStore:SetAsync(codeName,code)
end)
if success then
print("success")
return
end
task.wait(tryCooldown)
createCode(codeName,code,INDEX+1) --recursion
end
local function checkCodeName(codeName)
local success,code = pcall(function()
CodeDataStore:GetAsync(codeName)
end)
if success and code and code["active"] > tick() or code["active"] < 0 then
return true,code
end
return false
end
function CodeManager.newCode(codeName,itemId,count,creatorId,lifeTime) --lifetime in seconds or -1 for infinite
local newCode = {
itemId = itemId,
itemC = count,
active = tick() + (lifeTime > 0 and lifeTime) or (-2*tick()),
creatorId = creatorId;
}
createCode(string.lower(codeName),newCode,1)
end
local function giveItem(player,code)
end
local function playerRedeemCode(player,codeName,data,code)
local newData = table.insert(data["codes"],codeName)
local success = pcall(function()
CodeDataStore:SetAsync(player.UserId,newData)
end)
giveItem(player,code)
end
function CodeManager.redeemCode(player,codeName)
local codeName = string.lower(codeName)
local state,code = checkCodeName(codeName)
if state == true then
local success,data = pcall(function()
CodeDataStore:GetAsync(player.UserId)
end)
if success then
if data["codes"] and not table.find(data["codes"],codeName) then
playerRedeemCode(player,codeName,data,code)
end
else
RedeemDataStore:SetAsync(player.UserId,{})
data = {codes = {}}
playerRedeemCode(player,codeName,data,code)
end
end
end
return CodeManager
I am having this error now :
DataStoreService: CantStoreValue: Cannot store Dictionary in data store. Data stores can only accept valid UTF-8 characters. API: SetAsync, Data Store: CodeDataStore (x5)
The error occurs because you’re possibly using a type of character encoding that is not UTF-8. It could possibly be a character issue. Could you please provide the data you’re trying to store? (Perhaps by printing it out?)