@@ -8,12 +8,16 @@ use hyperion::{
8
8
player_join:: { PlayerListActions , PlayerListEntry , PlayerListS2c } ,
9
9
} ,
10
10
net:: { Compose , DataBundle , NetworkStreamRef , agnostic} ,
11
+ simulation:: { Pitch , Position , Yaw } ,
11
12
system_registry:: SystemId ,
12
13
valence_ident:: ident,
13
14
valence_protocol:: {
14
- GameMode , VarInt ,
15
+ BlockPos , GameMode , VarInt ,
15
16
game_mode:: OptGameMode ,
16
- packets:: { play, play:: PlayerRespawnS2c } ,
17
+ packets:: {
18
+ play,
19
+ play:: { PlayerRespawnS2c , player_position_look_s2c:: PlayerPositionLookFlags } ,
20
+ } ,
17
21
profile:: Property ,
18
22
} ,
19
23
} ;
@@ -32,97 +36,142 @@ impl MinecraftCommand for ClassCommand {
32
36
fn execute ( self , world : & World , caller : Entity ) {
33
37
let rank = self . rank ;
34
38
let team = self . team ;
35
- let msg = format ! ( "Setting rank to {rank:?}" ) ;
36
- let chat = agnostic:: chat ( msg) ;
37
39
38
40
world. get :: < & Compose > ( |compose| {
39
41
caller. entity_view ( world) . get :: < (
40
42
& NetworkStreamRef ,
41
43
& hyperion:: simulation:: Uuid ,
42
44
& mut PlayerInventory ,
43
- ) > ( |( stream, uuid, inventory) | {
44
- inventory. clear ( ) ;
45
-
46
- rank. apply_inventory ( team, inventory, world) ;
47
-
48
- let minecraft_id = caller. minecraft_id ( ) ;
49
- let mut bundle = DataBundle :: new ( compose) ;
50
-
51
- // Remove player info
52
- bundle
53
- . add_packet (
54
- & play:: PlayerRemoveS2c {
55
- uuids : Cow :: Borrowed ( & [ uuid. 0 ] ) ,
56
- } ,
57
- world,
58
- )
59
- . unwrap ( ) ;
60
-
61
- // Destroy player entity
62
- bundle
63
- . add_packet (
64
- & play:: EntitiesDestroyS2c {
65
- entity_ids : Cow :: Borrowed ( & [ VarInt ( minecraft_id) ] ) ,
66
- } ,
67
- world,
68
- )
69
- . unwrap ( ) ;
70
-
71
- let skin = rank. skin ( ) ;
72
- let property = Property {
73
- name : "textures" . to_string ( ) ,
74
- value : skin. textures . clone ( ) ,
75
- signature : Some ( skin. signature . clone ( ) ) ,
76
- } ;
77
-
78
- let property = & [ property] ;
79
-
80
- // Add player back with new skin
81
- bundle
82
- . add_packet (
83
- & PlayerListS2c {
84
- actions : PlayerListActions :: default ( ) . with_add_player ( true ) ,
85
- entries : Cow :: Borrowed ( & [ PlayerListEntry {
86
- player_uuid : uuid. 0 ,
87
- username : Cow :: Borrowed ( "Player" ) ,
88
- properties : Cow :: Borrowed ( property) ,
89
- chat_data : None ,
90
- listed : true ,
91
- ping : 20 ,
45
+ & Position ,
46
+ & Yaw ,
47
+ & Pitch ,
48
+ ) > (
49
+ |( stream, uuid, inventory, position, yaw, pitch) | {
50
+ inventory. clear ( ) ;
51
+
52
+ rank. apply_inventory ( team, inventory, world) ;
53
+
54
+ let minecraft_id = caller. minecraft_id ( ) ;
55
+ let mut bundle = DataBundle :: new ( compose) ;
56
+
57
+ let mut position_block = position. floor ( ) . as_ivec3 ( ) ;
58
+ position_block. y -= 1 ;
59
+
60
+ // Add bundle splitter so these are all received at once
61
+ bundle. add_packet ( & play:: BundleSplitterS2c , world) . unwrap ( ) ;
62
+
63
+ // Set respawn position to player's position
64
+ bundle
65
+ . add_packet (
66
+ & play:: PlayerSpawnPositionS2c {
67
+ position : BlockPos :: new (
68
+ position_block. x ,
69
+ position_block. y ,
70
+ position_block. z ,
71
+ ) ,
72
+ // todo: seems to not do anything; perhaps angle is different than yaw?
73
+ // regardless doesn't matter as we teleport to the correct position
74
+ // later anyway
75
+ angle : * * yaw,
76
+ } ,
77
+ world,
78
+ )
79
+ . unwrap ( ) ;
80
+
81
+ // Remove player info
82
+ bundle
83
+ . add_packet (
84
+ & play:: PlayerRemoveS2c {
85
+ uuids : Cow :: Borrowed ( & [ uuid. 0 ] ) ,
86
+ } ,
87
+ world,
88
+ )
89
+ . unwrap ( ) ;
90
+
91
+ // Destroy player entity
92
+ bundle
93
+ . add_packet (
94
+ & play:: EntitiesDestroyS2c {
95
+ entity_ids : Cow :: Borrowed ( & [ VarInt ( minecraft_id) ] ) ,
96
+ } ,
97
+ world,
98
+ )
99
+ . unwrap ( ) ;
100
+
101
+ let skin = rank. skin ( ) ;
102
+ let property = Property {
103
+ name : "textures" . to_string ( ) ,
104
+ value : skin. textures . clone ( ) ,
105
+ signature : Some ( skin. signature . clone ( ) ) ,
106
+ } ;
107
+
108
+ let property = & [ property] ;
109
+
110
+ // Add player back with new skin
111
+ bundle
112
+ . add_packet (
113
+ & PlayerListS2c {
114
+ actions : PlayerListActions :: default ( ) . with_add_player ( true ) ,
115
+ entries : Cow :: Borrowed ( & [ PlayerListEntry {
116
+ player_uuid : uuid. 0 ,
117
+ username : Cow :: Borrowed ( "Player" ) ,
118
+ properties : Cow :: Borrowed ( property) ,
119
+ chat_data : None ,
120
+ listed : true ,
121
+ ping : 20 ,
122
+ game_mode : GameMode :: Survival ,
123
+ display_name : None ,
124
+ } ] ) ,
125
+ } ,
126
+ world,
127
+ )
128
+ . unwrap ( ) ;
129
+
130
+ // Respawn player
131
+ bundle
132
+ . add_packet (
133
+ & PlayerRespawnS2c {
134
+ dimension_type_name : ident ! ( "minecraft:overworld" ) . into ( ) ,
135
+ dimension_name : ident ! ( "minecraft:overworld" ) . into ( ) ,
136
+ hashed_seed : 0 ,
92
137
game_mode : GameMode :: Survival ,
93
- display_name : None ,
94
- } ] ) ,
95
- } ,
96
- world,
97
- )
98
- . unwrap ( ) ;
99
-
100
- // Respawn player
101
- bundle
102
- . add_packet (
103
- & PlayerRespawnS2c {
104
- dimension_type_name : ident ! ( "minecraft:overworld" ) . into ( ) ,
105
- dimension_name : ident ! ( "minecraft:overworld" ) . into ( ) ,
106
- hashed_seed : 0 ,
107
- game_mode : GameMode :: Survival ,
108
- previous_game_mode : OptGameMode :: default ( ) ,
109
- is_debug : false ,
110
- is_flat : false ,
111
- copy_metadata : false ,
112
- last_death_location : None ,
113
- portal_cooldown : VarInt :: default ( ) ,
114
- } ,
115
- world,
116
- )
117
- . unwrap ( ) ;
118
-
119
- bundle. add_packet ( & chat, world) . unwrap ( ) ;
120
-
121
- let show_all = show_all ( minecraft_id) ;
122
- bundle. add_packet ( show_all. borrow_packet ( ) , world) . unwrap ( ) ;
123
-
124
- bundle. send ( world, * stream, SystemId ( 0 ) ) . unwrap ( ) ;
125
- } ) ;
138
+ previous_game_mode : OptGameMode :: default ( ) ,
139
+ is_debug : false ,
140
+ is_flat : false ,
141
+ copy_metadata : false ,
142
+ last_death_location : None ,
143
+ portal_cooldown : VarInt :: default ( ) ,
144
+ } ,
145
+ world,
146
+ )
147
+ . unwrap ( ) ;
148
+
149
+ // look and teleport to more accurate position than full-block respawn position
150
+ bundle
151
+ . add_packet (
152
+ & play:: PlayerPositionLookS2c {
153
+ position : position. as_dvec3 ( ) ,
154
+ yaw : * * yaw,
155
+ pitch : * * pitch,
156
+ flags : PlayerPositionLookFlags :: default ( ) ,
157
+ teleport_id : VarInt ( fastrand:: i32 ( ..) ) ,
158
+ } ,
159
+ world,
160
+ )
161
+ . unwrap ( ) ;
162
+
163
+ let msg = format ! ( "Setting rank to {rank:?} with yaw {yaw:?}" ) ;
164
+ let chat = agnostic:: chat ( msg) ;
165
+ bundle. add_packet ( & chat, world) . unwrap ( ) ;
166
+
167
+ let show_all = show_all ( minecraft_id) ;
168
+ bundle. add_packet ( show_all. borrow_packet ( ) , world) . unwrap ( ) ;
169
+
170
+ bundle. add_packet ( & play:: BundleSplitterS2c , world) . unwrap ( ) ;
171
+
172
+ bundle. send ( world, * stream, SystemId ( 0 ) ) . unwrap ( ) ;
173
+ } ,
174
+ ) ;
126
175
} ) ;
127
176
}
128
177
}
0 commit comments