Optimize GameProfile and add Identifiable interface

This commit is contained in:
Yeregorix 2018-11-12 19:50:52 +01:00
parent c94794a845
commit b6bb4ad1a1
11 changed files with 118 additions and 34 deletions

View File

@ -7,6 +7,7 @@ import com.velocitypowered.api.proxy.player.PlayerSettings;
import com.velocitypowered.api.proxy.player.TabList;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import com.velocitypowered.api.util.GameProfile;
import com.velocitypowered.api.util.Identifiable;
import com.velocitypowered.api.util.MessagePosition;
import com.velocitypowered.api.util.ModInfo;
import com.velocitypowered.api.util.title.Title;
@ -19,7 +20,7 @@ import net.kyori.text.Component;
* Represents a player who is connected to the proxy.
*/
public interface Player extends CommandSource, InboundConnection, ChannelMessageSource,
ChannelMessageSink {
ChannelMessageSink, Identifiable {
/**
* Returns the player's current username.
@ -28,13 +29,6 @@ public interface Player extends CommandSource, InboundConnection, ChannelMessage
*/
String getUsername();
/**
* Returns the player's UUID.
*
* @return the UUID
*/
UUID getUniqueId();
/**
* Returns the server that the player is currently connected to.
*

View File

@ -8,24 +8,36 @@ import java.util.UUID;
/**
* Represents a Mojang game profile. This class is immutable.
*/
public final class GameProfile {
public final class GameProfile implements Identifiable {
private final String id;
private final String name;
private final UUID id;
private final String undashedId, name;
private final List<Property> properties;
public GameProfile(String id, String name, List<Property> properties) {
this.id = Preconditions.checkNotNull(id, "id");
this.name = Preconditions.checkNotNull(name, "name");
this.properties = ImmutableList.copyOf(properties);
public GameProfile(UUID id, String name, List<Property> properties) {
this(Preconditions.checkNotNull(id, "id"), UuidUtils.toUndashed(id),
Preconditions.checkNotNull(name, "name"), ImmutableList.copyOf(properties));
}
public String getId() {
return id;
public GameProfile(String undashedId, String name, List<Property> properties) {
this(UuidUtils.fromUndashed(Preconditions.checkNotNull(undashedId, "undashedId")), undashedId,
Preconditions.checkNotNull(name, "name"), ImmutableList.copyOf(properties));
}
public UUID idAsUuid() {
return UuidUtils.fromUndashed(id);
private GameProfile(UUID id, String undashedId, String name, List<Property> properties) {
this.id = id;
this.undashedId = undashedId;
this.name = name;
this.properties = properties;
}
@Override
public UUID getUniqueId() {
return this.id;
}
public String getUndashedId() {
return this.undashedId;
}
public String getName() {
@ -36,6 +48,36 @@ public final class GameProfile {
return properties;
}
public GameProfile setUniqueId(UUID id) {
return new GameProfile(Preconditions.checkNotNull(id, "id"), UuidUtils.toUndashed(id),
this.name, this.properties);
}
public GameProfile setUndashedId(String undashedId) {
return new GameProfile(
UuidUtils.fromUndashed(Preconditions.checkNotNull(undashedId, "undashedId")), undashedId,
this.name, this.properties);
}
public GameProfile setName(String name) {
return new GameProfile(this.id, this.undashedId, Preconditions.checkNotNull(name, "name"),
this.properties);
}
public GameProfile setProperties(List<Property> properties) {
return new GameProfile(this.id, this.undashedId, this.name, ImmutableList.copyOf(properties));
}
public GameProfile addProperties(Iterable<Property> properties) {
return new GameProfile(this.id, this.undashedId, this.name,
ImmutableList.<Property>builder().addAll(this.properties).addAll(properties).build());
}
public GameProfile addProperty(Property property) {
return new GameProfile(this.id, this.undashedId, this.name,
ImmutableList.<Property>builder().addAll(this.properties).add(property).build());
}
/**
* Creates a game profile suitable for use in offline-mode.
*
@ -44,8 +86,8 @@ public final class GameProfile {
*/
public static GameProfile forOfflinePlayer(String username) {
Preconditions.checkNotNull(username, "username");
String id = UuidUtils.toUndashed(UuidUtils.generateOfflinePlayerUuid(username));
return new GameProfile(id, username, ImmutableList.of());
return new GameProfile(UuidUtils.generateOfflinePlayerUuid(username), username,
ImmutableList.of());
}
@Override

View File

@ -0,0 +1,11 @@
package com.velocitypowered.api.util;
import java.util.UUID;
/**
* Represents an object that can be identified by its UUID
*/
public interface Identifiable {
UUID getUniqueId();
}

View File

@ -15,6 +15,7 @@ import com.velocitypowered.api.proxy.ProxyServer;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import com.velocitypowered.api.proxy.server.ServerInfo;
import com.velocitypowered.api.util.Favicon;
import com.velocitypowered.api.util.GameProfile;
import com.velocitypowered.api.util.ProxyVersion;
import com.velocitypowered.proxy.command.ServerCommand;
import com.velocitypowered.proxy.command.ShutdownCommand;
@ -30,6 +31,7 @@ import com.velocitypowered.proxy.plugin.VelocityEventManager;
import com.velocitypowered.proxy.plugin.VelocityPluginManager;
import com.velocitypowered.proxy.protocol.packet.Chat;
import com.velocitypowered.proxy.protocol.util.FaviconSerializer;
import com.velocitypowered.proxy.protocol.util.GameProfileSerializer;
import com.velocitypowered.proxy.scheduler.VelocityScheduler;
import com.velocitypowered.proxy.server.ServerMap;
import com.velocitypowered.proxy.util.AddressUtil;
@ -65,6 +67,7 @@ public class VelocityServer implements ProxyServer {
public static final Gson GSON = new GsonBuilder()
.registerTypeHierarchyAdapter(Component.class, new GsonComponentSerializer())
.registerTypeHierarchyAdapter(Favicon.class, new FaviconSerializer())
.registerTypeHierarchyAdapter(GameProfile.class, new GameProfileSerializer())
.create();
private @MonotonicNonNull ConnectionManager cm;

View File

@ -157,7 +157,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
try {
ProtocolUtils.writeVarInt(dataToForward, VelocityConstants.FORWARDING_VERSION);
ProtocolUtils.writeString(dataToForward, address);
ProtocolUtils.writeUuid(dataToForward, profile.idAsUuid());
ProtocolUtils.writeUuid(dataToForward, profile.getUniqueId());
ProtocolUtils.writeString(dataToForward, profile.getName());
ProtocolUtils.writeProperties(dataToForward, profile.getProperties());

View File

@ -109,7 +109,7 @@ public class VelocityServerConnection implements MinecraftConnectionAssociation,
.append('\0')
.append(proxyPlayer.getRemoteAddress().getHostString())
.append('\0')
.append(proxyPlayer.getProfile().getId())
.append(proxyPlayer.getProfile().getUndashedId())
.append('\0');
GSON.toJson(proxyPlayer.getProfile().getProperties(), data);
return data.toString();

View File

@ -100,7 +100,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
@Override
public UUID getUniqueId() {
return profile.idAsUuid();
return profile.getUniqueId();
}
@Override
@ -212,8 +212,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
@Override
public void setGameProfileProperties(List<GameProfile.Property> properties) {
Preconditions.checkNotNull(properties);
this.profile = new GameProfile(profile.getId(), profile.getName(), properties);
this.profile = profile.setProperties(Preconditions.checkNotNull(properties));
}
@Override

View File

@ -219,9 +219,7 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
if (inbound.isLegacyForge()
&& server.getConfiguration().getPlayerInfoForwardingMode() == PlayerInfoForwarding.LEGACY) {
// We want to add the FML token to the properties
List<GameProfile.Property> properties = new ArrayList<>(profile.getProperties());
properties.add(new GameProfile.Property("forgeClient", "true", ""));
profile = new GameProfile(profile.getId(), profile.getName(), properties);
profile = profile.addProperty(new GameProfile.Property("forgeClient", "true", ""));
}
GameProfileRequestEvent profileRequestEvent = new GameProfileRequestEvent(apiInbound, profile,
onlineMode);

View File

@ -142,7 +142,7 @@ public class PlayerListItem implements MinecraftPacket {
}
public static Item from(TabListEntry entry) {
return new Item(entry.getProfile().idAsUuid())
return new Item(entry.getProfile().getUniqueId())
.setName(entry.getProfile().getName())
.setProperties(entry.getProfile().getProperties())
.setLatency(entry.getLatency())

View File

@ -0,0 +1,37 @@
package com.velocitypowered.proxy.protocol.util;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.google.gson.reflect.TypeToken;
import com.velocitypowered.api.util.GameProfile;
import com.velocitypowered.api.util.GameProfile.Property;
import java.lang.reflect.Type;
import java.util.List;
public class GameProfileSerializer implements JsonSerializer<GameProfile>,
JsonDeserializer<GameProfile> {
private static final Type propertyList = new TypeToken<List<Property>>() {}.getType();
@Override
public GameProfile deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context) {
JsonObject obj = json.getAsJsonObject();
return new GameProfile(obj.get("id").getAsString(), obj.get("name").getAsString(),
context.deserialize(obj.get("properties"), propertyList));
}
@Override
public JsonElement serialize(GameProfile src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject obj = new JsonObject();
obj.add("id", new JsonPrimitive(src.getUndashedId()));
obj.add("name", new JsonPrimitive(src.getName()));
obj.add("properties", context.serialize(src.getProperties(), propertyList));
return obj;
}
}

View File

@ -45,13 +45,13 @@ public class VelocityTabList implements TabList {
Preconditions.checkNotNull(entry, "entry");
Preconditions.checkArgument(entry.getTabList().equals(this),
"The provided entry was not created by this tab list");
Preconditions.checkArgument(!entries.containsKey(entry.getProfile().idAsUuid()),
Preconditions.checkArgument(!entries.containsKey(entry.getProfile().getUniqueId()),
"this TabList already contains an entry with the same uuid");
PlayerListItem.Item packetItem = PlayerListItem.Item.from(entry);
connection.write(
new PlayerListItem(PlayerListItem.ADD_PLAYER, Collections.singletonList(packetItem)));
entries.put(entry.getProfile().idAsUuid(), entry);
entries.put(entry.getProfile().getUniqueId(), entry);
}
@Override
@ -105,7 +105,7 @@ public class VelocityTabList implements TabList {
}
entries.put(item.getUuid(), TabListEntry.builder()
.tabList(this)
.profile(new GameProfile(UuidUtils.toUndashed(uuid), name, properties))
.profile(new GameProfile(uuid, name, properties))
.displayName(item.getDisplayName())
.latency(item.getLatency())
.gameMode(item.getGameMode())
@ -141,7 +141,7 @@ public class VelocityTabList implements TabList {
}
void updateEntry(int action, TabListEntry entry) {
if (entries.containsKey(entry.getProfile().idAsUuid())) {
if (entries.containsKey(entry.getProfile().getUniqueId())) {
PlayerListItem.Item packetItem = PlayerListItem.Item.from(entry);
connection.write(new PlayerListItem(action, Collections.singletonList(packetItem)));
}