#719: Add Player Profile API

Slight changes may occur as this API is stabilized.

This PR is based on work previously done by DerFrZocker in #663.

By: blablubbabc <lukas@wirsindwir.de>
This commit is contained in:
Bukkit/Spigot
2022-02-03 09:25:35 +11:00
parent e6392d1992
commit 7c667b37d9
7 changed files with 362 additions and 0 deletions

View File

@@ -0,0 +1,100 @@
package org.bukkit.profile;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import org.bukkit.Server;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* A player profile.
* <p>
* A player profile always provides a unique id, a non-empty name, or both. Its
* unique id and name are immutable, but other properties (such as its textures)
* can be altered.
* <p>
* New profiles can be created via
* {@link Server#createPlayerProfile(UUID, String)}.
*/
public interface PlayerProfile extends Cloneable, ConfigurationSerializable {
/**
* Gets the player's unique id.
*
* @return the player's unique id, or <code>null</code> if not available
*/
@Nullable
UUID getUniqueId();
/**
* Gets the player name.
*
* @return the player name, or <code>null</code> if not available
*/
@Nullable
String getName();
/**
* Gets the {@link PlayerTextures} of this profile.
*
* @return the textures, not <code>null</code>
*/
@NotNull
PlayerTextures getTextures();
/**
* Copies the given textures.
*
* @param textures the textures to copy, or <code>null</code> to clear the
* textures
*/
void setTextures(@Nullable PlayerTextures textures);
/**
* Checks whether this profile is complete.
* <p>
* A profile is currently considered complete if it has a name, a unique id,
* and textures.
*
* @return <code>true</code> if this profile is complete
*/
boolean isComplete();
/**
* Produces an updated player profile based on this profile.
* <p>
* This tries to produce a completed profile by filling in missing
* properties (name, unique id, textures, etc.), and updates existing
* properties (e.g. name, textures, etc.) to their official and up-to-date
* values. This operation does not alter the current profile, but produces a
* new updated {@link PlayerProfile}.
* <p>
* If no player exists for the unique id or name of this profile, this
* operation yields a profile that is equal to the current profile, which
* might not be complete.
* <p>
* This is an asynchronous operation: Updating the profile can result in an
* outgoing connection in another thread in order to fetch the latest
* profile properties. The returned {@link CompletableFuture} will be
* completed once the updated profile is available. In order to not block
* the server's main thread, you should not wait for the result of the
* returned CompletableFuture on the server's main thread. Instead, if you
* want to do something with the updated player profile on the server's main
* thread once it is available, you could do something like this:
* <pre>
* profile.update().thenAcceptAsync(updatedProfile -> {
* // Do something with the updated profile:
* // ...
* }, runnable -> Bukkit.getScheduler().runTask(plugin, runnable));
* </pre>
*
* @return a completable future that gets completed with the updated
* PlayerProfile once it is available
*/
@NotNull
CompletableFuture<PlayerProfile> update();
@NotNull
PlayerProfile clone();
}

View File

@@ -0,0 +1,127 @@
package org.bukkit.profile;
import java.net.URL;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Provides access to the textures stored inside a {@link PlayerProfile}.
* <p>
* Modifying the textures immediately invalidates and clears any previously
* present attributes that are specific to official player profiles, such as the
* {@link #getTimestamp() timestamp} and {@link #isSigned() signature}.
*/
public interface PlayerTextures {
/**
* The different Minecraft skin models.
*/
enum SkinModel {
/**
* The classic Minecraft skin model.
*/
CLASSIC,
/**
* The slim model has slimmer arms than the classic model.
*/
SLIM;
}
/**
* Checks if the profile stores no textures.
*
* @return <code>true</code> if the profile stores no textures
*/
boolean isEmpty();
/**
* Clears the textures.
*/
void clear();
/**
* Gets the URL that points to the player's skin.
*
* @return the URL of the player's skin, or <code>null</code> if not set
*/
@Nullable
URL getSkin();
/**
* Sets the player's skin to the specified URL, and the skin model to
* {@link SkinModel#CLASSIC}.
* <p>
* The URL <b>must</b> point to the Minecraft texture server. Example URL:
* <pre>
* http://textures.minecraft.net/texture/b3fbd454b599df593f57101bfca34e67d292a8861213d2202bb575da7fd091ac
* </pre>
*
* @param skinUrl the URL of the player's skin, or <code>null</code> to
* unset it
*/
void setSkin(@Nullable URL skinUrl);
/**
* Sets the player's skin and {@link SkinModel}.
* <p>
* The URL <b>must</b> point to the Minecraft texture server. Example URL:
* <pre>
* http://textures.minecraft.net/texture/b3fbd454b599df593f57101bfca34e67d292a8861213d2202bb575da7fd091ac
* </pre>
* <p>
* A skin model of <code>null</code> results in {@link SkinModel#CLASSIC} to
* be used.
*
* @param skinUrl the URL of the player's skin, or <code>null</code> to
* unset it
* @param skinModel the skin model, ignored if the skin URL is
* <code>null</code>
*/
void setSkin(@Nullable URL skinUrl, @Nullable SkinModel skinModel);
/**
* Gets the model of the player's skin.
* <p>
* This returns {@link SkinModel#CLASSIC} if no skin is set.
*
* @return the model of the player's skin
*/
@NotNull
SkinModel getSkinModel();
/**
* Gets the URL that points to the player's cape.
*
* @return the URL of the player's cape, or <code>null</code> if not set
*/
@Nullable
URL getCape();
/**
* Sets the URL that points to the player's cape.
* <p>
* The URL <b>must</b> point to the Minecraft texture server. Example URL:
* <pre>
* http://textures.minecraft.net/texture/2340c0e03dd24a11b15a8b33c2a7e9e32abb2051b2481d0ba7defd635ca7a933
* </pre>
*
* @param capeUrl the URL of the player's cape, or <code>null</code> to
* unset it
*/
void setCape(@Nullable URL capeUrl);
/**
* Gets the timestamp at which the profile was last updated.
*
* @return the timestamp, or <code>0</code> if unknown
*/
long getTimestamp();
/**
* Checks if the textures are signed and the signature is valid.
*
* @return <code>true</code> if the textures are signed and the signature is
* valid
*/
boolean isSigned();
}