My friend made this a long time ago and i need help with saving tables. Id like to have a function like “createTable” or something, like the “createValue” function. How would i edit this to support that?
Code:
local players = game:GetService("Players")
local dataStoreService = game:GetService("DataStoreService")
local serverStorage = game:GetService("ServerStorage")
local replicatedStorage = game:GetService("ReplicatedStorage")
local updateValueServer = serverStorage.UpdateValue
local requestValueServer = serverStorage.RequestValue
local updateValueClient = replicatedStorage:WaitForChild("DatastoreUpdateValue")
local requestValueClient = replicatedStorage.RequestValue
local dataStore = dataStoreService:GetDataStore("PlayerData")
function getAsync(player : Player)
local success = false
local attempts = 0
local data = nil
while success == false and attempts < 8 do
attempts += 1
success = pcall(function()
data = dataStore:GetAsync(tostring(player.UserId))
end)
task.wait(0.1)
end
return data, success
end
function setAsync(player : Player, valueName : string, value : string | number | boolean)
local success = false
local attempts = 0
while success == false and attempts < 8 do
attempts += 1
success = pcall(function()
local storedData = getAsync(player)
storedData[valueName] = value
dataStore:SetAsync(tostring(player.UserId), storedData, {player.UserId})
end)
task.wait(0.1)
end
end
function createPlayerData(player : Player)
local success = false
local attempts = 0
while success == false and attempts < 8 do
attempts += 1
success = pcall(function()
dataStore:SetAsync(tostring(player.UserId), {}, {player.UserId})
end)
task.wait(0.1)
end
end
function createValue(player : Player, valueName : string, defaultValue : string | number | boolean, valueLocation)
local newValue = nil
if type(defaultValue) == "string" then
newValue = Instance.new("StringValue")
elseif type(defaultValue) == "number" then
newValue = Instance.new("NumberValue")
elseif type(defaultValue) == "boolean" then
newValue = Instance.new("BoolValue")
end
newValue.Name = valueName
newValue.Parent = valueLocation
local storedData, success = getAsync(player)
if storedData == nil and success == true then
storedData = {}
createPlayerData(player)
end
local storedValue = storedData[valueName]
if storedValue ~= nil then
newValue.Value = storedValue
else
setAsync(player, valueName, defaultValue)
newValue.Value = defaultValue
end
end
function savePlayerData(player)
print("saved ".. tostring(player) .. "'s Data!")
--full system works
--saves every 10 seconds + when they leave
local leaderstats = player:FindFirstChild("leaderstats")
local settingsFolder = player:FindFirstChild("SettingsFolder")
for _, value : StringValue | NumberValue | BoolValue in pairs(leaderstats:GetChildren()) do
setAsync(player, value.Name, value.Value)
end
for _, value : StringValue | NumberValue | BoolValue in pairs(settingsFolder:GetChildren()) do
setAsync(player, value.Name, value.Value)
end
end
function onInvoke(player : Player, valueName : string)
local leaderstats = player:FindFirstChild("leaderstats")
local settingsFolder = player:FindFirstChild("SettingsFolder")
local checkValue : StringValue | NumberValue | BoolValue = leaderstats:FindFirstChild(valueName) or settingsFolder:FindFirstChild(valueName)
if checkValue then
return checkValue.Value
end
end
function onServerInvoke(player : Player, valueName : string)
local leaderstats = player:FindFirstChild("leaderstats")
local settingsFolder = player:FindFirstChild("SettingsFolder")
local checkValue : StringValue | NumberValue | BoolValue = leaderstats:FindFirstChild(valueName) or settingsFolder:FindFirstChild(valueName)
if checkValue then
if checkValue.Parent == settingsFolder then
return checkValue.Value
else
warn("Cannot access server-side data from client!")
return nil
end
end
end
requestValueServer.OnInvoke = onInvoke
requestValueClient.OnServerInvoke = onServerInvoke
players.PlayerAdded:Connect(function(player : Player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local settingsFolder = Instance.new("Folder")
settingsFolder.Name = "SettingsFolder"
settingsFolder.Parent = player
createValue(player, "MN:Kills", 0, settingsFolder)
createValue(player, "MN:Deaths", 0, settingsFolder)
createValue(player, "KB:Sprint", "LeftControl", settingsFolder)
createValue(player, "OT:WeaponUnlocks", "", settingsFolder)
end)
players.PlayerRemoving:Connect(function(player)
savePlayerData(player)
end)
updateValueServer.Event:Connect(function(player : Player, valueName : string, value : string | number | boolean)
local leaderstats = player:FindFirstChild("leaderstats")
local settingsFolder = player:FindFirstChild("SettingsFolder")
local checkValue : StringValue | NumberValue | BoolValue = leaderstats:FindFirstChild(valueName) or settingsFolder:FindFirstChild(valueName)
if checkValue then
checkValue.Value = value
end
end)
updateValueClient.OnServerEvent:Connect(function(player : Player, valueName : string, value : string | number | boolean)
local leaderstats = player:FindFirstChild("leaderstats")
local settingsFolder = player:FindFirstChild("SettingsFolder")
local checkValue : StringValue | NumberValue | BoolValue = leaderstats:FindFirstChild(valueName) or settingsFolder:FindFirstChild(valueName)
if checkValue then
if checkValue.Parent == settingsFolder then
checkValue.Value = value
else
warn("Cannot access server-side data from client!")
end
end
end)
while task.wait(10) do
for _, player in pairs(players:GetPlayers()) do
savePlayerData(player)
end
end