Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add PlayerLoadedWorldEvent #11940

Merged
merged 9 commits into from
Jan 25, 2025
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package io.papermc.paper.event.player;

import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;

/**
* Called when a player is marked as loaded.
* <p>
* This either happens when the player notifies the server after loading the world (closing the downloading terrain screen)
* or when the player has not done so for 60 ticks after joining the server or respawning.
*/
@NullMarked
public class PlayerClientLoadedWorldEvent extends PlayerEvent {

private static final HandlerList HANDLER_LIST = new HandlerList();

private final boolean timeout;

@ApiStatus.Internal
public PlayerClientLoadedWorldEvent(final Player who, final boolean timeout) {
super(who);
this.timeout = timeout;
}

/**
* True if the event was triggered because the server has not been notified by the player
* for 60 ticks after the player joined the server or respawned.
*
* @return true if the event was triggered because of a timeout
*/
public boolean isTimeout() {
return timeout;
}

@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}

public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ index 3aad9ee86d6af392f4a98022cbc88bb53000e7be..27ef385a85b13ceb58e8d14984998310
}

@Override
@@ -1361,7 +1393,7 @@ public class ServerGamePacketListenerImpl
@@ -1368,7 +1400,7 @@ public class ServerGamePacketListenerImpl
}
}

Expand All @@ -97,15 +97,15 @@ index 3aad9ee86d6af392f4a98022cbc88bb53000e7be..27ef385a85b13ceb58e8d14984998310
d3 = d - this.lastGoodX; // Paper - diff on change, used for checking large move vectors above
d4 = d1 - this.lastGoodY; // Paper - diff on change, used for checking large move vectors above
d5 = d2 - this.lastGoodZ; // Paper - diff on change, used for checking large move vectors above
@@ -1400,6 +1432,7 @@ public class ServerGamePacketListenerImpl
@@ -1407,6 +1439,7 @@ public class ServerGamePacketListenerImpl
boolean flag1 = this.player.verticalCollisionBelow;
this.player.move(MoverType.PLAYER, new Vec3(d3, d4, d5));
this.player.onGround = packet.isOnGround(); // CraftBukkit - SPIGOT-5810, SPIGOT-5835, SPIGOT-6828: reset by this.player.move
+ boolean didCollide = toX != this.player.getX() || toY != this.player.getY() || toZ != this.player.getZ(); // Paper - needed here as the difference in Y can be reset - also note: this is only a guess at whether collisions took place, floating point errors can make this true when it shouldn't be...
// Paper start - prevent position desync
if (this.awaitingPositionFromClient != null) {
return; // ... thanks Mojang for letting move calls teleport across dimensions.
@@ -1432,7 +1465,17 @@ public class ServerGamePacketListenerImpl
@@ -1439,7 +1472,17 @@ public class ServerGamePacketListenerImpl
}

// Paper start - Add fail move event
Expand All @@ -124,7 +124,7 @@ index 3aad9ee86d6af392f4a98022cbc88bb53000e7be..27ef385a85b13ceb58e8d14984998310
if (teleportBack) {
io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.CLIPPED_INTO_BLOCK,
toX, toY, toZ, toYaw, toPitch, false);
@@ -1568,7 +1611,7 @@ public class ServerGamePacketListenerImpl
@@ -1575,7 +1618,7 @@ public class ServerGamePacketListenerImpl

private boolean updateAwaitingTeleport() {
if (this.awaitingPositionFromClient != null) {
Expand All @@ -133,7 +133,7 @@ index 3aad9ee86d6af392f4a98022cbc88bb53000e7be..27ef385a85b13ceb58e8d14984998310
this.awaitingTeleportTime = this.tickCount;
this.teleport(
this.awaitingPositionFromClient.x,
@@ -1587,6 +1630,33 @@ public class ServerGamePacketListenerImpl
@@ -1594,6 +1637,33 @@ public class ServerGamePacketListenerImpl
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -373,14 +373,27 @@
this.awaitingPositionFromClient.x,
this.awaitingPositionFromClient.y,
this.awaitingPositionFromClient.z,
@@ -495,6 +_,7 @@
@@ -495,12 +_,20 @@
this.lastGoodZ = this.awaitingPositionFromClient.z;
this.player.hasChangedDimension();
this.awaitingPositionFromClient = null;
+ this.player.serverLevel().getChunkSource().move(this.player); // CraftBukkit
}
}

@Override
public void handleAcceptPlayerLoad(ServerboundPlayerLoadedPacket packet) {
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
+ // Paper start - PlayerLoadedWorldEvent
+ if (this.player.hasClientLoaded()) {
+ return;
+ }
+ final io.papermc.paper.event.player.PlayerLoadedWorldEvent event = new io.papermc.paper.event.player.PlayerLoadedWorldEvent(this.player.getBukkitEntity(), false);
+ event.callEvent();
+ // Paper end - PlayerLoadedWorldEvent
this.player.setClientLoaded(true);
}

@@ -521,6 +_,7 @@
@Override
public void handleRecipeBookChangeSettingsPacket(ServerboundRecipeBookChangeSettingsPacket packet) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -674,3 +674,25 @@

for (int i = 0; i < this.inventory.getContainerSize(); i++) {
ItemStack item = this.inventory.getItem(i);
@@ -2089,12 +_,20 @@
}

public boolean hasClientLoaded() {
- return this.clientLoaded || this.clientLoadedTimeoutTimer <= 0;
+ return this.clientLoaded; // Paper - Add PlayerLoadedWorldEvent
}

public void tickClientLoadTimeout() {
if (!this.clientLoaded) {
this.clientLoadedTimeoutTimer--;
+ // Paper start - Add PlayerLoadedWorldEvent
+ if (this.clientLoadedTimeoutTimer <= 0) {
+ this.clientLoaded = true;
+
+ final io.papermc.paper.event.player.PlayerLoadedWorldEvent event = new io.papermc.paper.event.player.PlayerLoadedWorldEvent((org.bukkit.craftbukkit.entity.CraftPlayer) getBukkitEntity(), true);
+ event.callEvent();
+ }
+ // Paper end - Add PlayerLoadedWorldEvent
}
}

Loading