So I have obtained the player’s Data from line 43 by activeData = GetDataRemoteFunction:InvokeServer()
, which prints out the player’s Data after putting a print statement a line below.
What I want to be able to do at this point is to change specifically the number of how much the player has of a particular resource. This is inside of a tool activated function, to further elaborate we’re collecting ‘resources’ as a player in this little game demo of mine.
How can I change the player’s Data using the instance “activeData” which I used as I explained earlier to get the player’s data?
PickaxeClient:
local ReplicatedStorage = game:GetService('ReplicatedStorage')
local RemotesFolder = ReplicatedStorage:WaitForChild('Remotes')
local GetDataRemoteFunction = RemotesFolder:WaitForChild('GetData')
local UpdateData = RemotesFolder:WaitForChild('UpdateData')
local player = game:GetService("Players").LocalPlayer
local Pickaxe = script.Parent
local PickaxeHandle = script.Parent.Handle
--local DataService = require(game.ServerStorage.Systems.DataService)
Pickaxe.Equipped:Connect(function()
--local Weld = Instance.new("Weld")
--Weld.Name = "PickaxeWeld"
--Weld.Parent = player.Character.LeftHand
--Weld.Part0 = player.Character.LeftHand
--Weld.Part1 = PickaxeHandle
end)
resources = {}
local function IsPlayerInProximity(boolstatement)
boolstatement = false
--if player.Character.
return boolstatement
end
local activeData = nil
Pickaxe.Activated:Connect(function(LocalPlayer, Object)
local resourceItem = nil
for i,v in pairs(game.Workspace.Collectables:GetChildren()) do
resourceItem = v
if (player:DistanceFromCharacter(v.Main.Position) <= 8) then
local mouse = player:GetMouse()
if mouse.Target.Name == "Main" then
print("Collected +1 "..v.Name)
activeData = GetDataRemoteFunction:InvokeServer()
print(activeData)
for itemID, quantity in pairs(activeData.Inventory) do
print(activeData)
end
end
end
end
end)
DataService:
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local ServerModules = ServerStorage:WaitForChild("Modules")
local ProfileService = require(ServerModules:WaitForChild("ProfileService"))
local ProfileTemplate = {
-- game values
Cash = 0,
Gems = 0,
Quests = { },
Inventory = { },
-- analytic
LogInTimes = 0,
TotalGameTime = 0,
}
local GameProfileStore = ProfileService.GetProfileStore("PlayerData2", ProfileTemplate)
local Profiles = {}
local JoinTimes = {}
local function FloorNumber(number, decimalPlaces)
decimalPlaces = decimalPlaces or 2 -- this is saying that if decimalPlaces is not given, just make it "2"
return math.floor(number * math.pow(10, decimalPlaces)) / math.pow(10, decimalPlaces)
end
local function OnPostProfileLoad(player, profile)
print(profile)
profile.Data.LogInTimes += 1
local totalLogins = profile.Data.LogInTimes
print( string.format('%s has logged in %s time%s', player.Name, totalLogins, (totalLogins > 1) and 's' or '') )
print( ' This player has played a total of ' ..profile.Data.TotalGameTime..' seconds before joining this server.' )
for i, str in ipairs( profile.Data.Inventory ) do
print(i, str)
if profile.Data.Inventory[str] then
profile.Data.Inventory[str] += 1
else
profile.Data.Inventory[str] = 1
end
table.remove(profile.Data.Inventory, i)
end
-- ^ ^ ^------------------------.
-- player time here specific login number here time or time(s) depending on the number of login times
-- ex)
-- SPOOK_EXE has logged in 1 time.
-- SPOOK_EXE has logged in 2 times.
JoinTimes[player] = tick()
end
local function PlayerAdded(player)
local profile = GameProfileStore:LoadProfileAsync(tostring(player.UserId))
if profile then
profile:AddUserId(player.UserId) -- GDPR compliance
profile:Reconcile() -- putting all missing template values into the active data ( optional )
profile:ListenToRelease(function()
Profiles[player] = nil
-- The profile could've been loaded on another Roblox server:
player:Kick('Profile has been loaded onto another Server.')
end)
if player:IsDescendantOf(Players) then
OnPostProfileLoad(player, profile)
Profiles[player] = profile
else
-- Player left before the profile loaded:
profile:Release()
end
else
player:Kick('Failed to Load Data : OnPlayerAdded_1')
end
end
--Lets say you have a Admin Panel and you try to edit the player's data, it will kick them from the server
-- // Module // --
local Module = {}
function Module:GetPlayerProfile(Player, Yield)
local profile = Profiles[Player]
if Yield and not profile then
repeat task.wait(0.1)
profile = Profiles[Player]
until profile or (not Player.Parent)
end
return profile
end
function Module:Init()
for _, player in ipairs(Players:GetPlayers()) do
coroutine.wrap(PlayerAdded)(player)
end
Players.PlayerAdded:Connect(PlayerAdded)
Players.PlayerRemoving:Connect(function(player)
local profile = Profiles[player]
if profile then
--add the duration they've played to the data
local duration = tick() - JoinTimes[player]
--profile.Data.TotalGameTime += duration
--profile.Data.TotalGameTime = FloorNumber(profile.Data.TotalGameTime, 3)
--print( string.format('%s has played a total of %s seconds this session, totalling the total to %s seconds', player.Name, FloorNumber(duration), profile.Data.TotalGameTime))
JoinTimes[player] = nil
--release the profile so other games can load it
profile:Release()
end
end)
end
return Module
Now I know this looks pretty dumb and you might ask, “Why are you trying to do this when the other functionality doesn’t work?” Well I will come back to fixing everything else, but right now I just want to update the player’s data.
Attached below is a video.