36
36
import org .cloudburstmc .protocol .bedrock .data .entity .EntityDataTypes ;
37
37
import org .cloudburstmc .protocol .bedrock .data .entity .EntityFlag ;
38
38
import org .cloudburstmc .protocol .bedrock .packet .MovePlayerPacket ;
39
+ import org .cloudburstmc .protocol .bedrock .packet .SetEntityMotionPacket ;
39
40
import org .cloudburstmc .protocol .bedrock .packet .UpdateAttributesPacket ;
40
41
import org .geysermc .geyser .entity .EntityDefinitions ;
41
42
import org .geysermc .geyser .entity .attribute .GeyserAttributeType ;
42
43
import org .geysermc .geyser .entity .type .BoatEntity ;
43
44
import org .geysermc .geyser .entity .type .Entity ;
44
45
import org .geysermc .geyser .inventory .GeyserItemStack ;
45
46
import org .geysermc .geyser .item .Items ;
46
- import org .geysermc .geyser .level .BedrockDimension ;
47
47
import org .geysermc .geyser .level .block .Blocks ;
48
48
import org .geysermc .geyser .level .block .property .Properties ;
49
49
import org .geysermc .geyser .level .block .type .BlockState ;
@@ -117,15 +117,6 @@ public class SessionPlayerEntity extends PlayerEntity {
117
117
@ Getter @ Setter
118
118
private Vector2f bedrockInteractRotation = Vector2f .ZERO ;
119
119
120
- /**
121
- * Determines if our position is currently out-of-sync with the Java server
122
- * due to our workaround for the void floor
123
- * <p>
124
- * Must be reset when dying, switching worlds, or being teleported out of the void
125
- */
126
- @ Getter @ Setter
127
- private boolean voidPositionDesynched ;
128
-
129
120
public SessionPlayerEntity (GeyserSession session ) {
130
121
super (session , -1 , 1 , null , Vector3f .ZERO , Vector3f .ZERO , 0 , 0 , 0 , null , null );
131
122
@@ -152,29 +143,18 @@ public void spawnEntity() {
152
143
153
144
@ Override
154
145
public void moveRelative (double relX , double relY , double relZ , float yaw , float pitch , float headYaw , boolean isOnGround ) {
155
- if (voidPositionDesynched ) {
156
- if (!isBelowVoidFloor ()) {
157
- voidPositionDesynched = false ; // No need to fix our offset; we've been moved
158
- }
159
- }
160
146
super .moveRelative (relX , relY , relZ , yaw , pitch , headYaw , isOnGround );
161
147
session .getCollisionManager ().updatePlayerBoundingBox (this .position .down (definition .offset ()));
162
148
}
163
149
164
- @ Override
165
- public void moveAbsolute (Vector3f position , float yaw , float pitch , float headYaw , boolean isOnGround , boolean teleported ) {
166
- if (voidPositionDesynched ) {
167
- if (!isBelowVoidFloor ()) {
168
- voidPositionDesynched = false ; // No need to fix our offset; we've been moved
169
- }
170
- }
171
- super .moveAbsolute (position , yaw , pitch , headYaw , isOnGround , teleported );
172
- }
173
-
174
150
@ Override
175
151
public void setPosition (Vector3f position ) {
176
152
if (valid ) { // Don't update during session init
177
153
session .getCollisionManager ().updatePlayerBoundingBox (position );
154
+
155
+ if (session .isNoClip () && position .getY () >= session .getBedrockDimension ().minY () - 5 ) {
156
+ session .setNoClip (false );
157
+ }
178
158
}
179
159
this .position = position .add (0 , definition .offset (), 0 );
180
160
}
@@ -200,6 +180,12 @@ public void updateOwnRotation(float yaw, float pitch, float headYaw) {
200
180
movePlayerPacket .setTeleportationCause (MovePlayerPacket .TeleportationCause .BEHAVIOR );
201
181
202
182
session .sendUpstreamPacket (movePlayerPacket );
183
+
184
+ // We're just setting rotation, player shouldn't lose motion, send motion packet to account for that.
185
+ SetEntityMotionPacket entityMotionPacket = new SetEntityMotionPacket ();
186
+ entityMotionPacket .setRuntimeEntityId (geyserId );
187
+ entityMotionPacket .setMotion (motion );
188
+ session .sendUpstreamPacket (entityMotionPacket );
203
189
}
204
190
205
191
/**
@@ -211,6 +197,11 @@ public void updateOwnRotation(float yaw, float pitch, float headYaw) {
211
197
*/
212
198
public void setPositionManual (Vector3f position ) {
213
199
this .position = position ;
200
+
201
+ // Player is "above" the void so they're not supposed to no clip.
202
+ if (session .isNoClip () && position .getY () - EntityDefinitions .PLAYER .offset () >= session .getBedrockDimension ().minY () - 5 ) {
203
+ session .setNoClip (false );
204
+ }
214
205
}
215
206
216
207
/**
@@ -360,9 +351,6 @@ public void setLastDeathPosition(@Nullable GlobalPos pos) {
360
351
} else {
361
352
dirtyMetadata .put (EntityDataTypes .PLAYER_HAS_DIED , false );
362
353
}
363
-
364
- // We're either respawning or switching worlds, either way, we are no longer desynched
365
- this .setVoidPositionDesynched (false );
366
354
}
367
355
368
356
@ Override
@@ -448,51 +436,7 @@ public void setVehicle(Entity entity) {
448
436
449
437
super .setVehicle (entity );
450
438
}
451
-
452
- private boolean isBelowVoidFloor () {
453
- return position .getY () < voidFloorPosition ();
454
- }
455
-
456
- public int voidFloorPosition () {
457
- // The void floor is offset about 40 blocks below the bottom of the world
458
- BedrockDimension bedrockDimension = session .getBedrockDimension ();
459
- return bedrockDimension .minY () - 40 ;
460
- }
461
-
462
- /**
463
- * This method handles teleporting the player below or above the Bedrock void floor.
464
- * The Java server should never see this desync as we adjust the position that we send to it
465
- *
466
- * @param up in which direction to teleport - true to resync our position, or false to be
467
- * teleported below the void floor.
468
- */
469
- public void teleportVoidFloorFix (boolean up ) {
470
- // Safety to avoid double teleports
471
- if ((voidPositionDesynched && !up ) || (!voidPositionDesynched && up )) {
472
- return ;
473
- }
474
-
475
- // Work around there being a floor at the bottom of the world and teleport the player below it
476
- // Moving from below to above the void floor works fine
477
- Vector3f newPosition = this .getPosition ();
478
- if (up ) {
479
- newPosition = newPosition .up (4f );
480
- voidPositionDesynched = false ;
481
- } else {
482
- newPosition = newPosition .down (4f );
483
- voidPositionDesynched = true ;
484
- }
485
-
486
- this .setPositionManual (newPosition );
487
- MovePlayerPacket movePlayerPacket = new MovePlayerPacket ();
488
- movePlayerPacket .setRuntimeEntityId (geyserId );
489
- movePlayerPacket .setPosition (newPosition );
490
- movePlayerPacket .setRotation (getBedrockRotation ());
491
- movePlayerPacket .setMode (MovePlayerPacket .Mode .TELEPORT );
492
- movePlayerPacket .setTeleportationCause (MovePlayerPacket .TeleportationCause .BEHAVIOR );
493
- session .sendUpstreamPacketImmediately (movePlayerPacket );
494
- }
495
-
439
+
496
440
/**
497
441
* Used to calculate player jumping velocity for ground status calculation.
498
442
*/
0 commit comments