From c27298c0ed821b2e7556e75100ed55c5830bcead Mon Sep 17 00:00:00 2001 From: Aikar Date: Mon, 15 Jan 2018 22:11:48 -0500 Subject: [PATCH] Basic PlayerProfile API diff --git a/src/main/java/com/destroystokyo/paper/profile/CraftPlayerProfile.java b/src/main/java/com/destroystokyo/paper/profile/CraftPlayerProfile.java new file mode 100644 index 000000000..1d669e3e2 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/profile/CraftPlayerProfile.java @@ -0,0 +1,199 @@ +package com.destroystokyo.paper.profile; + +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.properties.Property; +import com.mojang.authlib.properties.PropertyMap; +import net.minecraft.server.MinecraftServer; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.AbstractSet; +import java.util.Collection; +import java.util.Iterator; +import java.util.Set; +import java.util.UUID; + +public class CraftPlayerProfile implements PlayerProfile { + + private GameProfile profile; + private final PropertySet properties; + + /** + * Constructs a new Game Profile with the specified ID and name. + *

+ * Either ID or name may be null/empty, but at least one must be filled. + * + * @param id Unique ID of the profile + * @param name Display name of the profile + * @throws IllegalArgumentException Both ID and name are either null or empty + */ + public CraftPlayerProfile(UUID id, String name) { + this(new GameProfile(id, name)); + } + + public CraftPlayerProfile(GameProfile profile) { + this.profile = profile; + this.properties = new PropertySet(); + } + + public GameProfile getGameProfile() { + return profile; + } + + @Nullable + @Override + public UUID getId() { + return profile.getId(); + } + + @Nonnull + @Override + public Set getProperties() { + return properties; + } + + @Nullable + @Override + public String getName() { + return profile.getName(); + } + + @Override + public boolean equals(Object o) { + return profile.equals(o); + } + + @Override + public int hashCode() { + return profile.hashCode(); + } + + @Override + public String toString() { + return profile.toString(); + } + + @Override + public CraftPlayerProfile clone() { + CraftPlayerProfile clone = new CraftPlayerProfile(this.getId(), this.getName()); + clone.setProperties(getProperties()); + return clone; + } + + @Override + public void setProperty(ProfileProperty property) { + String name = property.getName(); + PropertyMap properties = profile.getProperties(); + properties.removeAll(name); + properties.put(name, new Property(name, property.getValue(), property.getSignature())); + } + + @Override + public void setProperties(Collection properties) { + properties.forEach(this::setProperty); + } + + @Override + public boolean removeProperty(String property) { + return !profile.getProperties().removeAll(property).isEmpty(); + } + + @Override + public void clearProperties() { + profile.getProperties().clear(); + } + + @Override + public boolean isComplete() { + return profile.isComplete(); + } + + public boolean complete() { + if (!profile.isComplete()) { + profile = MinecraftServer.getServer().getSessionService().fillProfileProperties(profile, true); + } + return profile.isComplete(); + } + + private static ProfileProperty toBukkit(Property property) { + return new ProfileProperty(property.getName(), property.getValue(), property.getSignature()); + } + + public static PlayerProfile asBukkitCopy(GameProfile gameProfile) { + PlayerProfile profile = new CraftPlayerProfile(gameProfile.getId(), gameProfile.getName()); + gameProfile.getProperties().values().forEach(property -> profile.setProperty(toBukkit(property))); + return profile; + } + + public static PlayerProfile asBukkitMirror(GameProfile profile) { + return new CraftPlayerProfile(profile); + } + + public static Property asAuthlib(ProfileProperty property) { + return new Property(property.getName(), property.getValue(), property.getSignature()); + } + public static GameProfile asAuthlibCopy(PlayerProfile profile) { + CraftPlayerProfile craft = ((CraftPlayerProfile) profile); + return asAuthlib(craft.clone()); + } + + public static GameProfile asAuthlib(PlayerProfile profile) { + CraftPlayerProfile craft = ((CraftPlayerProfile) profile); + return craft.getGameProfile(); + } + + private class PropertySet extends AbstractSet { + + @Override + @Nonnull + public Iterator iterator() { + return new ProfilePropertyIterator(profile.getProperties().values().iterator()); + } + + @Override + public int size() { + return profile.getProperties().size(); + } + + @Override + public boolean add(ProfileProperty property) { + setProperty(property); + return true; + } + + @Override + public boolean addAll(Collection c) { + //noinspection unchecked + setProperties((Collection) c); + return true; + } + + @Override + public boolean contains(Object o) { + return o instanceof ProfileProperty && profile.getProperties().containsKey(((ProfileProperty) o).getName()); + } + + private class ProfilePropertyIterator implements Iterator { + private final Iterator iterator; + + ProfilePropertyIterator(Iterator iterator) { + this.iterator = iterator; + } + + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public ProfileProperty next() { + return toBukkit(iterator.next()); + } + + @Override + public void remove() { + iterator.remove(); + } + } + } +} diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java index 02940d697..4539b5601 100644 --- a/src/main/java/net/minecraft/server/MCUtil.java +++ b/src/main/java/net/minecraft/server/MCUtil.java @@ -1,6 +1,9 @@ package net.minecraft.server; +import com.destroystokyo.paper.profile.CraftPlayerProfile; +import com.destroystokyo.paper.profile.PlayerProfile; import com.google.common.util.concurrent.ThreadFactoryBuilder; +import com.mojang.authlib.GameProfile; import org.apache.commons.lang.exception.ExceptionUtils; import org.bukkit.Location; import org.bukkit.craftbukkit.CraftWorld; @@ -66,6 +69,10 @@ public final class MCUtil { return run.get(); } + public static PlayerProfile toBukkit(GameProfile profile) { + return CraftPlayerProfile.asBukkitMirror(profile); + } + /** * Calculates distance between 2 entities * @param e1 diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java index e8bddc171..3b01ebd96 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -1538,6 +1538,7 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IAs this.H = i; } + public MinecraftSessionService getSessionService() { return az(); } // Paper - OBFHELPER public MinecraftSessionService az() { return this.W; } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java index 77c16fe2c..aca5ea7c0 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -135,6 +135,10 @@ import org.bukkit.craftbukkit.util.CraftNamespacedKey; import org.bukkit.event.server.TabCompleteEvent; import net.md_5.bungee.api.chat.BaseComponent; +import javax.annotation.Nullable; // Paper +import javax.annotation.Nonnull; // Paper + + public final class CraftServer implements Server { private final String serverName = "Paper"; private final String serverVersion; @@ -1923,5 +1927,17 @@ public final class CraftServer implements Server { public boolean suggestPlayerNamesWhenNullTabCompletions() { return com.destroystokyo.paper.PaperConfig.suggestPlayersWhenNullTabCompletions; } + + public com.destroystokyo.paper.profile.PlayerProfile createProfile(@Nonnull UUID uuid) { + return createProfile(uuid, null); + } + + public com.destroystokyo.paper.profile.PlayerProfile createProfile(@Nonnull String name) { + return createProfile(null, name); + } + + public com.destroystokyo.paper.profile.PlayerProfile createProfile(@Nullable UUID uuid, @Nullable String name) { + return new com.destroystokyo.paper.profile.CraftPlayerProfile(uuid, name); + } // Paper end } -- 2.16.2