geforkt von Mirrors/Paper
3e90a19183
Upstream has released updates that appear to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: 304e83eb PR-1002: Improve documentation and implementation of getMaxStackSize e8215ea2 SPIGOT-7638: Library loader does not seem to resolve every dependency 79c595c0 SPIGOT-7637: Bad logic in checking nullability of AttributeModifier slots CraftBukkit Changes: 91b1fc3f1 SPIGOT-7644: Fix ItemMeta#getAsString 4e77a81e1 SPIGOT-7615: PlayerLeashEntityEvent cancelled eats lead 996f660f3 Do not remove leash knot if leasing to an existing leash knot gets cancelled f70367d42 SPIGOT-7643: Fix inverted leash event cancelled usage and remove leash knot if no entity gets leashed 7ddb48294 SPIGOT-7640: Abnormal jumping height of wind charge 080c8711e SPIGOT-7639: Incoming plugin channels not working ad549847e Open a direct connection instead of pinging mojang server to check if it is reachable 38e2926c5 SPIGOT-7365: DamageCause blocked by shield should trigger invulnerableTime
107 Zeilen
6.3 KiB
Diff
107 Zeilen
6.3 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Aikar <aikar@aikar.co>
|
|
Date: Sun, 19 Apr 2020 00:05:46 -0400
|
|
Subject: [PATCH] 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
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
|
index 66936834a80ef6b645ab44f3439defcb90237bfa..406c78dcb97d954f16f05d379d4dbf74c61c8fd1 100644
|
|
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
|
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
|
@@ -1476,6 +1476,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
|
return;
|
|
}
|
|
// Paper end - ignore and warn about illegal addEntity calls instead of crashing server
|
|
+ if (entity instanceof ServerPlayer && ((ServerPlayer) entity).supressTrackerForLogin) return; // Paper - Fire PlayerJoinEvent when Player is actually ready; Delay adding to tracker until after list packets
|
|
if (!(entity instanceof EnderDragonPart)) {
|
|
EntityType<?> entitytypes = entity.getType();
|
|
int i = entitytypes.clientTrackingRange() * 16;
|
|
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
|
index 9f74168b0dd9392d2f4164fc7011e98623e28882..a8c9a9cea8d527f2bb4393c0539b3c8f3b25e06e 100644
|
|
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
|
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
|
@@ -284,6 +284,7 @@ public class ServerPlayer extends Player {
|
|
public double maxHealthCache;
|
|
public boolean joining = true;
|
|
public boolean sentListPacket = false;
|
|
+ public boolean supressTrackerForLogin = false; // Paper - Fire PlayerJoinEvent when Player is actually ready
|
|
public String kickLeaveMessage = null; // SPIGOT-3034: Forward leave message to PlayerQuitEvent
|
|
// CraftBukkit end
|
|
public boolean isRealPlayer; // Paper
|
|
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
|
index d2f94afe667627a14cff896b463c2b9b51bf6e29..a4db0bcefc92091ff26b146a2ce914c1d36a3c23 100644
|
|
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
|
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
|
@@ -297,6 +297,12 @@ public abstract class PlayerList {
|
|
this.playersByUUID.put(player.getUUID(), player);
|
|
// 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); // see commented out section below worldserver.addPlayerJoin(entityplayer);
|
|
+ this.mountSavedVehicle(player, worldserver1, optional);
|
|
+ // Paper end - Fire PlayerJoinEvent when Player is actually ready
|
|
// CraftBukkit start
|
|
CraftPlayer bukkitPlayer = player.getBukkitEntity();
|
|
|
|
@@ -335,6 +341,8 @@ public abstract class PlayerList {
|
|
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
|
|
@@ -356,7 +364,11 @@ public abstract class PlayerList {
|
|
|
|
playerconnection.send(new ClientboundUpdateMobEffectPacket(player.getId(), mobeffect, false));
|
|
}
|
|
-
|
|
+ // Paper start - Fire PlayerJoinEvent when Player is actually ready; move vehicle into method so it can be called above - short circuit around that code
|
|
+ this.onPlayerJoinFinish(player, worldserver1, s1);
|
|
+ }
|
|
+ private void mountSavedVehicle(ServerPlayer player, ServerLevel worldserver1, Optional<CompoundTag> optional) {
|
|
+ // Paper end - Fire PlayerJoinEvent when Player is actually ready
|
|
if (optional.isPresent() && ((CompoundTag) optional.get()).contains("RootVehicle", 10)) {
|
|
CompoundTag nbttagcompound = ((CompoundTag) optional.get()).getCompound("RootVehicle");
|
|
ServerLevel finalWorldServer = worldserver1; // CraftBukkit - decompile error
|
|
@@ -403,6 +415,10 @@ public abstract class PlayerList {
|
|
}
|
|
}
|
|
|
|
+ // Paper start - Fire PlayerJoinEvent when Player is actually ready
|
|
+ }
|
|
+ public void onPlayerJoinFinish(ServerPlayer player, ServerLevel worldserver1, String s1) {
|
|
+ // Paper end - Fire PlayerJoinEvent when Player is actually ready
|
|
player.initInventoryMenu();
|
|
// CraftBukkit - Moved from above, added world
|
|
// Paper start - Configurable player collision; Add to collideRule team if needed
|