@@ -34,20 +34,16 @@ def player_joined(self):
34
34
# in-game, and does some logging.
35
35
ServerProtocol .player_joined (self )
36
36
37
- # Send server data packet on 1.19+
38
- if self .protocol_version >= 760 :
39
- self .send_packet ('server_data' ,
40
- self .buff_type .pack ('????' ,
41
- False , # Optional description
42
- False , # Optional favicon
43
- False , # Disable chat previews
44
- self .factory .online_mode )) # Enforce chat signing when in online mode
45
- elif self .protocol_version == 759 : # 1.19 lacks enforce chat signing field
46
- self .send_packet ('server_data' , self .buff_type .pack ('???' , False , False , False ))
37
+ # Send server data
38
+ self .factory .send_server_data (self )
47
39
48
40
# Send join game packet
49
41
self .factory .send_join_game (self )
50
42
43
+ # 1.19.3+ Send default spawn position, required to hide Loading Terrain screen
44
+ if self .protocol_version >= 761 :
45
+ self .send_packet ("spawn_position" , self .buff_type .pack ("iii" , 0 , 0 , 0 ))
46
+
51
47
# Send "Player Position and Look" packet
52
48
self .send_packet (
53
49
"player_position_and_look" ,
@@ -225,6 +221,27 @@ class ChatRoomFactory(ServerFactory):
225
221
protocol = ChatRoomProtocol
226
222
motd = "Chat Room Server"
227
223
224
+ def send_server_data (self , player ):
225
+ # 1.19.3+ removed chat preview field
226
+ if player .protocol_version >= 761 :
227
+ player .send_packet ('server_data' ,
228
+ player .buff_type .pack ('???' ,
229
+ False ,
230
+ False ,
231
+ self .online_mode )) # Enforce chat signing when in online mode
232
+
233
+ # 1.19 added enforce chat signing field
234
+ elif player .protocol_version >= 760 :
235
+ player .send_packet ('server_data' ,
236
+ player .buff_type .pack ('????' ,
237
+ False ,
238
+ False ,
239
+ False ,
240
+ self .online_mode )) # Enforce chat signing when in online mode
241
+
242
+ elif player .protocol_version == 759 :
243
+ player .send_packet ('server_data' , self .buff_type .pack ('???' , False , False , False ))
244
+
228
245
def send_join_game (self , player ):
229
246
# Build up fields for "Join Game" packet
230
247
entity_id = 0
@@ -375,10 +392,17 @@ def broadcast_player_list_add(self, added: ChatRoomProtocol):
375
392
376
393
@staticmethod
377
394
def send_player_list_add (player : ChatRoomProtocol , added : List [ChatRoomProtocol ]):
378
- data = [
379
- player .buff_type .pack_varint (0 ), # Action - 0 = Player add
380
- player .buff_type .pack_varint (len (added )), # Player entry count
381
- ]
395
+ data = []
396
+
397
+ # 1.19.3+ splits the player list into separate remove and update packets (which also add players)
398
+ # Update packets use a bitset to indicate which player information is being added/updated
399
+ if player .protocol_version >= 761 :
400
+ data .append (player .buff_type .pack ('B' , 63 )) # Set first 6 bits to indicate all fields are being updated
401
+
402
+ else : # Older versions have a single packet with a varint for "action", 0 being adding a player
403
+ data .append (player .buff_type .pack_varint (0 ))
404
+
405
+ data .append (player .buff_type .pack_varint (len (added ))) # Player entry count
382
406
383
407
for entry in added :
384
408
if entry .protocol_mode != 'play' :
@@ -387,12 +411,22 @@ def send_player_list_add(player: ChatRoomProtocol, added: List[ChatRoomProtocol]
387
411
data .append (player .buff_type .pack_uuid (entry .uuid )) # Player UUID
388
412
data .append (player .buff_type .pack_string (entry .display_name )) # Player name
389
413
data .append (player .buff_type .pack_varint (0 )) # Empty properties list
414
+
415
+ # 1.19.3+ include the players public key here
416
+ if player .protocol_version >= 761 :
417
+ data .append (player .buff_type .pack ('?' , False ))
418
+
390
419
data .append (player .buff_type .pack_varint (3 )) # Gamemode
420
+
421
+ # 1.19.3+ includes an extra field for whether to update the tab list
422
+ if player .protocol_version >= 761 :
423
+ data .append (player .buff_type .pack ('?' , True ))
424
+
391
425
data .append (player .buff_type .pack_varint (0 )) # Latency
392
426
data .append (player .buff_type .pack ('?' , False )) # No display name
393
427
394
- # Add signature for 1.19+ clients if it exists
395
- if player .protocol_version >= 759 :
428
+ # 1.19 - 1.19.1 include the players public key here
429
+ if 759 <= player .protocol_version < 761 :
396
430
data .append (player .buff_type .pack_optional (player .buff_type .pack_player_public_key , entry .public_key_data ))
397
431
398
432
player .send_packet ('player_list_item' , * data )
@@ -401,10 +435,16 @@ def send_player_list_add(player: ChatRoomProtocol, added: List[ChatRoomProtocol]
401
435
def broadcast_player_list_remove (self , removed : ChatRoomProtocol ):
402
436
for player in self .players :
403
437
if player .protocol_mode == 'play' and player != removed :
404
- player .send_packet ('player_list_item' ,
405
- player .buff_type .pack_varint (4 ), # Action - 4 = Player remove
406
- player .buff_type .pack_varint (1 ), # Player entry count
407
- player .buff_type .pack_uuid (removed .uuid )) # Player UUID
438
+
439
+ if player .protocol_version >= 761 : # 1.19.3 has separate packet for player list removals
440
+ player .send_packet ('player_list_remove' ,
441
+ player .buff_type .pack_varint (1 ), # Player entry count
442
+ player .buff_type .pack_uuid (removed .uuid )) # Player UUID
443
+ else :
444
+ player .send_packet ('player_list_item' ,
445
+ player .buff_type .pack_varint (4 ), # Action - 4 = Player remove
446
+ player .buff_type .pack_varint (1 ), # Player entry count
447
+ player .buff_type .pack_uuid (removed .uuid )) # Player UUID
408
448
409
449
410
450
def main (argv ):
0 commit comments