(PROFILE SERVICE) Load profile of offline player

Alr so, since I know the userid of the player I want to change data to, I just loaded its profile like this:

withdrawerProfile = GameProfileStore:LoadProfileAsync(
	"Player_" .. gamepassInfo.Creator.Id
)

But if that player is playing in another server he gets kicked from it. Will the “Steal” method make this not happen anymore?

withdrawerProfile = GameProfileStore:LoadProfileAsync(
	"Player_" .. gamepassInfo.Creator.Id,
	"Steal"
)

Thanks!

3 Likes

I’d love to help you with this as I’ve used profile service before but you have to be more descriptive of your question or problem.

I want to change a profiles data in a server that doesn’t have the player on it. Im actualy able to load its profile since I know the UserId of the player to load. But, if the server loads the profile and that player is indeed active in another server he gets kicked due to session locking. How do I load a players profile which is playing in another server without kicking him due to session locking?

Thought Steal would work, but it doesnt

I don’t know how to do this in profile service but I can tell you the logic behind doing what you want

the simple option is to just use globalupdate and let the server that opens the session handle it when the player enters the server

if thats not a option then here is a option

-- try to open the session when a player enters the server
-- don't kick them if the session is locked wait a bit and try again
local function OnPlayerAdded(player)
    while playerisonline do
        local success = TryToOpenTheSession()
        if success then break end
        task.wait(10) -- give some time for the other server to close the session 
    end
end

local function update()
    if playerIsOnline() then
        UpdateThemLocally()
    else
        local success = tryToOpenSesstion()
        if success then
            updateTheProfilethenclosethesession()
        else
            useglobalupdatetoTelltheotherservertoupdate()
        end
    end
end





Here is a example using Suphi’s DataStore Module
how to load the players datastore

local DataStoreModule = require(11671168253)

local template = {
    Level = 0,
    Coins = 0,
}

local function StateChanged(state, dataStore)
    while dataStore.State == false do
        if dataStore:Open(template) ~= "Success" then task.wait(6) end
    end
end

game.Players.PlayerAdded:Connect(function(player)
    local dataStore = DataStoreModule.new("Player", player.UserId)
    dataStore.StateChanged:Connect(StateChanged)
    StateChanged(dataStore.State, dataStore)
end)

game.Players.PlayerRemoving:Connect(function(player)
    local dataStore = DataStoreModule.find("Player", player.UserId)
    if dataStore ~= nil then dataStore:Destroy() end
end)

and this is how we update the datastore even if the player is offline

local DataStoreModule = require(11671168253)

local function Update(player, amount)
    -- try to find a local datastore or make a hidden datastore
    local dataStore = DataStoreModule.find("Player", player.UserId) or DataStoreModule.hidden("Player", player.UserId)
    local response, message = dataStore:Open(template)    -- try to open the session
    if response == "Success" then                         -- if we open the session 
        dataStore.Value.Coins += amount                   -- make a change
    elseif response == "Locked" then                      -- if the session is locked
        local response, message = dataStore:Queue(amount) -- send a message to the server that has the lock
        -- WARNING Queues dont last forever if you dont process them within the expiration time
        if dataStore ~= "Success" then warn(message) end  -- if we fail to send a message then print why
    else
        warn(message)                                     -- if all fails print why
    end
    if dataStore.Hidden then dataStore:Destroy() end      -- if this is a hidden datastore destroy it
end

1 Like

so I Should to that with global updates?

yes that would be the easiest and most secure method

just add a global update and when the player enters any server process it at that time

1 Like
pcall(function()
			local withdrawerPlayer = Players:GetPlayerByUserId(gamepassInfo.Creator.Id)
			local withdrawerProfile = nil
			
			local wasProfileGlobal = false
			
			if not Manager.Profiles[withdrawerPlayer] then
				local success = pcall(function()
					PublicProfilesDataStore:UpdateAsync("Player_" .. gamepassInfo.Creator.Id, function(value)
						if value and value.Data then
							print("Before edit withdrawing: " .. tostring(value.Data.Withdrawing))
							
							-- Safely update the Withdrawn and Withdrawing values
							value.Data.Withdrawing = value.Data.Withdrawing - gamepassPrice
							value.Data.Withdrawn = value.Data.Withdrawn + gamepassPrice
							
							print("After edit withdrawing: " .. tostring(value.Data.Withdrawing))

							return value
						end
					end)
				end)
				
				if success then
					print("Successfully updated global profile Data")
					
					wasProfileGlobal = true
				end
			else
				withdrawerProfile = Manager.Profiles[withdrawerPlayer]
			end

			if withdrawerProfile then
				withdrawerProfile.Data.Withdrawing -= gamepassPrice
				withdrawerProfile.Data.Withdrawn += gamepassPrice

				withdrawerProfile:Release()
			else
				if not wasProfileGlobal then
					warn("Player purchased a gamepass from the queue, but the withdrawer profile data coulnd't be updated.")
				end
			end
		end)

Before trying the global updates method I just tried using normal datastores handling, and it seems to change the data properly. does this still lead to session locking?

I’m now switching to global updates btw, just to make sure

if your bypassing profile service and just updating the datastore directly then if another server has the session open it will overwrite any changes you make

1 Like

It means that the changes won’t be saved?

profile service will save its cached data that is saved locally on the server into the datastore every 30 seconds so it will save but then after about 30 seconds profile service will save over it with its cached data

but remember that i don’t really know how profile service works im just using what is logically sound to guess what profile service is doing

holy crap. I have to change this fast before causing too many problems. I hate updates!!!

GameProfileStore:GlobalUpdateProfileAsync("Player_" .. gamepassInfo.Creator.Id, function(global_updates)
					global_updates:AddActiveUpdate({
						CreditsWithdrawn = gamepassPrice,
						PurchaserId = player.UserId
					})
				end)

will something like this work? How do I load global updates when the player joins? Sorry but I never used global updates