30
30
import com .comphenix .protocol .utility .MinecraftVersion ;
31
31
import com .comphenix .protocol .wrappers .EnumWrappers .NativeGameMode ;
32
32
33
+ import javax .annotation .Nullable ;
34
+
33
35
/**
34
36
* Represents an immutable PlayerInfoData in the PLAYER_INFO packet.
35
37
* @author dmulloy2
@@ -43,6 +45,9 @@ public class PlayerInfoData {
43
45
private final NativeGameMode gameMode ;
44
46
private final WrappedGameProfile profile ;
45
47
private final WrappedChatComponent displayName ;
48
+ @ Nullable
49
+ private final WrappedRemoteChatSessionData remoteChatSessionData ;
50
+ @ Nullable
46
51
private final WrappedProfileKeyData profileKeyData ;
47
52
48
53
// This is the same order as the NMS class, minus the packet (which isn't a field)
@@ -54,21 +59,75 @@ public PlayerInfoData(WrappedGameProfile profile, int latency, NativeGameMode ga
54
59
this (profile .getUUID (), latency , true , gameMode , profile , displayName , keyData );
55
60
}
56
61
57
- public PlayerInfoData (UUID profileId , int latency , boolean listed , NativeGameMode gameMode , WrappedGameProfile profile , WrappedChatComponent displayName , WrappedProfileKeyData profileKeyData ) {
62
+ /**
63
+ * Constructs a new PlayerInfoData for Minecraft 1.19 or later without signature data
64
+ * @see PlayerInfoData#PlayerInfoData(UUID, int, boolean, NativeGameMode, WrappedGameProfile, WrappedChatComponent, WrappedRemoteChatSessionData)
65
+ *
66
+ * @param profileId the id of the profile (has to be non-null)
67
+ * @param latency the latency in milliseconds
68
+ * @param listed whether the player is listed in the tab list
69
+ * @param gameMode the game mode
70
+ * @param profile the game profile
71
+ * @param displayName display name in tab list (optional)
72
+ */
73
+ public PlayerInfoData (UUID profileId , int latency , boolean listed , NativeGameMode gameMode , WrappedGameProfile profile , WrappedChatComponent displayName ) {
74
+ this (profileId , latency , listed , gameMode , profile , displayName , (WrappedRemoteChatSessionData ) null );
75
+ }
76
+
77
+ /**
78
+ * Constructs a new PlayerInfoData for Minecraft 1.19. This is incompatible on 1.19.3.
79
+ * @see PlayerInfoData#PlayerInfoData(UUID, int, boolean, NativeGameMode, WrappedGameProfile, WrappedChatComponent, WrappedRemoteChatSessionData)
80
+ *
81
+ * @param profileId the id of the profile (has to be non-null)
82
+ * @param latency the latency in milliseconds
83
+ * @param listed whether the player is listed in the tab list
84
+ * @param gameMode the game mode
85
+ * @param profile the game profile
86
+ * @param displayName display name in tab list (optional)
87
+ * @param profileKeyData the public key for the profile or null
88
+ */
89
+ @ Deprecated
90
+ public PlayerInfoData (UUID profileId , int latency , boolean listed , NativeGameMode gameMode , WrappedGameProfile profile , WrappedChatComponent displayName , @ Nullable WrappedProfileKeyData profileKeyData ) {
58
91
this .profileId = profileId ;
59
92
this .latency = latency ;
60
93
this .listed = listed ;
61
94
this .gameMode = gameMode ;
62
95
this .profile = profile ;
63
96
this .displayName = displayName ;
64
97
this .profileKeyData = profileKeyData ;
98
+ this .remoteChatSessionData = null ;
99
+ }
100
+
101
+ /**
102
+ * Constructs a new PlayerInfoData for Minecraft 1.19.3 or later.
103
+ *
104
+ * @param profileId the id of the profile (has to be non-null)
105
+ * @param latency the latency in milliseconds
106
+ * @param listed whether the player is listed in the tab list
107
+ * @param gameMode the game mode
108
+ * @param profile the game profile
109
+ * @param displayName display name in tab list (optional)
110
+ * @param remoteChatSession the remote chat session for this profile or null
111
+ */
112
+ public PlayerInfoData (UUID profileId , int latency , boolean listed , NativeGameMode gameMode , WrappedGameProfile profile , WrappedChatComponent displayName , @ Nullable WrappedRemoteChatSessionData remoteChatSession ) {
113
+ this .profileId = profileId ;
114
+ this .latency = latency ;
115
+ this .listed = listed ;
116
+ this .gameMode = gameMode ;
117
+ this .profile = profile ;
118
+ this .displayName = displayName ;
119
+ this .profileKeyData = null ;
120
+ this .remoteChatSessionData = remoteChatSession ;
65
121
}
66
122
67
123
/**
68
124
* Get the id of the affected profile (since 1.19.3)
69
125
* @return the id of the profile
70
126
*/
71
127
public UUID getProfileId () {
128
+ if (profileId == null && profile != null ) {
129
+ return profile .getUUID (); // Ensure forward compatability
130
+ }
72
131
return profileId ;
73
132
}
74
133
@@ -97,7 +156,7 @@ public int getLatency() {
97
156
}
98
157
99
158
/**
100
- * Gets if the player is listed on the client.
159
+ * Gets if the player is listed on the client (since 1.19.3)
101
160
* @return if the player is listed
102
161
*/
103
162
public boolean isListed () {
@@ -121,11 +180,21 @@ public WrappedChatComponent getDisplayName() {
121
180
}
122
181
123
182
/**
124
- * Gets the profile key data of the player represented by this data, null if not present.
125
- * @return The profile key data
183
+ * Returns the public key of the profile (since 1.19). Returns the public key of the remote chat session since 1.19.3
184
+ * @return The public key of the profile.
126
185
*/
186
+ @ Nullable
127
187
public WrappedProfileKeyData getProfileKeyData () {
128
- return this .profileKeyData ;
188
+ return this .profileKeyData != null ? this .profileKeyData : (this .remoteChatSessionData != null ? this .remoteChatSessionData .getProfilePublicKey () : null );
189
+ }
190
+
191
+ /**
192
+ * Returns the remoteChatSessionData (since 1.19.3)
193
+ * @return The remote chat sesion data or null
194
+ */
195
+ @ Nullable
196
+ public WrappedRemoteChatSessionData getRemoteChatSessionData () {
197
+ return this .remoteChatSessionData ;
129
198
}
130
199
131
200
/**
@@ -157,8 +226,7 @@ public Object getGeneric(PlayerInfoData specific) {
157
226
args .add (MinecraftReflection .getIChatBaseComponentClass ());
158
227
159
228
if (MinecraftVersion .FEATURE_PREVIEW_UPDATE .atOrAbove ()) {
160
- // RemoteChatSession$a...
161
- args .add (MinecraftReflection .getRemoteChatSessionClass ().getClasses ()[0 ]);
229
+ args .add (MinecraftReflection .getRemoteChatSessionDataClass ());
162
230
} else if (MinecraftVersion .WILD_UPDATE .atOrAbove ()) {
163
231
args .add (MinecraftReflection .getProfilePublicKeyDataClass ());
164
232
}
@@ -175,26 +243,28 @@ public Object getGeneric(PlayerInfoData specific) {
175
243
Object gameMode = EnumWrappers .getGameModeConverter ().getGeneric (specific .gameMode );
176
244
Object displayName = specific .displayName != null ? specific .displayName .handle : null ;
177
245
246
+ Object profile = specific .profile != null ? specific .profile .handle : null ;
178
247
if (MinecraftVersion .FEATURE_PREVIEW_UPDATE .atOrAbove ()) {
179
248
return constructor .newInstance (
180
249
specific .profileId ,
181
- specific . profile . handle ,
250
+ profile ,
182
251
specific .listed ,
183
252
specific .latency ,
184
253
gameMode ,
185
254
displayName ,
186
- null ); // TODO: do we want to support this?
255
+ specific .remoteChatSessionData != null ? BukkitConverters .getWrappedRemoteChatSessionDataConverter ().getGeneric (specific .remoteChatSessionData ) : null
256
+ );
187
257
} else if (MinecraftVersion .WILD_UPDATE .atOrAbove ()) {
188
258
return constructor .newInstance (
189
- specific . profile . handle ,
259
+ profile ,
190
260
specific .latency ,
191
261
gameMode ,
192
262
displayName ,
193
263
specific .profileKeyData == null ? null : specific .profileKeyData .handle );
194
264
} else if (MinecraftVersion .CAVES_CLIFFS_1 .atOrAbove ()) {
195
- return constructor .newInstance (specific . profile . handle , specific .latency , gameMode , displayName );
265
+ return constructor .newInstance (profile , specific .latency , gameMode , displayName );
196
266
} else {
197
- return constructor .newInstance (null , specific . profile . handle , specific .latency , gameMode , displayName );
267
+ return constructor .newInstance (null , profile , specific .latency , gameMode , displayName );
198
268
}
199
269
} catch (Exception e ) {
200
270
throw new RuntimeException ("Failed to construct PlayerInfoData." , e );
@@ -222,8 +292,18 @@ public PlayerInfoData getSpecific(Object generic) {
222
292
MinecraftReflection .getIChatBaseComponentClass (), BukkitConverters .getWrappedChatComponentConverter ());
223
293
WrappedChatComponent displayName = displayNames .read (0 );
224
294
295
+ if (MinecraftVersion .FEATURE_PREVIEW_UPDATE .atOrAbove ()) {
296
+ return new PlayerInfoData (modifier .<UUID >withType (UUID .class ).read (0 ),
297
+ latency ,
298
+ modifier .<Boolean >withType (boolean .class ).read (0 ),
299
+ gameMode ,
300
+ gameProfile ,
301
+ displayName ,
302
+ modifier .withType (MinecraftReflection .getRemoteChatSessionDataClass (), BukkitConverters .getWrappedRemoteChatSessionDataConverter ()).read (0 )
303
+ );
304
+ }
225
305
WrappedProfileKeyData key = null ;
226
- if (MinecraftVersion .WILD_UPDATE .atOrAbove () && ! MinecraftVersion . FEATURE_PREVIEW_UPDATE . atOrAbove () ) {
306
+ if (MinecraftVersion .WILD_UPDATE .atOrAbove ()) {
227
307
StructureModifier <WrappedProfileKeyData > keyData = modifier .withType (
228
308
MinecraftReflection .getProfilePublicKeyDataClass (), BukkitConverters .getWrappedPublicKeyDataConverter ());
229
309
key = keyData .read (0 );
@@ -253,20 +333,34 @@ public boolean equals(Object obj) {
253
333
// Only compare objects of similar type
254
334
if (obj instanceof PlayerInfoData ) {
255
335
PlayerInfoData other = (PlayerInfoData ) obj ;
256
- return profile .equals (other .profile ) && latency == other .latency && gameMode == other .gameMode
257
- && Objects .equals (displayName , other .displayName );
336
+ return Objects .equals (profile , other .profile )
337
+ && Objects .equals (profileId , other .profileId )
338
+ && latency == other .latency
339
+ && gameMode == other .gameMode
340
+ && Objects .equals (displayName , other .displayName )
341
+ && listed == other .listed
342
+ && Objects .equals (remoteChatSessionData , other .remoteChatSessionData )
343
+ && Objects .equals (profileKeyData , other .profileKeyData );
258
344
}
259
345
return false ;
260
346
}
261
347
262
348
@ Override
263
349
public int hashCode () {
264
- return Objects .hash (latency , gameMode , profile , displayName );
350
+ return Objects .hash (latency , gameMode , profile , displayName , profileKeyData , remoteChatSessionData , listed );
265
351
}
266
352
267
353
@ Override
268
354
public String toString () {
355
+ if (MinecraftVersion .FEATURE_PREVIEW_UPDATE .atOrAbove ()) {
356
+ return String .format ("PlayerInfoData[latency=%s, listed=%b, gameMode=%s, profile=%s, displayName=%s, remoteChatSession=%s]" ,
357
+ latency , listed , gameMode , profile , displayName , remoteChatSessionData );
358
+ }
359
+ if (MinecraftVersion .WILD_UPDATE .atOrAbove ()) {
360
+ return String .format ("PlayerInfoData[latency=%s, listed=%b, gameMode=%s, profile=%s, displayName=%s, profilePublicKey=%s]" ,
361
+ latency , listed , gameMode , profile , displayName , profileKeyData );
362
+ }
269
363
return String .format ("PlayerInfoData[latency=%s, gameMode=%s, profile=%s, displayName=%s]" ,
270
- latency , gameMode , profile , displayName );
364
+ latency , gameMode , profile , displayName );
271
365
}
272
366
}
0 commit comments