package net.glowstone.entity.meta.profile; import lombok.Data; import net.glowstone.GlowServer; import net.glowstone.entity.GlowPlayer; import net.glowstone.util.UuidUtils; import net.glowstone.util.nbt.CompoundTag; import net.glowstone.util.nbt.Tag; import org.apache.commons.lang3.Validate; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import java.util.*; import java.util.logging.Level; /** * Information about a player's name, UUID, and other properties. */ @Data public final class PlayerProfile { private final String name; private final UUID uniqueId; private final List<PlayerProperty> properties; public static final int MAX_USERNAME_LENGTH = 16; /** * Construct a new profile with only a name and UUID. * @param name The player's name. * @param uuid The player's UUID. */ public PlayerProfile(String name, UUID uuid) { this(name, uuid, Collections.<PlayerProperty>emptyList()); } /** * Construct a new profile with additional properties. * @param name The player's name. * @param uuid The player's UUID. * @param properties A list of extra properties. * @throws IllegalArgumentException if any arguments are null. */ public PlayerProfile(String name, UUID uuid, List<PlayerProperty> properties) { Validate.notNull(uuid, "uuid must not be null"); Validate.notNull(properties, "properties must not be null"); if (null == name) { PlayerProfile profile = ProfileCache.getProfile(uuid); name = profile != null ? profile.getName() : null; } this.name = name; this.uniqueId = uuid; this.properties = properties; } /** * Get the profile for a username. * @param name The username to lookup. * @return The profile. */ public static PlayerProfile getProfile(String name) { if (name == null || name.length() > MAX_USERNAME_LENGTH || name.isEmpty()) { return null; } Player player = ((GlowServer) Bukkit.getServer()).getPlayer(name); if (player != null) { return ((GlowPlayer) player).getProfile(); } UUID uuid = ProfileCache.getUUID(name); if (uuid != null) { return ProfileCache.getProfile(uuid); } GlowServer.logger.warning("Unable to get UUID for username: " + name); return null; } public CompoundTag toNBT() { CompoundTag profileTag = new CompoundTag(); profileTag.putString("Id", uniqueId.toString()); profileTag.putString("Name", name); CompoundTag propertiesTag = new CompoundTag(); for (PlayerProperty property : properties) { CompoundTag propertyValueTag = new CompoundTag(); propertyValueTag.putString("Signature", property.getSignature()); propertyValueTag.putString("Value", property.getValue()); propertiesTag.putCompoundList(property.getName(), Arrays.asList(propertyValueTag)); } if (!propertiesTag.isEmpty()) { // Only add properties if not empty profileTag.putCompound("Properties", propertiesTag); } return profileTag; } public static PlayerProfile fromNBT(CompoundTag tag) { // NBT: {Id: "", Name: "", Properties: {textures: [{Signature: "", Value: {}}]}} String uuidStr = tag.getString("Id"); String name = tag.getString("Name"); List<PlayerProperty> properties = new ArrayList<>(); if (tag.containsKey("Properties")) { for (Map.Entry<String, Tag> property : tag.getCompound("Properties").getValue().entrySet()) { @SuppressWarnings("unchecked") CompoundTag propertyValueTag = ((List<CompoundTag>) property.getValue().getValue()).get(0); properties.add(new PlayerProperty(property.getKey(), propertyValueTag.getString("Value"), propertyValueTag.getString("Signature"))); } } return new PlayerProfile(name, UUID.fromString(uuidStr), properties); } public static PlayerProfile fromJson(JSONObject json) { final String name = (String) json.get("name"); final String id = (String) json.get("id"); final JSONArray propsArray = (JSONArray) json.get("properties"); // Parse UUID final UUID uuid; try { uuid = UuidUtils.fromFlatString(id); } catch (IllegalArgumentException ex) { GlowServer.logger.log(Level.SEVERE, "Returned authentication UUID invalid: " + id); return null; } // Parse properties final List<PlayerProperty> properties = new ArrayList<>(propsArray.size()); for (Object obj : propsArray) { JSONObject propJson = (JSONObject) obj; String propName = (String) propJson.get("name"); String value = (String) propJson.get("value"); String signature = (String) propJson.get("signature"); properties.add(new PlayerProperty(propName, value, signature)); } return new PlayerProfile(name, uuid, properties); } }