I am making a UGC Code System but I have a error,
DataStoreService: CantStoreValue: Cannot store Dictionary in data store. Data stores can only accept valid UTF-8 characters. API: SetAsync, Data Store: CodeDataStore (x5)
Script :
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
--Credits: made by Nico_Nic77 / Crafter1338 (yt,discord)
----Services:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local DataStoreService = game:GetService("DataStoreService")
local MarketplaceService = game:GetService("MarketplaceService")
----Datastores:
local RedeemDataStore = DataStoreService:GetDataStore("RedeemDataStore")
local CodeDataStore = DataStoreService:GetDataStore("CodeDataStore")
----Settings:
local maxTries = 2 --for recursion
local tryCooldown = 1 --seconds
----module:
local module = {}
local function safeGetAsync(datastore,key,index)
index = index or 0
if index > maxTries then return {key,nil} end
local succes,value = pcall(function()
return datastore:GetAsync(key)
end)
if succes then
return {key,value}
end
task.wait(tryCooldown)
return safeGetAsync(index + 1) --recursive function
end
local function safeSetAsync(datastore,key,value,index)
index = index or 0
if index > maxTries then return false end
local succes = pcall(function()
return datastore:SetAsync(key,value)
end)
if succes then
return true
end
task.wait(tryCooldown)
return safeSetAsync(index + 1) --recursive function
end
function module.createCode(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;
}
print(safeSetAsync(CodeDataStore,codeName,newCode))
end
function module.removeCode(codeName)
local s = safeSetAsync(CodeDataStore, codeName, nil)
return s
end
local function promptPlayer(player,assetId)
MarketplaceService:PromptPurchase(player, assetId)
end
function module.redeemCode(player,codeName)
local code = safeGetAsync(CodeDataStore,codeName)[2]
if code then
if code.active < tick() and code.active > 0 then
module.removeCode(codeName)
return
end
local check = safeGetAsync(RedeemDataStore,player.UserId)
if typeof(check) ~= "table" then check = {} end
if table.find(check,codeName) then print("player already used that code!") return end
table.insert(check,codeName)
local s = safeSetAsync(RedeemDataStore,player.UserId,check)
if s then
promptPlayer(player,code.itemId)
return true
end
warn("error while reedeming code!")
else
return false
end
end
return module
--Credits: made by Nico_Nic77 / Crafter1338 (yt,discord)
The main issue was that OP didn’t use code and codeName correctly! Always check your types my guys!