Fire PlayerJoinEvent when Player is actually ready
For years, plugin developers have had to delay many things they do inside of the PlayerJoinEvent by 1 tick to make it actually work. This all boiled down to 1 reason why: The event fired before the player was fully ready and joined to the world! Additionally, if that player logged out on a vehicle, the event fired before the vehicle was even loaded, so that plugins had no access to the vehicle during this event either. This change finally fixes this issue, fully preparing the player into the world as a fully ready entity, vehicle included. There should be no plugins that break because of this change, but might improve consistency with other plugins instead. For example, if 2 plugins listens to this event, and the first one teleported the player in the event, then the 2nd plugin actually would be getting a valid player! This was very non deterministic. This change will ensure every plugin receives a deterministic result, and should no longer require 1 tick delays anymore. == AT == public net.minecraft.server.level.ChunkMap addEntity(Lnet/minecraft/world/entity/Entity;)V
This commit is contained in:
@@ -196,7 +196,7 @@
|
||||
playerconnection.teleport(player.getX(), player.getY(), player.getZ(), player.getYRot(), player.getXRot());
|
||||
ServerStatus serverping = this.server.getStatus();
|
||||
|
||||
@@ -222,17 +293,77 @@
|
||||
@@ -222,17 +293,85 @@
|
||||
player.sendServerStatus(serverping);
|
||||
}
|
||||
|
||||
@@ -206,8 +206,18 @@
|
||||
+ this.playersByName.put(player.getScoreboardName().toLowerCase(java.util.Locale.ROOT), player); // Spigot
|
||||
this.playersByUUID.put(player.getUUID(), player);
|
||||
- this.broadcastAll(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(player)));
|
||||
- this.sendLevelInfo(player, worldserver1);
|
||||
+ // this.broadcastAll(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(entityplayer))); // CraftBukkit - replaced with loop below
|
||||
+
|
||||
+ // Paper start - Fire PlayerJoinEvent when Player is actually ready; correctly register player BEFORE PlayerJoinEvent, so the entity is valid and doesn't require tick delay hacks
|
||||
+ player.supressTrackerForLogin = true;
|
||||
worldserver1.addNewPlayer(player);
|
||||
- this.server.getCustomBossEvents().onPlayerConnect(player);
|
||||
- this.sendActivePlayerEffects(player);
|
||||
+ this.server.getCustomBossEvents().onPlayerConnect(player); // see commented out section below worldserver.addPlayerJoin(entityplayer);
|
||||
player.loadAndSpawnEnderpearls(optional);
|
||||
player.loadAndSpawnParentVehicle(optional);
|
||||
+ // Paper end - Fire PlayerJoinEvent when Player is actually ready
|
||||
+ // CraftBukkit start
|
||||
+ CraftPlayer bukkitPlayer = player.getBukkitEntity();
|
||||
+
|
||||
@@ -246,13 +256,13 @@
|
||||
+ player.connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(entityplayer1)));
|
||||
+ }
|
||||
+ player.sentListPacket = true;
|
||||
+ player.supressTrackerForLogin = false; // Paper - Fire PlayerJoinEvent when Player is actually ready
|
||||
+ ((ServerLevel)player.level()).getChunkSource().chunkMap.addEntity(player); // Paper - Fire PlayerJoinEvent when Player is actually ready; track entity now
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
+ player.refreshEntityData(player); // CraftBukkit - BungeeCord#2321, send complete data to self on spawn
|
||||
+
|
||||
this.sendLevelInfo(player, worldserver1);
|
||||
- worldserver1.addNewPlayer(player);
|
||||
- this.server.getCustomBossEvents().onPlayerConnect(player);
|
||||
+ this.sendLevelInfo(player, worldserver1);
|
||||
+
|
||||
+ // CraftBukkit start - Only add if the player wasn't moved in the event
|
||||
+ if (player.level() == worldserver1 && !worldserver1.players().contains(player)) {
|
||||
@@ -262,9 +272,8 @@
|
||||
+
|
||||
+ worldserver1 = player.serverLevel(); // CraftBukkit - Update in case join event changed it
|
||||
+ // CraftBukkit end
|
||||
this.sendActivePlayerEffects(player);
|
||||
player.loadAndSpawnEnderpearls(optional);
|
||||
player.loadAndSpawnParentVehicle(optional);
|
||||
+ this.sendActivePlayerEffects(player);
|
||||
+ // Paper - move loading pearls / parent vehicle up
|
||||
player.initInventoryMenu();
|
||||
+ // CraftBukkit - Moved from above, added world
|
||||
+ // Paper start - Configurable player collision; Add to collideRule team if needed
|
||||
@@ -278,7 +287,7 @@
|
||||
}
|
||||
|
||||
public void updateEntireScoreboard(ServerScoreboard scoreboard, ServerPlayer player) {
|
||||
@@ -269,30 +400,31 @@
|
||||
@@ -269,30 +408,31 @@
|
||||
}
|
||||
|
||||
public void addWorldborderListener(ServerLevel world) {
|
||||
@@ -315,7 +324,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -319,14 +451,15 @@
|
||||
@@ -319,14 +459,15 @@
|
||||
}
|
||||
|
||||
protected void save(ServerPlayer player) {
|
||||
@@ -333,7 +342,7 @@
|
||||
|
||||
if (advancementdataplayer != null) {
|
||||
advancementdataplayer.save();
|
||||
@@ -334,95 +467,186 @@
|
||||
@@ -334,95 +475,186 @@
|
||||
|
||||
}
|
||||
|
||||
@@ -558,7 +567,7 @@
|
||||
|
||||
if (entityplayer1 != null) {
|
||||
set.add(entityplayer1);
|
||||
@@ -431,72 +655,160 @@
|
||||
@@ -431,72 +663,160 @@
|
||||
Iterator iterator1 = set.iterator();
|
||||
|
||||
while (iterator1.hasNext()) {
|
||||
@@ -740,7 +749,7 @@
|
||||
return entityplayer1;
|
||||
}
|
||||
|
||||
@@ -516,15 +828,32 @@
|
||||
@@ -516,15 +836,32 @@
|
||||
}
|
||||
|
||||
public void sendPlayerPermissionLevel(ServerPlayer player) {
|
||||
@@ -775,7 +784,7 @@
|
||||
this.sendAllPlayerInfoIn = 0;
|
||||
}
|
||||
|
||||
@@ -541,6 +870,25 @@
|
||||
@@ -541,6 +878,25 @@
|
||||
|
||||
}
|
||||
|
||||
@@ -801,7 +810,7 @@
|
||||
public void broadcastAll(Packet<?> packet, ResourceKey<Level> dimension) {
|
||||
Iterator iterator = this.players.iterator();
|
||||
|
||||
@@ -554,7 +902,7 @@
|
||||
@@ -554,7 +910,7 @@
|
||||
|
||||
}
|
||||
|
||||
@@ -810,7 +819,7 @@
|
||||
PlayerTeam scoreboardteam = source.getTeam();
|
||||
|
||||
if (scoreboardteam != null) {
|
||||
@@ -573,7 +921,7 @@
|
||||
@@ -573,7 +929,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -819,7 +828,7 @@
|
||||
PlayerTeam scoreboardteam = source.getTeam();
|
||||
|
||||
if (scoreboardteam == null) {
|
||||
@@ -619,7 +967,7 @@
|
||||
@@ -619,7 +975,7 @@
|
||||
}
|
||||
|
||||
public void deop(GameProfile profile) {
|
||||
@@ -828,7 +837,7 @@
|
||||
ServerPlayer entityplayer = this.getPlayer(profile.getId());
|
||||
|
||||
if (entityplayer != null) {
|
||||
@@ -643,36 +991,51 @@
|
||||
@@ -643,36 +999,51 @@
|
||||
player.connection.send(new ClientboundEntityEventPacket(player, b0));
|
||||
}
|
||||
|
||||
@@ -893,7 +902,7 @@
|
||||
if (entityplayer != player && entityplayer.level().dimension() == worldKey) {
|
||||
double d4 = x - entityplayer.getX();
|
||||
double d5 = y - entityplayer.getY();
|
||||
@@ -687,10 +1050,12 @@
|
||||
@@ -687,10 +1058,12 @@
|
||||
}
|
||||
|
||||
public void saveAll() {
|
||||
@@ -906,7 +915,7 @@
|
||||
}
|
||||
|
||||
public UserWhiteList getWhiteList() {
|
||||
@@ -712,15 +1077,19 @@
|
||||
@@ -712,15 +1085,19 @@
|
||||
public void reloadWhiteList() {}
|
||||
|
||||
public void sendLevelInfo(ServerPlayer player, ServerLevel world) {
|
||||
@@ -930,7 +939,7 @@
|
||||
}
|
||||
|
||||
player.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.LEVEL_CHUNKS_LOAD_START, 0.0F));
|
||||
@@ -729,8 +1098,16 @@
|
||||
@@ -729,8 +1106,16 @@
|
||||
|
||||
public void sendAllPlayerInfo(ServerPlayer player) {
|
||||
player.inventoryMenu.sendAllDataToRemote();
|
||||
@@ -948,7 +957,7 @@
|
||||
}
|
||||
|
||||
public int getPlayerCount() {
|
||||
@@ -746,6 +1123,7 @@
|
||||
@@ -746,6 +1131,7 @@
|
||||
}
|
||||
|
||||
public void setUsingWhiteList(boolean whitelistEnabled) {
|
||||
@@ -956,7 +965,7 @@
|
||||
this.doWhiteList = whitelistEnabled;
|
||||
}
|
||||
|
||||
@@ -786,12 +1164,36 @@
|
||||
@@ -786,11 +1172,35 @@
|
||||
}
|
||||
|
||||
public void removeAll() {
|
||||
@@ -972,30 +981,29 @@
|
||||
+ for (ServerPlayer player : this.players) {
|
||||
+ if (isRestarting) player.connection.disconnect(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(org.spigotmc.SpigotConfig.restartMessage)); else // Paper
|
||||
+ player.connection.disconnect(java.util.Objects.requireNonNullElseGet(this.server.server.shutdownMessage(), net.kyori.adventure.text.Component::empty)); // CraftBukkit - add custom shutdown message // Paper - Adventure
|
||||
}
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
|
||||
+
|
||||
+ // Paper start - Configurable player collision; Remove collideRule team if it exists
|
||||
+ if (this.collideRuleTeamName != null) {
|
||||
+ final net.minecraft.world.scores.Scoreboard scoreboard = this.getServer().getLevel(Level.OVERWORLD).getScoreboard();
|
||||
+ final PlayerTeam team = scoreboard.getPlayersTeam(this.collideRuleTeamName);
|
||||
+ if (team != null) scoreboard.removePlayerTeam(team);
|
||||
+ }
|
||||
}
|
||||
+ // Paper end - Configurable player collision
|
||||
}
|
||||
+ }
|
||||
|
||||
+ // CraftBukkit start
|
||||
+ public void broadcastMessage(Component[] iChatBaseComponents) {
|
||||
+ for (Component component : iChatBaseComponents) {
|
||||
+ this.broadcastSystemMessage(component, false);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
|
||||
public void broadcastSystemMessage(Component message, boolean overlay) {
|
||||
this.broadcastSystemMessage(message, (entityplayer) -> {
|
||||
return message;
|
||||
@@ -819,24 +1221,43 @@
|
||||
@@ -819,24 +1229,43 @@
|
||||
}
|
||||
|
||||
public void broadcastChatMessage(PlayerChatMessage message, ServerPlayer sender, ChatType.Bound params) {
|
||||
@@ -1042,7 +1050,7 @@
|
||||
}
|
||||
|
||||
if (flag1 && sender != null) {
|
||||
@@ -845,20 +1266,27 @@
|
||||
@@ -845,20 +1274,27 @@
|
||||
|
||||
}
|
||||
|
||||
@@ -1075,7 +1083,7 @@
|
||||
Path path = file2.toPath();
|
||||
|
||||
if (FileUtil.isPathNormalized(path) && FileUtil.isPathPortable(path) && path.startsWith(file.getPath()) && file2.isFile()) {
|
||||
@@ -867,7 +1295,7 @@
|
||||
@@ -867,7 +1303,7 @@
|
||||
}
|
||||
|
||||
serverstatisticmanager = new ServerStatsCounter(this.server, file1);
|
||||
@@ -1084,7 +1092,7 @@
|
||||
}
|
||||
|
||||
return serverstatisticmanager;
|
||||
@@ -875,13 +1303,13 @@
|
||||
@@ -875,13 +1311,13 @@
|
||||
|
||||
public PlayerAdvancements getPlayerAdvancements(ServerPlayer player) {
|
||||
UUID uuid = player.getUUID();
|
||||
@@ -1100,7 +1108,7 @@
|
||||
}
|
||||
|
||||
advancementdataplayer.setPlayer(player);
|
||||
@@ -932,15 +1360,28 @@
|
||||
@@ -932,15 +1368,28 @@
|
||||
}
|
||||
|
||||
public void reloadResources() {
|
||||
|
||||
Reference in New Issue
Block a user