Fix PlayerProfile BukkitObject serialization, deprecate setName and setId for removal (#7471)
Having a modifiable hash here is a bit flawed and most developers should never need these methods
This commit is contained in:
parent
61ecf80013
commit
aa0e21a2dc
2 changed files with 112 additions and 18 deletions
|
@ -39,6 +39,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||||
+ * @return The previous Name
|
+ * @return The previous Name
|
||||||
+ */
|
+ */
|
||||||
+ @NotNull
|
+ @NotNull
|
||||||
|
+ @Deprecated(forRemoval = true)
|
||||||
+ String setName(@Nullable String name);
|
+ String setName(@Nullable String name);
|
||||||
+
|
+
|
||||||
+ /**
|
+ /**
|
||||||
|
@ -53,6 +54,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||||
+ * @return The previous UUID
|
+ * @return The previous UUID
|
||||||
+ */
|
+ */
|
||||||
+ @Nullable
|
+ @Nullable
|
||||||
|
+ @Deprecated(forRemoval = true)
|
||||||
+ UUID setId(@Nullable UUID uuid);
|
+ UUID setId(@Nullable UUID uuid);
|
||||||
+
|
+
|
||||||
+ /**
|
+ /**
|
||||||
|
|
|
@ -23,6 +23,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||||
+import net.minecraft.server.MinecraftServer;
|
+import net.minecraft.server.MinecraftServer;
|
||||||
+import net.minecraft.server.players.GameProfileCache;
|
+import net.minecraft.server.players.GameProfileCache;
|
||||||
+import org.apache.commons.lang3.Validate;
|
+import org.apache.commons.lang3.Validate;
|
||||||
|
+import org.bukkit.configuration.serialization.SerializableAs;
|
||||||
|
+import org.bukkit.craftbukkit.configuration.ConfigSerializationUtil;
|
||||||
+import org.bukkit.craftbukkit.entity.CraftPlayer;
|
+import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||||
+import org.bukkit.craftbukkit.profile.CraftPlayerTextures;
|
+import org.bukkit.craftbukkit.profile.CraftPlayerTextures;
|
||||||
+import org.bukkit.craftbukkit.profile.CraftProfileProperty;
|
+import org.bukkit.craftbukkit.profile.CraftProfileProperty;
|
||||||
|
@ -34,6 +36,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||||
+import java.util.*;
|
+import java.util.*;
|
||||||
+import java.util.concurrent.CompletableFuture;
|
+import java.util.concurrent.CompletableFuture;
|
||||||
+
|
+
|
||||||
|
+@SerializableAs("PlayerProfile")
|
||||||
+public class CraftPlayerProfile implements PlayerProfile, SharedPlayerProfile {
|
+public class CraftPlayerProfile implements PlayerProfile, SharedPlayerProfile {
|
||||||
+
|
+
|
||||||
+ private GameProfile profile;
|
+ private GameProfile profile;
|
||||||
|
@ -92,6 +95,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ @Override
|
+ @Override
|
||||||
|
+ @Deprecated(forRemoval = true)
|
||||||
+ public UUID setId(@Nullable UUID uuid) {
|
+ public UUID setId(@Nullable UUID uuid) {
|
||||||
+ GameProfile prev = this.profile;
|
+ GameProfile prev = this.profile;
|
||||||
+ this.profile = new GameProfile(uuid, prev.getName());
|
+ this.profile = new GameProfile(uuid, prev.getName());
|
||||||
|
@ -111,6 +115,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ @Override
|
+ @Override
|
||||||
|
+ @Deprecated(forRemoval = true)
|
||||||
+ public String setName(@Nullable String name) {
|
+ public String setName(@Nullable String name) {
|
||||||
+ GameProfile prev = this.profile;
|
+ GameProfile prev = this.profile;
|
||||||
+ this.profile = new GameProfile(prev.getId(), name);
|
+ this.profile = new GameProfile(prev.getId(), name);
|
||||||
|
@ -163,24 +168,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ @Override
|
+ @Override
|
||||||
+ public boolean equals(Object o) {
|
|
||||||
+ if (this == o) return true;
|
|
||||||
+ if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
+ CraftPlayerProfile that = (CraftPlayerProfile) o;
|
|
||||||
+ return Objects.equals(profile, that.profile);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ @Override
|
|
||||||
+ public int hashCode() {
|
|
||||||
+ return profile.hashCode();
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ @Override
|
|
||||||
+ public String toString() {
|
|
||||||
+ return profile.toString();
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ @Override
|
|
||||||
+ public CraftPlayerProfile clone() {
|
+ public CraftPlayerProfile clone() {
|
||||||
+ CraftPlayerProfile clone = new CraftPlayerProfile(this.getId(), this.getName());
|
+ CraftPlayerProfile clone = new CraftPlayerProfile(this.getId(), this.getName());
|
||||||
+ clone.setProperties(getProperties());
|
+ clone.setProperties(getProperties());
|
||||||
|
@ -328,6 +315,46 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||||
+ return map;
|
+ return map;
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
|
+ public static CraftPlayerProfile deserialize(Map<String, Object> map) {
|
||||||
|
+ UUID uniqueId = ConfigSerializationUtil.getUuid(map, "uniqueId", true);
|
||||||
|
+ String name = ConfigSerializationUtil.getString(map, "name", true);
|
||||||
|
+
|
||||||
|
+ // This also validates the deserialized unique id and name (ensures that not both are null):
|
||||||
|
+ CraftPlayerProfile profile = new CraftPlayerProfile(uniqueId, name);
|
||||||
|
+
|
||||||
|
+ if (map.containsKey("properties")) {
|
||||||
|
+ for (Object propertyData : (List<?>) map.get("properties")) {
|
||||||
|
+ if (!(propertyData instanceof Map)) {
|
||||||
|
+ throw new IllegalArgumentException("Property data (" + propertyData + ") is not a valid Map");
|
||||||
|
+ }
|
||||||
|
+ Property property = CraftProfileProperty.deserialize((Map<?, ?>) propertyData);
|
||||||
|
+ profile.profile.getProperties().put(property.getName(), property);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return profile;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public boolean equals(Object obj) {
|
||||||
|
+ if (this == obj) return true;
|
||||||
|
+ if (!(obj instanceof CraftPlayerProfile otherProfile)) return false;
|
||||||
|
+ return Objects.equals(this.profile, otherProfile.profile);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public String toString() {
|
||||||
|
+ return "CraftPlayerProfile [uniqueId=" + getId() +
|
||||||
|
+ ", name=" + getName() +
|
||||||
|
+ ", properties=" + org.bukkit.craftbukkit.profile.CraftPlayerProfile.toString(this.profile.getProperties()) +
|
||||||
|
+ "]";
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public int hashCode() {
|
||||||
|
+ return this.profile.hashCode();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
+ private class PropertySet extends AbstractSet<ProfileProperty> {
|
+ private class PropertySet extends AbstractSet<ProfileProperty> {
|
||||||
+
|
+
|
||||||
+ @Override
|
+ @Override
|
||||||
|
@ -603,6 +630,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||||
public final class CraftServer implements Server {
|
public final class CraftServer implements Server {
|
||||||
private final String serverName = "Paper"; // Paper
|
private final String serverName = "Paper"; // Paper
|
||||||
private final String serverVersion;
|
private final String serverVersion;
|
||||||
|
@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
|
||||||
|
static {
|
||||||
|
ConfigurationSerialization.registerClass(CraftOfflinePlayer.class);
|
||||||
|
ConfigurationSerialization.registerClass(CraftPlayerProfile.class);
|
||||||
|
+ ConfigurationSerialization.registerClass(com.destroystokyo.paper.profile.CraftPlayerProfile.class); // Paper
|
||||||
|
CraftItemFactory.instance();
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
|
@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
|
||||||
public boolean suggestPlayerNamesWhenNullTabCompletions() {
|
public boolean suggestPlayerNamesWhenNullTabCompletions() {
|
||||||
return com.destroystokyo.paper.PaperConfig.suggestPlayersWhenNullTabCompletions;
|
return com.destroystokyo.paper.PaperConfig.suggestPlayersWhenNullTabCompletions;
|
||||||
|
@ -668,6 +703,63 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
||||||
}
|
}
|
||||||
|
|
||||||
void rebuildDirtyProperties() {
|
void rebuildDirtyProperties() {
|
||||||
|
@@ -0,0 +0,0 @@ public final class CraftPlayerProfile implements PlayerProfile {
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
- private static String toString(@Nonnull PropertyMap propertyMap) {
|
||||||
|
+ public static String toString(@Nonnull PropertyMap propertyMap) { // Paper - public
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append("{");
|
||||||
|
propertyMap.asMap().forEach((propertyName, properties) -> {
|
||||||
|
@@ -0,0 +0,0 @@ public final class CraftPlayerProfile implements PlayerProfile {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
- private static boolean equals(@Nonnull PropertyMap propertyMap, @Nonnull PropertyMap other) {
|
||||||
|
+ public static boolean equals(@Nonnull PropertyMap propertyMap, @Nonnull PropertyMap other) { // Paper - public
|
||||||
|
if (propertyMap.size() != other.size()) return false;
|
||||||
|
// We take the order of properties into account here, because it is
|
||||||
|
// also relevant in the serialized and NBT forms of GameProfiles.
|
||||||
|
@@ -0,0 +0,0 @@ public final class CraftPlayerProfile implements PlayerProfile {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
- private static int hashCode(PropertyMap propertyMap) {
|
||||||
|
+ public static int hashCode(PropertyMap propertyMap) { // Paper - public
|
||||||
|
int result = 1;
|
||||||
|
for (Property property : propertyMap.values()) {
|
||||||
|
result = 31 * result + CraftProfileProperty.hashCode(property);
|
||||||
|
@@ -0,0 +0,0 @@ public final class CraftPlayerProfile implements PlayerProfile {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> serialize() {
|
||||||
|
+ // Paper - diff on change
|
||||||
|
Map<String, Object> map = new LinkedHashMap<>();
|
||||||
|
if (this.uniqueId != null) {
|
||||||
|
map.put("uniqueId", this.uniqueId.toString());
|
||||||
|
@@ -0,0 +0,0 @@ public final class CraftPlayerProfile implements PlayerProfile {
|
||||||
|
});
|
||||||
|
map.put("properties", propertiesData);
|
||||||
|
}
|
||||||
|
+ // Paper - diff on change
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CraftPlayerProfile deserialize(Map<String, Object> map) {
|
||||||
|
+ // Paper - diff on change
|
||||||
|
UUID uniqueId = ConfigSerializationUtil.getUuid(map, "uniqueId", true);
|
||||||
|
String name = ConfigSerializationUtil.getString(map, "name", true);
|
||||||
|
|
||||||
|
@@ -0,0 +0,0 @@ public final class CraftPlayerProfile implements PlayerProfile {
|
||||||
|
profile.properties.put(property.getName(), property);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
-
|
||||||
|
+ // Paper - diff on change
|
||||||
|
return profile;
|
||||||
|
}
|
||||||
|
}
|
||||||
diff --git a/src/main/java/org/bukkit/craftbukkit/profile/CraftPlayerTextures.java b/src/main/java/org/bukkit/craftbukkit/profile/CraftPlayerTextures.java
|
diff --git a/src/main/java/org/bukkit/craftbukkit/profile/CraftPlayerTextures.java b/src/main/java/org/bukkit/craftbukkit/profile/CraftPlayerTextures.java
|
||||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||||
--- a/src/main/java/org/bukkit/craftbukkit/profile/CraftPlayerTextures.java
|
--- a/src/main/java/org/bukkit/craftbukkit/profile/CraftPlayerTextures.java
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue