Mirror von
https://github.com/PaperMC/Paper.git
synchronisiert 2024-11-15 04:20:04 +01:00
6483ecb8a2
Upstream has released updates that appear to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: a6aba46f PR-1078: Improve Javadocs of Player#loadData() and Player#saveData() 1e2e6a18 SPIGOT-7946: API for server pause when empty seconds 54a36938 SPIGOT-7944, PR-1077: Allow nullable fields in DamageTypeTags CraftBukkit Changes: 2702c5c8e SPIGOT-7946: API for server pause when empty seconds 485f910fc SPIGOT-7947: addPassenger doesn't work if the vehicle is a player ecf3dff0e SPIGOT-7949: Registering a new scoreboard objective with an empty display name throws a NPE 9b048cc84 SPIGOT-7948: `Bukkit#dispatchCommand` uses the wrong `CommandListenerWrapper` for Players 7b44d4640 SPIGOT-7931: Fix sync in Anvil View when result item is taken
531 Zeilen
21 KiB
Diff
531 Zeilen
21 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Aikar <aikar@aikar.co>
|
|
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..324c1cba46c9eef95cc22ffa231b04f9298a5e00
|
|
--- /dev/null
|
|
+++ b/src/main/java/com/destroystokyo/paper/profile/PlayerProfile.java
|
|
@@ -0,0 +1,246 @@
|
|
+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.jspecify.annotations.NullMarked;
|
|
+import org.jspecify.annotations.Nullable;
|
|
+
|
|
+/**
|
|
+ * Represents a players profile for the game, such as UUID, Name, and textures.
|
|
+ */
|
|
+@NullMarked
|
|
+public interface PlayerProfile extends org.bukkit.profile.PlayerProfile {
|
|
+
|
|
+ /**
|
|
+ * @return The players name, if set
|
|
+ */
|
|
+ @Override
|
|
+ @Nullable
|
|
+ String getName();
|
|
+
|
|
+ /**
|
|
+ * Sets this profiles Name
|
|
+ *
|
|
+ * @param name The new Name
|
|
+ * @return The previous Name
|
|
+ */
|
|
+ @Deprecated(forRemoval = true, since = "1.18.1")
|
|
+ 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
|
|
+ */
|
|
+ @Deprecated(forRemoval = true, since = "1.18.1")
|
|
+ @Nullable
|
|
+ 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>
|
|
+ */
|
|
+ @Override
|
|
+ PlayerTextures getTextures();
|
|
+
|
|
+ /**
|
|
+ * Copies the given textures.
|
|
+ *
|
|
+ * @param textures the textures to copy, or <code>null</code> to clear the
|
|
+ * textures
|
|
+ */
|
|
+ @Override
|
|
+ void setTextures(@Nullable PlayerTextures textures);
|
|
+
|
|
+ /**
|
|
+ * @return A Mutable set of this players properties, such as textures.
|
|
+ * Values specified here are subject to implementation details.
|
|
+ */
|
|
+ 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.
|
|
+ * @throws IllegalArgumentException if setting the property results in more than 16 properties
|
|
+ */
|
|
+ void setProperty(ProfileProperty property);
|
|
+
|
|
+ /**
|
|
+ * Sets multiple properties. If any of the set properties already exist, it will be replaced
|
|
+ *
|
|
+ * @param properties The properties to set
|
|
+ * @throws IllegalArgumentException if the number of properties exceeds 16
|
|
+ */
|
|
+ void setProperties(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(final ProfileProperty property) {
|
|
+ return this.removeProperty(property.getName());
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Removes all properties in the collection
|
|
+ *
|
|
+ * @param properties The properties to remove
|
|
+ * @return If any property was removed
|
|
+ */
|
|
+ default boolean removeProperties(final Collection<ProfileProperty> properties) {
|
|
+ boolean removed = false;
|
|
+ for (final ProfileProperty property : properties) {
|
|
+ if (this.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)
|
|
+ */
|
|
+ @Override
|
|
+ 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.
|
|
+ * <p>
|
|
+ * 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 this.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.
|
|
+ * <p>
|
|
+ * Optionally will also fill textures.
|
|
+ * <p>
|
|
+ * 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.
|
|
+ * <p>
|
|
+ * 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
|
|
+ CompletableFuture<PlayerProfile> update();
|
|
+
|
|
+ /**
|
|
+ * Whether this Profile has textures associated to it
|
|
+ *
|
|
+ * @return If it has a textures property
|
|
+ */
|
|
+ default boolean hasTextures() {
|
|
+ return this.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..35341d8f1ac2d80f339084ef80d099a545027554
|
|
--- /dev/null
|
|
+++ b/src/main/java/com/destroystokyo/paper/profile/ProfileProperty.java
|
|
@@ -0,0 +1,73 @@
|
|
+package com.destroystokyo.paper.profile;
|
|
+
|
|
+import com.google.common.base.Preconditions;
|
|
+import java.util.Objects;
|
|
+import org.jspecify.annotations.NullMarked;
|
|
+import org.jspecify.annotations.Nullable;
|
|
+
|
|
+/**
|
|
+ * Represents a property on a {@link PlayerProfile}
|
|
+ */
|
|
+@NullMarked
|
|
+public final class ProfileProperty {
|
|
+
|
|
+ private final String name;
|
|
+ private final String value;
|
|
+ private final @Nullable String signature;
|
|
+
|
|
+ public ProfileProperty(final String name, final String value) {
|
|
+ this(name, value, null);
|
|
+ }
|
|
+
|
|
+ public ProfileProperty(final String name, final String value, final @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;
|
|
+ Preconditions.checkArgument(name.length() <= 64, "ProfileProperty name can not be longer than 64 characters");
|
|
+ Preconditions.checkArgument(value.length() <= Short.MAX_VALUE, "ProfileProperty value can not be longer than 32767 characters");
|
|
+ Preconditions.checkArgument(signature == null || signature.length() <= 1024, "ProfileProperty signature can not be longer than 1024 characters");
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * @return The property name, ie "textures"
|
|
+ */
|
|
+ public String getName() {
|
|
+ return this.name;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * @return The property value, likely to be base64 encoded
|
|
+ */
|
|
+ public String getValue() {
|
|
+ return this.value;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * @return A signature from Mojang for signed properties
|
|
+ */
|
|
+ public @Nullable String getSignature() {
|
|
+ return this.signature;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * @return If this property has a signature or not
|
|
+ */
|
|
+ public boolean isSigned() {
|
|
+ return this.signature != null;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean equals(final @Nullable Object o) {
|
|
+ if (this == o) return true;
|
|
+ if (o == null || this.getClass() != o.getClass()) return false;
|
|
+ final ProfileProperty that = (ProfileProperty) o;
|
|
+ return Objects.equals(this.name, that.name) &&
|
|
+ Objects.equals(this.value, that.value) &&
|
|
+ Objects.equals(this.signature, that.signature);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int hashCode() {
|
|
+ return Objects.hash(this.name);
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
|
|
index c900bde81d8f20ed4775228fbe767d7db62508fa..6c44f58551dda4129d37cce100a9c5b9c9810cca 100644
|
|
--- a/src/main/java/org/bukkit/Bukkit.java
|
|
+++ b/src/main/java/org/bukkit/Bukkit.java
|
|
@@ -2424,6 +2424,89 @@ 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
|
|
+ * @throws IllegalArgumentException if the name is longer than 16 characters
|
|
+ * @throws IllegalArgumentException if the name contains invalid characters
|
|
+ */
|
|
+ @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
|
|
+ * @throws IllegalArgumentException if the name is longer than 16 characters
|
|
+ * @throws IllegalArgumentException if the name contains invalid characters
|
|
+ */
|
|
+ @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
|
|
+ * @throws IllegalArgumentException if the name is longer than 16 characters
|
|
+ * @throws IllegalArgumentException if the name contains invalid characters
|
|
+ */
|
|
+ @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 0588c6c8b30bfe6e1e8ab7e1523a8a9be6b11b6f..55d8602bb651f85b9d0a80ec015cec5e48948d44 100644
|
|
--- a/src/main/java/org/bukkit/Server.java
|
|
+++ b/src/main/java/org/bukkit/Server.java
|
|
@@ -2108,5 +2108,80 @@ 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
|
|
+ * @throws IllegalArgumentException if the name is longer than 16 characters
|
|
+ * @throws IllegalArgumentException if the name contains invalid characters
|
|
+ */
|
|
+ @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
|
|
+ * @throws IllegalArgumentException if the name is longer than 16 characters
|
|
+ * @throws IllegalArgumentException if the name contains invalid characters
|
|
+ */
|
|
+ @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
|
|
+ * @throws IllegalArgumentException if the name is longer than 16 characters
|
|
+ * @throws IllegalArgumentException if the name contains invalid characters
|
|
+ */
|
|
+ @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();
|