1
- use anyhow:: bail;
1
+ use std:: io:: Cursor ;
2
+
3
+ use anyhow:: { anyhow, bail} ;
2
4
3
5
use base:: {
4
6
BlockState , EntityMetadata , Gamemode , ParticleKind , ProfileProperty , ValidBlockPosition ,
@@ -7,7 +9,7 @@ pub use chunk_data::{ChunkData, ChunkDataKind};
7
9
use quill_common:: components:: PreviousGamemode ;
8
10
pub use update_light:: UpdateLight ;
9
11
10
- use crate :: { io:: VarLong , Readable , Writeable } ;
12
+ use crate :: { io:: VarLong , ProtocolVersion , Readable , Writeable } ;
11
13
12
14
use super :: * ;
13
15
@@ -334,8 +336,7 @@ packets! {
334
336
}
335
337
336
338
ChangeGameState {
337
- reason StateReason ;
338
- value f32 ;
339
+ state_change GameStateChange ;
339
340
}
340
341
341
342
OpenHorseWindow {
@@ -356,22 +357,131 @@ packets! {
356
357
}
357
358
}
358
359
359
- def_enum ! {
360
- StateReason ( i8 ) {
361
- 0 = NoRespawnBlock ,
362
- 1 = EndRaining ,
363
- 2 = BeginningRain ,
364
- 3 = ChangeGameMode ,
365
- 4 = WinGame ,
366
- 5 = DemoEvent ,
367
- 6 = ArrowHitPlayer ,
368
- 7 = RainLevelChange ,
369
- 8 = ThunderLevelChange ,
370
- 9 = PufferfishSting ,
371
- 10 = ElderGuardianAppearance ,
372
- 11 = EnableRespawnScreen ,
360
+ #[ derive( Debug , Clone ) ]
361
+ pub enum GameStateChange {
362
+ /// Sends block.minecraft.spawn.not_valid to client
363
+ SendNoRespawnBlockAvailableMessage ,
364
+ EndRaining ,
365
+ BeginRaining ,
366
+ ChangeGamemode {
367
+ gamemode : Gamemode ,
368
+ } ,
369
+ /// Sent when the player enters an end portal from minecraft:the_end to minecraft:overworld
370
+ WinGame {
371
+ show_credits : bool ,
372
+ } ,
373
+ /// See https://help.minecraft.net/hc/en-us/articles/4408948974989-Minecraft-Java-Edition-Demo-Mode-
374
+ DemoEvent ( DemoEventType ) ,
375
+ /// Sent when any player is struck by an arrow.
376
+ ArrowHitAnyPlayer ,
377
+ /// Seems to change both skycolor and lightning.
378
+ RainLevelChange {
379
+ /// Possible values are from 0 to 1
380
+ rain_level : f64 ,
381
+ } ,
382
+ /// Seems to change both skycolor and lightning (same as Rain level change, but doesn't start rain).
383
+ /// It also requires rain to render by notchian client.
384
+ ThunderLevelChange {
385
+ /// Possible values are from 0 to 1
386
+ thunder_level : f64 ,
387
+ } ,
388
+ PlayPufferfishStingSound ,
389
+ PlayElderGuardianAppearance ,
390
+ /// Send when doImmediateRespawn gamerule changes.
391
+ EnableRespawnScreen {
392
+ enable : bool ,
393
+ } ,
394
+ }
395
+
396
+ #[ derive( Debug , Clone ) ]
397
+ pub enum DemoEventType {
398
+ ShowWelcomeToDemoScreen ,
399
+ TellMovementControls ,
400
+ TellJumpControl ,
401
+ TellInventoryControl ,
402
+ TellDemoIsOver ,
403
+ }
404
+
405
+ impl Writeable for GameStateChange {
406
+ fn write ( & self , buffer : & mut Vec < u8 > , version : ProtocolVersion ) -> anyhow:: Result < ( ) > {
407
+ // Reason
408
+ match self {
409
+ GameStateChange :: SendNoRespawnBlockAvailableMessage => 0u8 ,
410
+ GameStateChange :: EndRaining => 1 ,
411
+ GameStateChange :: BeginRaining => 2 ,
412
+ GameStateChange :: ChangeGamemode { .. } => 3 ,
413
+ GameStateChange :: WinGame { .. } => 4 ,
414
+ GameStateChange :: DemoEvent ( _) => 5 ,
415
+ GameStateChange :: ArrowHitAnyPlayer => 6 ,
416
+ GameStateChange :: RainLevelChange { .. } => 7 ,
417
+ GameStateChange :: ThunderLevelChange { .. } => 8 ,
418
+ GameStateChange :: PlayPufferfishStingSound => 9 ,
419
+ GameStateChange :: PlayElderGuardianAppearance => 10 ,
420
+ GameStateChange :: EnableRespawnScreen { .. } => 11 ,
421
+ }
422
+ . write ( buffer, version) ?;
423
+
424
+ // Value
425
+ match self {
426
+ GameStateChange :: ChangeGamemode { gamemode } => * gamemode as u8 as f64 ,
427
+ GameStateChange :: WinGame { show_credits } => * show_credits as u8 as f64 ,
428
+ GameStateChange :: DemoEvent ( DemoEventType :: ShowWelcomeToDemoScreen ) => 0.0 ,
429
+ GameStateChange :: DemoEvent ( DemoEventType :: TellMovementControls ) => 101.0 ,
430
+ GameStateChange :: DemoEvent ( DemoEventType :: TellJumpControl ) => 102.0 ,
431
+ GameStateChange :: DemoEvent ( DemoEventType :: TellInventoryControl ) => 103.0 ,
432
+ GameStateChange :: DemoEvent ( DemoEventType :: TellDemoIsOver ) => 104.0 ,
433
+ GameStateChange :: RainLevelChange { rain_level } => * rain_level,
434
+ GameStateChange :: ThunderLevelChange { thunder_level } => * thunder_level,
435
+ GameStateChange :: EnableRespawnScreen { enable } => !enable as u8 as f64 ,
436
+ _ => 0.0 ,
437
+ }
438
+ . write ( buffer, version) ?;
439
+
440
+ Ok ( ( ) )
373
441
}
374
442
}
443
+
444
+ impl Readable for GameStateChange {
445
+ fn read ( buffer : & mut Cursor < & [ u8 ] > , version : ProtocolVersion ) -> anyhow:: Result < Self >
446
+ where
447
+ Self : Sized ,
448
+ {
449
+ let reason = u8:: read ( buffer, version) ?;
450
+ let value = f64:: read ( buffer, version) ?;
451
+ Ok ( match reason {
452
+ 0 => GameStateChange :: SendNoRespawnBlockAvailableMessage ,
453
+ 1 => GameStateChange :: EndRaining ,
454
+ 2 => GameStateChange :: BeginRaining ,
455
+ 3 => GameStateChange :: ChangeGamemode {
456
+ gamemode : Gamemode :: from_id ( value as u8 )
457
+ . ok_or ( anyhow ! ( "Unsupported gamemode ID" ) ) ?,
458
+ } ,
459
+ 4 => GameStateChange :: WinGame {
460
+ show_credits : value as u8 != 0 ,
461
+ } ,
462
+ 5 => GameStateChange :: DemoEvent ( match value as u8 {
463
+ 0 => DemoEventType :: ShowWelcomeToDemoScreen ,
464
+ 101 => DemoEventType :: TellMovementControls ,
465
+ 102 => DemoEventType :: TellJumpControl ,
466
+ 103 => DemoEventType :: TellInventoryControl ,
467
+ 104 => DemoEventType :: TellDemoIsOver ,
468
+ other => bail ! ( "Invalid demo event type: {}" , other) ,
469
+ } ) ,
470
+ 6 => GameStateChange :: ArrowHitAnyPlayer ,
471
+ 7 => GameStateChange :: RainLevelChange { rain_level : value } ,
472
+ 8 => GameStateChange :: ThunderLevelChange {
473
+ thunder_level : value,
474
+ } ,
475
+ 9 => GameStateChange :: PlayPufferfishStingSound ,
476
+ 10 => GameStateChange :: PlayElderGuardianAppearance ,
477
+ 11 => GameStateChange :: EnableRespawnScreen {
478
+ enable : value as u8 == 0 ,
479
+ } ,
480
+ other => bail ! ( "Invalid game state change reason: {}" , other) ,
481
+ } )
482
+ }
483
+ }
484
+
375
485
packets ! {
376
486
JoinGame {
377
487
entity_id i32 ;
0 commit comments