Get a player from UUID

As by title i’m trying to get a player from a UUID. Currently i use this code

public static Player getPlayer(UUID id) {
		UserStorageService userStorage = Sponge.getServiceManager().provide(UserStorageService.class).get();
		Collection<GameProfile> profiles = userStorage.getAll();

		for(GameProfile profile : profiles) {
		    Optional<User> optionalUser = userStorage.get(profile);
				    
		    if(optionalUser.isPresent()) {
		        Player p = optionalUser.get().getPlayer().get();
		        if(p.getUniqueId() == id) {
		        	return p;
		        }
		    	
		    }
		}
		return null;
	}

but when it runs it gives a NoValuePresent exception at this line

 Player p = optionalUser.get().getPlayer().get();

So what is wrong with this code?

First, you never check that the user is online. A Player represents an online User, so you need to check isPresent() before the second get().

Second, Sponge has some code to do all that for you, and slightly faster: Sponge.getServer().getPlayer(uuid)

I didn’t know that. Does it return offline players too? Because i need to get them as well

A Player is someone who is online. There is no way to get a Player object for someone who is offline.

What you want are User objects. A User is someone who has joined the server before, but is not necessarily online. A Player is a User who is online.

You can retrieve User objects from the UserStorageService as described in the docs.

To avoid going in wrong directions: What do you want to do with the “Offline Player” ?

1 Like

Getting the name of an offline player based on a uuid

In this case you do not need to bother with Users at all; simply use the GameProfileManager as described here.

If you only need the name for Players that have been on your Server at least once:

public Optional<String> getNameForUuid(UUID uuid){
	UserStorageService uss = Sponge.getServiceManager().provideUnchecked(UserStorageService.class);
	Optional<User> oUser = uss.get(uuid);
	
	if (oUser.isPresent()){
		// the name with which that player has been online the last time
		String name = oUser.get().getName();
		return Optional.of(name);
	} else {
		// a player with that uuid has never been on your server
		return Optional.empty();
	}
}

If you also need names for players that have never been on your server:

public Optional<String> lookupNameForUuid(UUID uuid){
	GameProfileManager gpm = Sponge.getServiceManager().provideUnchecked(GameProfileManager.class);
	
	try {
		GameProfile gp = gpm.get(uuid).get(10, TimeUnit.SECONDS);
		return gp.getName();
	} catch (InterruptedException | ExecutionException | TimeoutException ex){
		return Optional.empty();
	}
}

But please don’t use the last method on the main Thread! This method asks mojang’s servers for the name and that request can take a while. So run it asynchronously or do something else then get() on the CompletableFuture :smiley:

Thanks for the answer, i’ll use the first method since i need only the name of players who has been on the server at least once :smiley:

I’d suggest against contacting Mojang’s servers regardless. Most of the information you should need should already be there.