diff options
Diffstat (limited to 'patches/api/0060-Basic-PlayerProfile-API.patch')
-rw-r--r-- | patches/api/0060-Basic-PlayerProfile-API.patch | 502 |
1 files changed, 502 insertions, 0 deletions
diff --git a/patches/api/0060-Basic-PlayerProfile-API.patch b/patches/api/0060-Basic-PlayerProfile-API.patch new file mode 100644 index 0000000000..ab35d1c971 --- /dev/null +++ b/patches/api/0060-Basic-PlayerProfile-API.patch @@ -0,0 +1,502 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aikar <[email protected]> +Date: Mon, 15 Jan 2018 21:46:46 -0500 +Subject: [PATCH] Basic PlayerProfile API + +Provides basic elements of a PlayerProfile to be used by future API/events + +diff --git a/src/main/java/com/destroystokyo/paper/profile/PlayerProfile.java b/src/main/java/com/destroystokyo/paper/profile/PlayerProfile.java +new file mode 100644 +index 0000000000000000000000000000000000000000..b76f13a0266806544bde13952476d4867caaf25b +--- /dev/null ++++ b/src/main/java/com/destroystokyo/paper/profile/PlayerProfile.java +@@ -0,0 +1,231 @@ ++package com.destroystokyo.paper.profile; ++ ++import java.util.Collection; ++import java.util.Set; ++import java.util.UUID; ++ ++import java.util.concurrent.CompletableFuture; ++import org.bukkit.profile.PlayerTextures; ++import org.jetbrains.annotations.NotNull; ++import org.jetbrains.annotations.Nullable; ++ ++/** ++ * Represents a players profile for the game, such as UUID, Name, and textures. ++ */ ++public interface PlayerProfile extends org.bukkit.profile.PlayerProfile { ++ ++ /** ++ * @return The players name, if set ++ */ ++ @Nullable ++ String getName(); ++ ++ /** ++ * Sets this profiles Name ++ * ++ * @param name The new Name ++ * @return The previous Name ++ */ ++ @NotNull ++ @Deprecated(forRemoval = true) ++ String setName(@Nullable String name); ++ ++ /** ++ * @return The players unique identifier, if set ++ */ ++ @Nullable UUID getId(); ++ ++ /** ++ * Sets this profiles UUID ++ * ++ * @param uuid The new UUID ++ * @return The previous UUID ++ */ ++ @Nullable ++ @Deprecated(forRemoval = true) ++ UUID setId(@Nullable UUID uuid); ++ ++ /** ++ * Gets the {@link PlayerTextures} of this profile. ++ * This will build a snapshot of the current texture data once ++ * requested inside PlayerTextures. ++ * ++ * @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); ++ ++ /** ++ * @return A Mutable set of this players properties, such as textures. ++ * Values specified here are subject to implementation details. ++ */ ++ @NotNull Set<ProfileProperty> getProperties(); ++ ++ /** ++ * Check if the Profile has the specified property ++ * @param property Property name to check ++ * @return If the property is set ++ */ ++ boolean hasProperty(@Nullable String property); ++ ++ /** ++ * Sets a property. If the property already exists, the previous one will be replaced ++ * @param property Property to set. ++ */ ++ void setProperty(@NotNull ProfileProperty property); ++ ++ /** ++ * Sets multiple properties. If any of the set properties already exist, it will be replaced ++ * @param properties The properties to set ++ */ ++ void setProperties(@NotNull Collection<ProfileProperty> properties); ++ ++ /** ++ * Removes a specific property from this profile ++ * @param property The property to remove ++ * @return If a property was removed ++ */ ++ boolean removeProperty(@Nullable String property); ++ ++ /** ++ * Removes a specific property from this profile ++ * @param property The property to remove ++ * @return If a property was removed ++ */ ++ default boolean removeProperty(@NotNull ProfileProperty property) { ++ return removeProperty(property.getName()); ++ } ++ ++ /** ++ * Removes all properties in the collection ++ * @param properties The properties to remove ++ * @return If any property was removed ++ */ ++ default boolean removeProperties(@NotNull Collection<ProfileProperty> properties) { ++ boolean removed = false; ++ for (ProfileProperty property : properties) { ++ if (removeProperty(property)) { ++ removed = true; ++ } ++ } ++ return removed; ++ } ++ ++ /** ++ * Clears all properties on this profile ++ */ ++ void clearProperties(); ++ ++ /** ++ * @return If the profile is now complete (has UUID and Name) ++ */ ++ boolean isComplete(); ++ ++ /** ++ * Like {@link #complete(boolean)} but will try only from cache, and not make network calls ++ * Does not account for textures. ++ * ++ * @return If the profile is now complete (has UUID and Name) ++ */ ++ boolean completeFromCache(); ++ ++ /** ++ * Like {@link #complete(boolean)} but will try only from cache, and not make network calls ++ * Does not account for textures. ++ * ++ * @param onlineMode Treat this as online mode or not ++ * @return If the profile is now complete (has UUID and Name) ++ */ ++ boolean completeFromCache(boolean onlineMode); ++ ++ /** ++ * Like {@link #complete(boolean)} but will try only from cache, and not make network calls ++ * Does not account for textures. ++ * ++ * @param lookupUUID If only name is supplied, should we do a UUID lookup ++ * @param onlineMode Treat this as online mode or not ++ * @return If the profile is now complete (has UUID and Name) ++ */ ++ boolean completeFromCache(boolean lookupUUID, boolean onlineMode); ++ ++ /** ++ * If this profile is not complete, then make the API call to complete it. ++ * This is a blocking operation and should be done asynchronously. ++ * ++ * This will also complete textures. If you do not want to load textures, use {{@link #complete(boolean)}} ++ * @return If the profile is now complete (has UUID and Name) (if you get rate limited, this operation may fail) ++ */ ++ default boolean complete() { ++ return complete(true); ++ } ++ ++ /** ++ * If this profile is not complete, then make the API call to complete it. ++ * This is a blocking operation and should be done asynchronously. ++ * ++ * Optionally will also fill textures. ++ * ++ * Online mode will be automatically determined ++ * @param textures controls if we should fill the profile with texture properties ++ * @return If the profile is now complete (has UUID and Name) (if you get rate limited, this operation may fail) ++ */ ++ boolean complete(boolean textures); ++ ++ /** ++ * If this profile is not complete, then make the API call to complete it. ++ * This is a blocking operation and should be done asynchronously. ++ * ++ * Optionally will also fill textures. ++ * @param textures controls if we should fill the profile with texture properties ++ * @param onlineMode Treat this server as online mode or not ++ * @return If the profile is now complete (has UUID and Name) (if you get rate limited, this operation may fail) ++ */ ++ boolean complete(boolean textures, boolean onlineMode); ++ ++ /** ++ * 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> ++ */ ++ @Override ++ @NotNull CompletableFuture<PlayerProfile> update(); ++ ++ /** ++ * Whether this Profile has textures associated to it ++ * @return If it has a textures property ++ */ ++ default boolean hasTextures() { ++ return hasProperty("textures"); ++ } ++} +diff --git a/src/main/java/com/destroystokyo/paper/profile/ProfileProperty.java b/src/main/java/com/destroystokyo/paper/profile/ProfileProperty.java +new file mode 100644 +index 0000000000000000000000000000000000000000..7b3b6ef533d32169fbeca389bd61cfc6b0e0faee +--- /dev/null ++++ b/src/main/java/com/destroystokyo/paper/profile/ProfileProperty.java +@@ -0,0 +1,72 @@ ++package com.destroystokyo.paper.profile; ++ ++import com.google.common.base.Preconditions; ++ ++import java.util.Objects; ++import org.jetbrains.annotations.NotNull; ++import org.jetbrains.annotations.Nullable; ++ ++/** ++ * Represents a property on a {@link PlayerProfile} ++ */ ++public class ProfileProperty { ++ private final String name; ++ private final String value; ++ private final String signature; ++ ++ public ProfileProperty(@NotNull String name, @NotNull String value) { ++ this(name, value, null); ++ } ++ ++ public ProfileProperty(@NotNull String name, @NotNull String value, @Nullable String signature) { ++ this.name = Preconditions.checkNotNull(name, "ProfileProperty name can not be null"); ++ this.value = Preconditions.checkNotNull(value, "ProfileProperty value can not be null"); ++ this.signature = signature; ++ } ++ ++ /** ++ * @return The property name, ie "textures" ++ */ ++ @NotNull ++ public String getName() { ++ return name; ++ } ++ ++ /** ++ * @return The property value, likely to be base64 encoded ++ */ ++ @NotNull ++ public String getValue() { ++ return value; ++ } ++ ++ /** ++ * @return A signature from Mojang for signed properties ++ */ ++ @Nullable ++ public String getSignature() { ++ return signature; ++ } ++ ++ /** ++ * @return If this property has a signature or not ++ */ ++ public boolean isSigned() { ++ return this.signature != null; ++ } ++ ++ @Override ++ public boolean equals(Object o) { ++ if (this == o) return true; ++ if (o == null || getClass() != o.getClass()) return false; ++ ProfileProperty that = (ProfileProperty) o; ++ return Objects.equals(name, that.name) && ++ Objects.equals(value, that.value) && ++ Objects.equals(signature, that.signature); ++ } ++ ++ @Override ++ public int hashCode() { ++ return Objects.hash(name); ++ } ++} +diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java +index 365c2cd4f5a3a382d3b52b50377fbf56731a30ae..87ce6947a1e974c18e84f56ba622bee9fff3570b 100644 +--- a/src/main/java/org/bukkit/Bukkit.java ++++ b/src/main/java/org/bukkit/Bukkit.java +@@ -2304,6 +2304,83 @@ public final class Bukkit { + public static boolean suggestPlayerNamesWhenNullTabCompletions() { + return server.suggestPlayerNamesWhenNullTabCompletions(); + } ++ ++ /** ++ * Creates a PlayerProfile for the specified uuid, with name as null. ++ * ++ * If a player with the passed uuid exists on the server at the time of creation, the returned player profile will ++ * be populated with the properties of said player (including their uuid and name). ++ * ++ * @param uuid UUID to create profile for ++ * @return A PlayerProfile object ++ */ ++ @NotNull ++ public static com.destroystokyo.paper.profile.PlayerProfile createProfile(@NotNull UUID uuid) { ++ return server.createProfile(uuid); ++ } ++ ++ /** ++ * Creates a PlayerProfile for the specified name, with UUID as null. ++ * ++ * If a player with the passed name exists on the server at the time of creation, the returned player profile will ++ * be populated with the properties of said player (including their uuid and name). ++ * <p> ++ * E.g. if the player 'jeb_' is currently playing on the server, calling {@code createProfile("JEB_")} will ++ * yield a profile with the name 'jeb_', their uuid and their textures. ++ * To bypass this pre-population on a case-insensitive name match, see {@link #createProfileExact(UUID, String)}. ++ * <p> ++ * ++ * @param name Name to create profile for ++ * @return A PlayerProfile object ++ */ ++ @NotNull ++ public static com.destroystokyo.paper.profile.PlayerProfile createProfile(@NotNull String name) { ++ return server.createProfile(name); ++ } ++ ++ /** ++ * Creates a PlayerProfile for the specified name/uuid ++ * ++ * Both UUID and Name can not be null at same time. One must be supplied. ++ * If a player with the passed uuid or name exists on the server at the time of creation, the returned player ++ * profile will be populated with the properties of said player (including their uuid and name). ++ * <p> ++ * E.g. if the player 'jeb_' is currently playing on the server, calling {@code createProfile(null, "JEB_")} will ++ * yield a profile with the name 'jeb_', their uuid and their textures. ++ * To bypass this pre-population on an case-insensitive name match, see {@link #createProfileExact(UUID, String)}. ++ * <p> ++ * ++ * The name comparison will compare the {@link String#toLowerCase()} version of both the passed name parameter and ++ * a players name to honour the case-insensitive nature of a mojang profile lookup. ++ * ++ * @param uuid UUID to create profile for ++ * @param name Name to create profile for ++ * @return A PlayerProfile object ++ */ ++ @NotNull ++ public static com.destroystokyo.paper.profile.PlayerProfile createProfile(@Nullable UUID uuid, @Nullable String name) { ++ return server.createProfile(uuid, name); ++ } ++ ++ /** ++ * Creates an exact PlayerProfile for the specified name/uuid ++ * ++ * Both UUID and Name can not be null at same time. One must be supplied. ++ * If a player with the passed uuid or name exists on the server at the time of creation, the returned player ++ * profile will be populated with the properties of said player. ++ * <p> ++ * Compared to {@link #createProfile(UUID, String)}, this method will never mutate the passed uuid or name. ++ * If a player with either the same uuid or a matching name (case-insensitive) is found on the server, their ++ * properties, such as textures, will be pre-populated in the profile, however the passed uuid and name stay intact. ++ * ++ * @param uuid UUID to create profile for ++ * @param name Name to create profile for ++ * @return A PlayerProfile object ++ */ ++ @NotNull ++ public static com.destroystokyo.paper.profile.PlayerProfile createProfileExact(@Nullable UUID uuid, @Nullable String name) { ++ return server.createProfileExact(uuid, name); ++ } + // Paper end + + @NotNull +diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java +index 36d07fda939a5e1b4acf77d9092bfc42bbd27d78..bc68d8af8b38232392a12ef5f338e85ca80bccd0 100644 +--- a/src/main/java/org/bukkit/Server.java ++++ b/src/main/java/org/bukkit/Server.java +@@ -2024,5 +2024,74 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi + * @return true if player names should be suggested + */ + boolean suggestPlayerNamesWhenNullTabCompletions(); ++ ++ /** ++ * Creates a PlayerProfile for the specified uuid, with name as null. ++ * ++ * If a player with the passed uuid exists on the server at the time of creation, the returned player profile will ++ * be populated with the properties of said player (including their uuid and name). ++ * ++ * @param uuid UUID to create profile for ++ * @return A PlayerProfile object ++ */ ++ @NotNull ++ com.destroystokyo.paper.profile.PlayerProfile createProfile(@NotNull UUID uuid); ++ ++ /** ++ * Creates a PlayerProfile for the specified name, with UUID as null. ++ * ++ * If a player with the passed name exists on the server at the time of creation, the returned player profile will ++ * be populated with the properties of said player (including their uuid and name). ++ * <p> ++ * E.g. if the player 'jeb_' is currently playing on the server, calling {@code createProfile("JEB_")} will ++ * yield a profile with the name 'jeb_', their uuid and their textures. ++ * To bypass this pre-population on a case-insensitive name match, see {@link #createProfileExact(UUID, String)}. ++ * <p> ++ * ++ * @param name Name to create profile for ++ * @return A PlayerProfile object ++ */ ++ @NotNull ++ com.destroystokyo.paper.profile.PlayerProfile createProfile(@NotNull String name); ++ ++ /** ++ * Creates a PlayerProfile for the specified name/uuid ++ * ++ * Both UUID and Name can not be null at same time. One must be supplied. ++ * If a player with the passed uuid or name exists on the server at the time of creation, the returned player ++ * profile will be populated with the properties of said player (including their uuid and name). ++ * <p> ++ * E.g. if the player 'jeb_' is currently playing on the server, calling {@code createProfile(null, "JEB_")} will ++ * yield a profile with the name 'jeb_', their uuid and their textures. ++ * To bypass this pre-population on an case-insensitive name match, see {@link #createProfileExact(UUID, String)}. ++ * <p> ++ * ++ * The name comparison will compare the {@link String#toLowerCase()} version of both the passed name parameter and ++ * a players name to honour the case-insensitive nature of a mojang profile lookup. ++ * ++ * @param uuid UUID to create profile for ++ * @param name Name to create profile for ++ * @return A PlayerProfile object ++ */ ++ @NotNull ++ com.destroystokyo.paper.profile.PlayerProfile createProfile(@Nullable UUID uuid, @Nullable String name); ++ ++ /** ++ * Creates an exact PlayerProfile for the specified name/uuid ++ * ++ * Both UUID and Name can not be null at same time. One must be supplied. ++ * If a player with the passed uuid or name exists on the server at the time of creation, the returned player ++ * profile will be populated with the properties of said player. ++ * <p> ++ * Compared to {@link #createProfile(UUID, String)}, this method will never mutate the passed uuid or name. ++ * If a player with either the same uuid or a matching name (case-insensitive) is found on the server, their ++ * properties, such as textures, will be pre-populated in the profile, however the passed uuid and name stay intact. ++ * ++ * @param uuid UUID to create profile for ++ * @param name Name to create profile for ++ * @return A PlayerProfile object ++ */ ++ @NotNull ++ com.destroystokyo.paper.profile.PlayerProfile createProfileExact(@Nullable UUID uuid, @Nullable String name); + // Paper end + } +diff --git a/src/main/java/org/bukkit/profile/PlayerProfile.java b/src/main/java/org/bukkit/profile/PlayerProfile.java +index 16ae1282f3178e8873483a25a5d5cce16b2c21a9..fc46add38bf59dc1a04ea566fd230dcd8ae2708c 100644 +--- a/src/main/java/org/bukkit/profile/PlayerProfile.java ++++ b/src/main/java/org/bukkit/profile/PlayerProfile.java +@@ -93,7 +93,7 @@ public interface PlayerProfile extends Cloneable, ConfigurationSerializable { + * PlayerProfile once it is available + */ + @NotNull +- CompletableFuture<PlayerProfile> update(); ++ CompletableFuture<? extends PlayerProfile> update(); // Paper + + @NotNull + PlayerProfile clone(); |