for some reason when i’m running this, it overwrites the default datatemplate which does so when u try to get the data, it returns the data as the modified table. I really don’t know how to fix this.
for some reason when i’m running this, it overwrites the default datatemplate which does so when u try to get the data, it returns the data as the modified table. I really don’t know how to fix this.
The default data template you are using is passed by reference when you return it in your GetDataForUserId function. This means that any modification to data will change the original instance of data which is why the table is being modified. You need to use table.clone() or return a new deep copy of your template table when assigning default data to a new player.
I didnt gift it the gamepass but i gifted a previous user the gamepass. Its still saying he owns it and from the servercode that prints both the originasl template and his data, it says he owns it. The preivous user did not own it before i purchased.
-- Gift VIP
[2662160435]=function(playerid,productid)
local player = game.Players:GetPlayerByUserId(playerid)
if not player then return Enum.ProductPurchaseDecision.NotProcessedYet end
local data = require(game.ReplicatedStorage.Modules.Server.Manager).Datas[player]
if not data then return Enum.ProductPurchaseDecision.NotProcessedYet end
local gifting = player:GetAttribute("GiftingPlayer")
if gifting == "" then return Enum.ProductPurchaseDecision.NotProcessedYet end
local giftingData = DataStore:GetAsync(gifting)
if not giftingData then
giftingData = table.clone(require(game.ReplicatedStorage.Modules.Server.DataTemplate))
end
if not giftingData then return Enum.ProductPurchaseDecision.NotProcessedYet end
if not giftingData.Passes then return Enum.ProductPurchaseDecision.NotProcessedYet end
if table.find(giftingData.Passes, 960021336) then return Enum.ProductPurchaseDecision.NotProcessedYet end
table.insert(giftingData.Passes,960021336)
giftingData.Gifts["VIP"]=playerid
DataStore:SetAsync(gifting, giftingData)
MsgService:PublishAsync("Gift", {"VIP", playerid, gifting, 960021336}) -- [1]=AssetType, [2]=from, [3]=to, [4]=passid
return Enum.ProductPurchaseDecision.PurchaseGranted
end,
The code that returns the offline playerdata
game.ReplicatedStorage.Remotes.GetDataForUserId.OnServerInvoke = function(plr,id)
local data = DataStore:GetAsync(id)
if not data then
data = table.clone(require(game.ReplicatedStorage.Modules.Server.DataTemplate))
end
return data
end
Because you have nested tables, table.clone returns a shallow copy, meaning it will not clone the tables inside, so modifying them will also modify the tables in the template. To fix this, you just need to use a deep copy function. This is pretty easy to implement yourself with recursion, but you could also find an example on the fprum.
Here’s a function that can be used to copy everything in the table:
function deepcopy(t) {
local nt = {}
for i, v in pairs(t) do
if type(v) == 'table' then
nt[i] = deepcopy(v) --use a copy instead
else
nt[i] = v
end
end
return nt
}
I was just going to go that way…
Put this on top of the purchase handler
local function deepClone(tbl)
local copy = {}
for key, value in pairs(tbl) do
if type(value) == "table" then
copy[key] = deepClone(value)
else
copy[key] = value
end
end
return copy
end
Then call; giftingData = deepClone(DataTemplate)
A freash new untainted data set to work with every time.