I’ve decided to make a global data-saving script for a game that I work on. This is mainly done to fix the datastore issues the game has been having and combining it into one helps tremendously.
I have each script that requires a data saving / receiving to fire a bindablefunction to receive it. I added a total of attempts for each data saving /receiving. I haven’t tested the attempts yet as I don’t know how I can make it error (if anyone knows how please let me know)
After the three attempts, if data fails to save it will send a webhook to Discord and will allow the developers to manually add any data in a last resort situation.
My code:
local Event = script.StoreData
local DataStorage = {}
local Webhook = "hidden"
local HttpService = game:GetService('HttpService')
local MaxAttempts = 3
function DataStorage:RecordDataLoss(player, type1, data)
local content
if type1 == "SetAsync" then
local data_send = " "
for i, v in next, data do
data_send = data_send .. i .." : ".. tostring(v).. " "
end
content = {
['content'] = "Type of data loss: "..type1.. " Data lost for player: ".. player.Name .. " ("..player.UserId..') '.. data_send
}
elseif type1 == "GetAsync" then
content = {
['content'] = "Type of data loss: "..type1.. " if data loss is GetAsync then no data will be lost, pew pew"
}
end
content = HttpService:JSONEncode(content)
HttpService:PostAsync(Webhook, content)
end
--local data = {money = 100, rebirth = 3}
--DataStorage:RecordDataLoss(game.Players.SovereignObesity, "SetAsync", data)
function DataStorage:SetData(player, ds, key, data, attempts)
if not player:FindFirstChild('DSFail') then
local success, data = pcall(function()
ds:SetAsync(key, data)
end)
if success then
warn('Success in saving data')
return true
else
warn('Failed to save data')
DataStorage:RecordDataLoss(player, "SetAsync")
if attempts >= 0 then
attempts = attempts - 1
return DataStorage:SetData(player, ds, key, data, attempts)
else
return false
end
end
end
end
function DataStorage:GetData(player, ds, key, attempts)
local dataToInput
local success, data = pcall(function()
dataToInput = ds:GetAsync(key)
end)
if success then
if not dataToInput then
warn('Failed to get dataToInput (no data exists in key: '..key..')')
return nil
else
warn('Success in getting data')
return dataToInput
end
else
warn('Failed to get data')
local a = Instance.new('BoolValue', player)
a.Name = "DSFail"
DataStorage:RecordDataLoss(player, "GetAsync")
if attempts >= 0 then
attempts = attempts - 1
return DataStorage:GetData(player, ds, key, data, attempts)
else
player:Kick('Failed to load data')
return false
end
end
end
--local args = {'text'}
--local args2 = unpack({args})
--print(args[1])
function Main(Type, ...)
local args = unpack({...})
if args.Player then
warn('Got player')
if Type == "SetData" then
warn('Found type 1')
return DataStorage:SetData(args.Player, args.Datastore, args.Key, args.Data, MaxAttempts)
elseif Type == "GetData" then
warn('Found type 2')
return DataStorage:GetData(args.Player, args.Datastore, args.Key, MaxAttempts)
else
warn('No type given')
end
end
end