How can I load profile without Player object (ProfileService)

This is how I get the player data normally.
local function PlayerAdded(player: Player)
	player:SetAttribute("Ready", false)
	
	local profile = PlayerProfileStore:LoadProfileAsync("Player_".. player.UserId, "ForceLoad")
	if not profile then issue(player, "Unable to load the profile.", true) return end

	profile:Reconcile()
	
	profile:ListenToRelease(function()
		CachedProfiles[player] = nil
		issue(player, "Has been disconnected from the server because profile was released.", true)
	end)

	if player:IsDescendantOf(Players) then
		CachedProfiles[player] = profile
		PlayerDataLoaded(player)
	else
		profile:Release()
	end
end

However I need to read and write into profile of a player that is not in the game. However I see that I need player object to do the following…

profile:ListenToRelease(function()
	CachedProfiles[player] = nil
	issue(player, "Has been disconnected from the server because profile was released.", true)
end)

if player:IsDescendantOf(Players) then
	CachedProfiles[player] = profile
	PlayerDataLoaded(player)
else
	profile:Release()
end

How can I get profile to read and write into it with just UserId?

Why do I need this?

I need this so I can change stuff for the player with commands even if they are not in the game.

2 Likes

I think you need to research the Global Updates mechanism. This would allow you to push updates into a player profile even if they’re currently online.

https://madstudioroblox.github.io/ProfileService/api/#global-updates

However, when you push a global update to an offline player, the changes will not be reflected until they are online, as your game will need to process the changes when the player joins.

This is mainly good for gifting, but would also work in your scenario, as it wouldn’t release the session lock for players who are in game—Meaning the player won’t be kicked if they’re in game in another server.

1 Like

I am planning to use this so I can ban players. So it won’t work? or will it?

For banning, it wouldn’t matter if you release their session lock and kick them then.

You’re indexing profile stores by the player’s user ID, so you just need to load their store by requesting the profile store with their user ID.

You can get a player’s user ID from their username (even if they’re offline) using Players:GetUserIdFromNameAsync

https://developer.roblox.com/en-us/api-reference/function/Players/GetUserIdFromNameAsync

5 Likes

Oh, I just forgot that CachedProfiles is my variable :roll_eyes:. So I just do this?

local function Do(userId: number)
	local profile = PlayerProfileStore:LoadProfileAsync("Player_".. userId, "ForceLoad")
	if not profile then return end

	profile:Reconcile()
	
	profile:ListenToRelease(function()
		profile = nil
	end)
	
	profile.Data = ProfileFulfillment:Verify(userId, profile.Data)
	profile.Data.Ban.Active = true
	
	profile:Release()
end

in all fairness, if you’re banning them you don’t need to bother with reconciling the data, you also don’t need the ListenToRelease callback

the rest should be good though

(I probably wouldn’t name the function “Do,” though, just to avoid confusion with the global keyword do)

That’s just temporary name, since I am still thinking what I want to do.

local function BanPlayer(userId: number)
	local profile = PlayerProfileStore:LoadProfileAsync("Player_".. userId, "ForceLoad")
	if not profile then return end
	
	profile:Reconcile()
	
	if profile.Data.Ban ~= nil then
		if profile.Data.Ban.Active ~= nil then
			profile.Data.Ban.Active = true
		end
	end
	
	profile:Release()
end
1 Like

looks fine to me, but again you can remove the reconcile. this is used to “fill in” missing data; for example, if you added a new stat to your game. you don’t need to waste any resources with reconciliation if you’re just banning the player

What if ban property doesn’t exist on the player? My game had serious datastore issues because of my lack of knowledge in the past and there was no such thing as Ban key in the player data.

local function BanPlayer(userId: number)
    local profile = PlayerProfileStore:LoadProfileAsync("Player_".. userId, "ForceLoad")
    if not profile then return end
	
    if not profile.Data.Ban then
        profile.Data.Ban = {}
    end

    if not profile.Data.Ban.Active then
        profile.Data.Ban.Active = true
    end
	
    profile:Release()
end

you can just create the ban table if it doesn’t exist

So it will create key for Ban automatically? I didn’t know that. Thanks.

yep! if profile.Data.Ban doesn’t exist, create it

While your here, I’m working gonna start working on a logging system here in the next few days [In-Game cad system for getting players arrest history etc while they are offline]

I don’t need to override any of the players data I just need ReadOnly values would the

ProfileStore:ViewProfileAsync(profile_key, version) - Work for this?
And to add onto it how would I get the version? If it left it blank does it get the latest?

I’ve just started using ProfileService a little over a week ago so I’m not too familiar with the API.

I was talking about ProfileService, I don’t really know much on whats going on behind the scenes and I dont feel like going through 2K lines of code…, and I have hard time understanding documentation like always.

Here is the final code.

local function BanPlayer(userId: number, active: boolean)
	local profile = PlayerProfileStore:LoadProfileAsync("Player_".. userId, "ForceLoad")
	if not profile then return end
	
	if not profile.Data.Ban then
		profile.Data.Ban = {
			active = false
		}
	end
	
	profile.Data.Ban.Active = active
	
	profile:Release()
end

According to the documentation you can leave it nil (blank).

ProfileStore:ViewProfileAsync(profile_key, version) --> [Profile] or nil
-- profile_key   [string] -- DataStore key
-- version       nil or [string] -- DataStore key version

I think?

2 Likes

that should work! obviously you might need to adjust this if you want to be able to ban people who have never played before, as you’re returning on the second line if the profile doesn’t exist

Oh, I forgot about that case. But won’t profile be returned still even if player never played before? Because when player joins I do pretty much the same thing.

yes, sorry; you’re right. the profile is only nil if profileservice runs into a problem—its been a while since I used profileservice

1 Like