So ive been trying to make my datastore skills a bit more secure. I recently(Like 1 week ago lol) wrote this datastore module. Is there anything that could be improved in it or is it already good enough?
Also please dont just reply with “Looks good” or stuff like that. I want some actual feedback!
Module code:
local module = {}
-- // Create datastore
local Api = game:GetService("DataStoreService")
local Stats = Api:GetDataStore("-Stats", "_S")
-- // End
-- // Funcs used by the "core" functions?
function module:GetBudget(Type)
return Api:GetRequestBudgetForRequestType(Type)
end
function module:WaitForBudget(Type, Num)
repeat task.wait() until self:GetBudget(Type) >= Num
end
function module:GetNumPlrs()
return #game.Players:GetPlayers()
end
-- // End
-- // Main funcs
function module:Get(key)
if self:GetBudget(Enum.DataStoreRequestType.GetAsync) >= 60 + self:GetNumPlrs() * 10 then
local Tries = 0
local Sucess, Res = nil
repeat
Sucess, Res = pcall(Stats.GetAsync, Stats, key)
Tries = Tries + 1
task.wait()
until Sucess or not Sucess or Tries >= 5
if Sucess then
if Res ~= nil then
return Res
else
self:Set(key)
return nil
end
else
if type(Res) == "string" then
game.Players:GetPlayerByUserId(key):Kick("Roblox datastores seems to be down at this moment. Youve been kicked to protect your data.")
end
error(Res)
end
else
self:WaitForBudget(Enum.DataStoreRequestType.GetAsync, 60 + self:GetNumPlrs() * 10)
return self:Get(key)
end
end
function module:Set(Key)
if self:GetBudget(Enum.DataStoreRequestType.SetIncrementAsync) >= 60 + self:GetNumPlrs() * 10 then
local Tries = 0
local Sucess, Res = nil
local DataTemp = {
Stats = {
Coins = 0,
Wins = 0
}
}
repeat
Sucess, Res = pcall(Stats.SetAsync, Stats, Key, DataTemp)
Tries = Tries + 1
task.wait()
until Sucess or not Sucess or Tries >= 5
if Sucess then
warn("Sucessfully did a force save!")
else
warn("An error occured at forcing a save!")
error(Res)
end
else
self:WaitForBudget(Enum.DataStoreRequestType.SetIncrementAsync, 60 + self:GetNumPlrs() * 10)
self:Set(Key)
end
end
function module:Update(Key, NewData)
local function AttemptUpdate(Old)
for Key, Data in pairs(NewData.Stats) do
if Data >= Old.Stats[Key] then
Old.Stats[Key] = Data
end
end
return Old
end
if self:GetBudget(Enum.DataStoreRequestType.UpdateAsync) > 0 then
local Tries = 0
local Sucess, Res = nil
repeat
Sucess, Res = pcall(Stats.UpdateAsync, Stats, Key, AttemptUpdate)
Tries = Tries + 1
task.wait()
until Sucess or not Sucess or Tries >= 5
if Sucess then
warn("Sucessfully updated data!")
else
warn("An error occured at updating existing data!")
error(Res)
end
else
self:WaitForBudget(Enum.DataStoreRequestType.UpdateAsync, 5)
self:Update(Key, NewData)
end
end
-- // End
return module