diff --git a/src/main/java/com/comphenix/protocol/events/PacketEvent.java b/src/main/java/com/comphenix/protocol/events/PacketEvent.java index df3f3c20..6c602252 100644 --- a/src/main/java/com/comphenix/protocol/events/PacketEvent.java +++ b/src/main/java/com/comphenix/protocol/events/PacketEvent.java @@ -527,7 +527,7 @@ public class PacketEvent extends EventObject implements Cancellable { // Write the name of the player (or NULL if it's not set) Player player = getPlayer(); - output.writeObject(player != null ? new SerializedOfflinePlayer(player) : null); + output.writeObject(player != null ? SerializedOfflinePlayer.init(player) : null); } private void readObject(ObjectInputStream input) throws ClassNotFoundException, IOException { diff --git a/src/main/java/com/comphenix/protocol/events/SerializedOfflinePlayer.java b/src/main/java/com/comphenix/protocol/events/SerializedOfflinePlayer.java index 57713e19..3ecc54a5 100644 --- a/src/main/java/com/comphenix/protocol/events/SerializedOfflinePlayer.java +++ b/src/main/java/com/comphenix/protocol/events/SerializedOfflinePlayer.java @@ -51,8 +51,12 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.time.Duration; import java.time.Instant; +import java.util.ArrayList; import java.util.Date; +import java.util.HashSet; +import java.util.List; import java.util.Map; +import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; @@ -61,7 +65,7 @@ import java.util.concurrent.ConcurrentHashMap; * * @author Kristian */ -class SerializedOfflinePlayer implements OfflinePlayer, Serializable { +abstract class SerializedOfflinePlayer implements OfflinePlayer, Serializable { /** * Generated by Eclipse. @@ -84,11 +88,33 @@ class SerializedOfflinePlayer implements OfflinePlayer, Serializable { private long lastSeen; private static final Constructor> proxyPlayerConstructor = setupProxyPlayerConstructor(); + private static final Constructor extends SerializedOfflinePlayer> CLASS_CONSTRUCTOR = setupClassConstructor(); + + /** + * Initialize a serializable offline player object from another offline player. + *
+ * All other methods cause an exception.
+ *
+ * @param player - another offline player.
+ * @return A serializable offline player object.
+ */
+ public static SerializedOfflinePlayer init(OfflinePlayer player) {
+ try {
+ CLASS_CONSTRUCTOR.setAccessible(true);
+ return CLASS_CONSTRUCTOR.newInstance(player);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException("Cannot access reflection.", e);
+ } catch (InstantiationException e) {
+ throw new RuntimeException("Cannot instantiate object.", e);
+ } catch (InvocationTargetException e) {
+ throw new RuntimeException("Error in invocation.", e);
+ }
+ }
/**
* Constructor used by serialization.
*/
- public SerializedOfflinePlayer() {
+ protected SerializedOfflinePlayer() {
// Do nothing
}
@@ -97,7 +123,7 @@ class SerializedOfflinePlayer implements OfflinePlayer, Serializable {
*
* @param offline - another player.
*/
- public SerializedOfflinePlayer(OfflinePlayer offline) {
+ protected SerializedOfflinePlayer(OfflinePlayer offline) {
this.name = offline.getName();
this.uuid = offline.getUniqueId();
this.firstPlayed = offline.getFirstPlayed();
@@ -342,6 +368,47 @@ class SerializedOfflinePlayer implements OfflinePlayer, Serializable {
}
}
+ private static Constructor extends SerializedOfflinePlayer> setupClassConstructor() {
+ final Method[] existingMethods = SerializedOfflinePlayer.class.getDeclaredMethods();
+ final Set