The data module provides a straightforward system which allows players to save and access their data, which works similar to ProfileService. The system provides users with a lightweight solution which they can easily use while creating their games.
local Players = game:GetService("Players")
local RS = game:GetService("ReplicatedStorage")
local SSS = game:GetService("ServerScriptService")
local DSS = game:GetService("DataStoreService")
local DSSKey = "_Molo"
local DS = DSS:GetDataStore("DaMoloTest")
local DataTemplate = require(script.DataTemplate)
local RSS = game:GetService("RunService")
local DaDataModule = {}
local DaDataTable = {}
local DaLoadedPlayer = {}
local DaSessionId = game.JobId
local DaForceLoadTime = 10
local function CopyDaTemplateToDaPlayer(Profile)
local ProfileA = {}
for Data, DaThing in pairs(Profile) do
if type(DaThing) == "table" then
ProfileA[Data] = CopyDaTemplateToDaPlayer(DaThing)
else
ProfileA[Data] = DaThing
end
end
return ProfileA
end
local function ReconcileDaData(Data, Template)
for Key, Value in pairs(Template) do
if Data[Key] == nil then
if type(Value) == "table" then
Data[Key] = CopyDaTemplateToDaPlayer(Value)
else
Data[Key] = Value
end
elseif type(Data[Key]) == "table" and type(Value) == "table" then
ReconcileDaData(Data[Key], Value)
end
end
end
local function DaOwnsSession(Data)
return Data and Data.DaSessionId == DaSessionId
end
function DaDataModule.LoadDaPlayerData(Player)
local DaReturn
local DaStartTime = os.clock()
while true do
local Success, Result = pcall(function()
return DS:UpdateAsync(Player.UserId .. DSSKey, function(OldData)
if OldData and OldData.DaSessionId and OldData.DaSessionId ~= DaSessionId then
if os.clock() - (OldData.DaLastUpdate or 0) < DaForceLoadTime then
return OldData
end
end
local NewData = OldData or CopyDaTemplateToDaPlayer(DataTemplate)
NewData.DaSessionId = DaSessionId
NewData.DaLastUpdate = os.clock()
return NewData
end)
end)
if Success and Result and Result.DaSessionId == DaSessionId then
DaReturn = Result
break
end
if os.clock() - DaStartTime >= DaForceLoadTime then
Player:Kick("Molo Attack")
return
end
task.wait(1)
end
ReconcileDaData(DaReturn, DataTemplate)
DaDataTable[Player.UserId] = DaReturn
DaLoadedPlayer[Player.UserId] = true
return DaDataTable[Player.UserId]
end
function DaDataModule.SaveDaPlayerData(Player)
if not RSS:InStudio() and DaLoadedPlayer[Player.UserId] then
for I = 1, 3 do
local Success = pcall(function()
DS:UpdateAsync(Player.UserId .. DSSKey, function(OldData)
if not DaOwnsSession(OldData) then
return OldData
end
local Data = DaDataTable[Player.UserId]
if Data then
Data.DaLastUpdate = os.clock()
end
return Data
end)
end)
if Success then
break
end
task.wait(1)
end
end
DaDataTable[Player.UserId] = nil
DaLoadedPlayer[Player.UserId] = nil
end
function DaDataModule.GetDaData(Player)
return DaDataTable[Player.UserId]
end
Players.PlayerAdded:Connect(function(Player)
DaDataModule.LoadDaPlayerData(Player)
end)
Players.PlayerRemoving:Connect(function(Player)
DaDataModule.SaveDaPlayerData(Player)
end)
game:BindToClose(function()
for _, DaPlayer in pairs(Players:GetPlayers()) do
task.spawn(function()
DaDataModule.SaveDaPlayerData(DaPlayer)
end)
end
task.wait(3)
end)
return DaDataModule