Move player to spawn point if spawn in unloaded world

If the playerdata contains an invalid world (missing, unloaded, invalid,
etc.), spawn the player at the spawn point of the main world.

Co-authored-by: Wyatt Childers <wchilders@nearce.com>
Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
This commit is contained in:
2277
2020-03-31 10:33:55 +01:00
parent d7f24e6729
commit dd3e099c9c
2 changed files with 154 additions and 127 deletions

View File

@@ -90,7 +90,7 @@
this.server = server; this.server = server;
this.registries = registryManager; this.registries = registryManager;
this.maxPlayers = maxPlayers; this.maxPlayers = maxPlayers;
@@ -148,27 +181,38 @@ @@ -148,44 +181,111 @@
} }
public void placeNewPlayer(Connection connection, ServerPlayer player, CommonListenerCookie clientData) { public void placeNewPlayer(Connection connection, ServerPlayer player, CommonListenerCookie clientData) {
@@ -112,7 +112,10 @@
} }
- optional = this.load(player); - optional = this.load(player);
- ResourceKey<Level> resourcekey = (ResourceKey) optional.flatMap((nbttagcompound) -> {
- DataResult dataresult = DimensionType.parseLegacy(new Dynamic(NbtOps.INSTANCE, nbttagcompound.get("Dimension")));
+ Optional<CompoundTag> optional = this.load(player); // CraftBukkit - decompile error + Optional<CompoundTag> optional = this.load(player); // CraftBukkit - decompile error
+ ResourceKey<Level> resourcekey = null; // Paper
+ // CraftBukkit start - Better rename detection + // CraftBukkit start - Better rename detection
+ if (optional.isPresent()) { + if (optional.isPresent()) {
+ CompoundTag nbttagcompound = optional.get(); + CompoundTag nbttagcompound = optional.get();
@@ -122,25 +125,60 @@
+ } + }
+ } + }
+ // CraftBukkit end + // CraftBukkit end
ResourceKey<Level> resourcekey = (ResourceKey) optional.flatMap((nbttagcompound) -> { + // Paper start - move logic in Entity to here, to use bukkit supplied world UUID & reset to main world spawn if no valid world is found
- DataResult dataresult = DimensionType.parseLegacy(new Dynamic(NbtOps.INSTANCE, nbttagcompound.get("Dimension"))); + boolean[] invalidPlayerWorld = {false};
+ bukkitData: if (optional.isPresent()) {
+ // The main way for bukkit worlds to store the world is the world UUID despite mojang adding custom worlds
+ final org.bukkit.World bWorld;
+ if (optional.get().contains("WorldUUIDMost") && optional.get().contains("WorldUUIDLeast")) {
+ bWorld = org.bukkit.Bukkit.getServer().getWorld(new UUID(optional.get().getLong("WorldUUIDMost"), optional.get().getLong("WorldUUIDLeast")));
+ } else if (optional.get().contains("world", net.minecraft.nbt.Tag.TAG_STRING)) { // Paper - legacy bukkit world name
+ bWorld = org.bukkit.Bukkit.getServer().getWorld(optional.get().getString("world"));
+ } else {
+ break bukkitData; // if neither of the bukkit data points exist, proceed to the vanilla migration section
+ }
+ if (bWorld != null) {
+ resourcekey = ((CraftWorld) bWorld).getHandle().dimension();
+ } else {
+ resourcekey = Level.OVERWORLD;
+ invalidPlayerWorld[0] = true;
+ }
+ }
+ if (resourcekey == null) { // only run the vanilla logic if we haven't found a world from the bukkit data
+ // Below is the vanilla way of getting the dimension, this is for migration from vanilla servers
+ resourcekey = optional.flatMap((nbttagcompound) -> {
+ // Paper end
+ DataResult<ResourceKey<Level>> dataresult = DimensionType.parseLegacy(new Dynamic(NbtOps.INSTANCE, nbttagcompound.get("Dimension"))); // CraftBukkit - decompile error + DataResult<ResourceKey<Level>> dataresult = DimensionType.parseLegacy(new Dynamic(NbtOps.INSTANCE, nbttagcompound.get("Dimension"))); // CraftBukkit - decompile error
Logger logger = PlayerList.LOGGER; Logger logger = PlayerList.LOGGER;
Objects.requireNonNull(logger); Objects.requireNonNull(logger);
return dataresult.resultOrPartial(logger::error); - return dataresult.resultOrPartial(logger::error);
- }).orElse(Level.OVERWORLD); - }).orElse(Level.OVERWORLD);
+ }).orElse(player.serverLevel().dimension()); // CraftBukkit - SPIGOT-7507: If no dimension, fall back to existing dimension loaded from "WorldUUID", which in turn defaults to World.OVERWORLD + // Paper start - reset to main world spawn if no valid world is found
+ final Optional<ResourceKey<Level>> result = dataresult.resultOrPartial(logger::error);
+ invalidPlayerWorld[0] = result.isEmpty();
+ return result;
+ }).orElse(Level.OVERWORLD); // Paper - revert to vanilla default main world, this isn't an "invalid world" since no player data existed
+ }
+ // Paper end
ServerLevel worldserver = this.server.getLevel(resourcekey); ServerLevel worldserver = this.server.getLevel(resourcekey);
ServerLevel worldserver1; ServerLevel worldserver1;
@@ -179,13 +223,36 @@ if (worldserver == null) {
PlayerList.LOGGER.warn("Unknown respawn dimension {}, defaulting to overworld", resourcekey);
worldserver1 = this.server.overworld();
+ invalidPlayerWorld[0] = true; // Paper - reset to main world if no world with parsed value is found
} else {
worldserver1 = worldserver; worldserver1 = worldserver;
} }
+ // Paper start - Entity#getEntitySpawnReason + // Paper start - Entity#getEntitySpawnReason
+ if (optional.isEmpty()) { + if (optional.isEmpty()) {
+ player.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT; // set Player SpawnReason to DEFAULT on first login + player.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT; // set Player SpawnReason to DEFAULT on first login
+ // Paper start - reset to main world spawn if first spawn or invalid world
+ }
+ if (optional.isEmpty() || invalidPlayerWorld[0]) {
+ // Paper end - reset to main world spawn if first spawn or invalid world
+ player.moveTo(player.adjustSpawnLocation(worldserver1, worldserver1.getSharedSpawnPos()).getBottomCenter(), 0.0F, 0.0F); + player.moveTo(player.adjustSpawnLocation(worldserver1, worldserver1.getSharedSpawnPos()).getBottomCenter(), 0.0F, 0.0F);
+ } + }
+ // Paper end - Entity#getEntitySpawnReason + // Paper end - Entity#getEntitySpawnReason
@@ -173,7 +211,7 @@
ServerGamePacketListenerImpl playerconnection = new ServerGamePacketListenerImpl(this.server, connection, player, clientData); ServerGamePacketListenerImpl playerconnection = new ServerGamePacketListenerImpl(this.server, connection, player, clientData);
connection.setupInboundProtocol(GameProtocols.SERVERBOUND_TEMPLATE.bind(RegistryFriendlyByteBuf.decorator(this.server.registryAccess())), playerconnection); connection.setupInboundProtocol(GameProtocols.SERVERBOUND_TEMPLATE.bind(RegistryFriendlyByteBuf.decorator(this.server.registryAccess())), playerconnection);
@@ -194,7 +261,9 @@ @@ -194,7 +294,9 @@
boolean flag1 = gamerules.getBoolean(GameRules.RULE_REDUCEDDEBUGINFO); boolean flag1 = gamerules.getBoolean(GameRules.RULE_REDUCEDDEBUGINFO);
boolean flag2 = gamerules.getBoolean(GameRules.RULE_LIMITED_CRAFTING); boolean flag2 = gamerules.getBoolean(GameRules.RULE_LIMITED_CRAFTING);
@@ -184,7 +222,7 @@
playerconnection.send(new ClientboundChangeDifficultyPacket(worlddata.getDifficulty(), worlddata.isDifficultyLocked())); playerconnection.send(new ClientboundChangeDifficultyPacket(worlddata.getDifficulty(), worlddata.isDifficultyLocked()));
playerconnection.send(new ClientboundPlayerAbilitiesPacket(player.getAbilities())); playerconnection.send(new ClientboundPlayerAbilitiesPacket(player.getAbilities()));
playerconnection.send(new ClientboundSetHeldSlotPacket(player.getInventory().selected)); playerconnection.send(new ClientboundSetHeldSlotPacket(player.getInventory().selected));
@@ -213,8 +282,10 @@ @@ -213,8 +315,10 @@
} else { } else {
ichatmutablecomponent = Component.translatable("multiplayer.player.joined.renamed", player.getDisplayName(), s); ichatmutablecomponent = Component.translatable("multiplayer.player.joined.renamed", player.getDisplayName(), s);
} }
@@ -196,7 +234,7 @@
playerconnection.teleport(player.getX(), player.getY(), player.getZ(), player.getYRot(), player.getXRot()); playerconnection.teleport(player.getX(), player.getY(), player.getZ(), player.getYRot(), player.getXRot());
ServerStatus serverping = this.server.getStatus(); ServerStatus serverping = this.server.getStatus();
@@ -222,17 +293,85 @@ @@ -222,17 +326,85 @@
player.sendServerStatus(serverping); player.sendServerStatus(serverping);
} }
@@ -287,7 +325,7 @@
} }
public void updateEntireScoreboard(ServerScoreboard scoreboard, ServerPlayer player) { public void updateEntireScoreboard(ServerScoreboard scoreboard, ServerPlayer player) {
@@ -269,30 +408,31 @@ @@ -269,30 +441,31 @@
} }
public void addWorldborderListener(ServerLevel world) { public void addWorldborderListener(ServerLevel world) {
@@ -324,7 +362,7 @@
} }
@Override @Override
@@ -319,14 +459,15 @@ @@ -319,14 +492,15 @@
} }
protected void save(ServerPlayer player) { protected void save(ServerPlayer player) {
@@ -342,7 +380,7 @@
if (advancementdataplayer != null) { if (advancementdataplayer != null) {
advancementdataplayer.save(); advancementdataplayer.save();
@@ -334,95 +475,186 @@ @@ -334,95 +508,186 @@
} }
@@ -525,13 +563,13 @@
+ if (this.players.size() >= this.maxPlayers && !this.canBypassPlayerLimit(gameprofile)) { + if (this.players.size() >= this.maxPlayers && !this.canBypassPlayerLimit(gameprofile)) {
+ event.disallow(PlayerLoginEvent.Result.KICK_FULL, net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(org.spigotmc.SpigotConfig.serverFullMessage)); // Spigot // Paper - Adventure + event.disallow(PlayerLoginEvent.Result.KICK_FULL, net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(org.spigotmc.SpigotConfig.serverFullMessage)); // Spigot // Paper - Adventure
+ } + }
} + }
+ +
+ this.cserver.getPluginManager().callEvent(event); + this.cserver.getPluginManager().callEvent(event);
+ if (event.getResult() != PlayerLoginEvent.Result.ALLOWED) { + if (event.getResult() != PlayerLoginEvent.Result.ALLOWED) {
+ loginlistener.disconnect(io.papermc.paper.adventure.PaperAdventure.asVanilla(event.kickMessage())); // Paper - Adventure + loginlistener.disconnect(io.papermc.paper.adventure.PaperAdventure.asVanilla(event.kickMessage())); // Paper - Adventure
+ return null; + return null;
+ } }
+ return entity; + return entity;
} }
@@ -567,7 +605,7 @@
if (entityplayer1 != null) { if (entityplayer1 != null) {
set.add(entityplayer1); set.add(entityplayer1);
@@ -431,72 +663,160 @@ @@ -431,72 +696,160 @@
Iterator iterator1 = set.iterator(); Iterator iterator1 = set.iterator();
while (iterator1.hasNext()) { while (iterator1.hasNext()) {
@@ -749,7 +787,7 @@
return entityplayer1; return entityplayer1;
} }
@@ -516,15 +836,32 @@ @@ -516,15 +869,32 @@
} }
public void sendPlayerPermissionLevel(ServerPlayer player) { public void sendPlayerPermissionLevel(ServerPlayer player) {
@@ -784,10 +822,14 @@
this.sendAllPlayerInfoIn = 0; this.sendAllPlayerInfoIn = 0;
} }
@@ -541,6 +878,25 @@ @@ -537,9 +907,28 @@
ServerPlayer entityplayer = (ServerPlayer) iterator.next();
}
entityplayer.connection.send(packet);
+ }
+
+ }
+
+ // CraftBukkit start - add a world/entity limited version + // CraftBukkit start - add a world/entity limited version
+ public void broadcastAll(Packet packet, net.minecraft.world.entity.player.Player entityhuman) { + public void broadcastAll(Packet packet, net.minecraft.world.entity.player.Player entityhuman) {
+ for (int i = 0; i < this.players.size(); ++i) { + for (int i = 0; i < this.players.size(); ++i) {
@@ -802,15 +844,14 @@
+ public void broadcastAll(Packet packet, Level world) { + public void broadcastAll(Packet packet, Level world) {
+ for (int i = 0; i < world.players().size(); ++i) { + for (int i = 0; i < world.players().size(); ++i) {
+ ((ServerPlayer) world.players().get(i)).connection.send(packet); + ((ServerPlayer) world.players().get(i)).connection.send(packet);
+ } }
+
+ } }
+ // CraftBukkit end + // CraftBukkit end
+
public void broadcastAll(Packet<?> packet, ResourceKey<Level> dimension) { public void broadcastAll(Packet<?> packet, ResourceKey<Level> dimension) {
Iterator iterator = this.players.iterator(); Iterator iterator = this.players.iterator();
@@ -554,7 +943,7 @@
@@ -554,7 +910,7 @@
} }
@@ -819,7 +860,7 @@
PlayerTeam scoreboardteam = source.getTeam(); PlayerTeam scoreboardteam = source.getTeam();
if (scoreboardteam != null) { if (scoreboardteam != null) {
@@ -573,7 +929,7 @@ @@ -573,7 +962,7 @@
} }
} }
@@ -828,7 +869,7 @@
PlayerTeam scoreboardteam = source.getTeam(); PlayerTeam scoreboardteam = source.getTeam();
if (scoreboardteam == null) { if (scoreboardteam == null) {
@@ -619,7 +975,7 @@ @@ -619,7 +1008,7 @@
} }
public void deop(GameProfile profile) { public void deop(GameProfile profile) {
@@ -837,7 +878,7 @@
ServerPlayer entityplayer = this.getPlayer(profile.getId()); ServerPlayer entityplayer = this.getPlayer(profile.getId());
if (entityplayer != null) { if (entityplayer != null) {
@@ -643,36 +999,51 @@ @@ -643,35 +1032,50 @@
player.connection.send(new ClientboundEntityEventPacket(player, b0)); player.connection.send(new ClientboundEntityEventPacket(player, b0));
} }
@@ -892,17 +933,16 @@
+ public void broadcast(@Nullable net.minecraft.world.entity.player.Player player, double x, double y, double z, double distance, ResourceKey<Level> worldKey, Packet<?> packet) { + public void broadcast(@Nullable net.minecraft.world.entity.player.Player player, double x, double y, double z, double distance, ResourceKey<Level> worldKey, Packet<?> packet) {
for (int i = 0; i < this.players.size(); ++i) { for (int i = 0; i < this.players.size(); ++i) {
ServerPlayer entityplayer = (ServerPlayer) this.players.get(i); ServerPlayer entityplayer = (ServerPlayer) this.players.get(i);
+
+ // CraftBukkit start - Test if player receiving packet can see the source of the packet + // CraftBukkit start - Test if player receiving packet can see the source of the packet
+ if (player != null && !entityplayer.getBukkitEntity().canSee(player.getBukkitEntity())) { + if (player != null && !entityplayer.getBukkitEntity().canSee(player.getBukkitEntity())) {
+ continue; + continue;
+ } + }
+ // CraftBukkit end + // CraftBukkit end
+
if (entityplayer != player && entityplayer.level().dimension() == worldKey) { if (entityplayer != player && entityplayer.level().dimension() == worldKey) {
double d4 = x - entityplayer.getX(); double d4 = x - entityplayer.getX();
double d5 = y - entityplayer.getY(); @@ -687,10 +1091,12 @@
@@ -687,10 +1058,12 @@
} }
public void saveAll() { public void saveAll() {
@@ -915,7 +955,7 @@
} }
public UserWhiteList getWhiteList() { public UserWhiteList getWhiteList() {
@@ -712,15 +1085,19 @@ @@ -712,15 +1118,19 @@
public void reloadWhiteList() {} public void reloadWhiteList() {}
public void sendLevelInfo(ServerPlayer player, ServerLevel world) { public void sendLevelInfo(ServerPlayer player, ServerLevel world) {
@@ -939,7 +979,7 @@
} }
player.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.LEVEL_CHUNKS_LOAD_START, 0.0F)); player.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.LEVEL_CHUNKS_LOAD_START, 0.0F));
@@ -729,8 +1106,16 @@ @@ -729,8 +1139,16 @@
public void sendAllPlayerInfo(ServerPlayer player) { public void sendAllPlayerInfo(ServerPlayer player) {
player.inventoryMenu.sendAllDataToRemote(); player.inventoryMenu.sendAllDataToRemote();
@@ -957,7 +997,7 @@
} }
public int getPlayerCount() { public int getPlayerCount() {
@@ -746,6 +1131,7 @@ @@ -746,6 +1164,7 @@
} }
public void setUsingWhiteList(boolean whitelistEnabled) { public void setUsingWhiteList(boolean whitelistEnabled) {
@@ -965,7 +1005,7 @@
this.doWhiteList = whitelistEnabled; this.doWhiteList = whitelistEnabled;
} }
@@ -786,11 +1172,35 @@ @@ -786,12 +1205,36 @@
} }
public void removeAll() { public void removeAll() {
@@ -981,29 +1021,30 @@
+ for (ServerPlayer player : this.players) { + 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 + 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 + 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 + // CraftBukkit end
+
+ // Paper start - Configurable player collision; Remove collideRule team if it exists + // Paper start - Configurable player collision; Remove collideRule team if it exists
+ if (this.collideRuleTeamName != null) { + if (this.collideRuleTeamName != null) {
+ final net.minecraft.world.scores.Scoreboard scoreboard = this.getServer().getLevel(Level.OVERWORLD).getScoreboard(); + final net.minecraft.world.scores.Scoreboard scoreboard = this.getServer().getLevel(Level.OVERWORLD).getScoreboard();
+ final PlayerTeam team = scoreboard.getPlayersTeam(this.collideRuleTeamName); + final PlayerTeam team = scoreboard.getPlayersTeam(this.collideRuleTeamName);
+ if (team != null) scoreboard.removePlayerTeam(team); + if (team != null) scoreboard.removePlayerTeam(team);
}
+ // Paper end - Configurable player collision
+ } + }
+ // Paper end - Configurable player collision
}
+ // CraftBukkit start + // CraftBukkit start
+ public void broadcastMessage(Component[] iChatBaseComponents) { + public void broadcastMessage(Component[] iChatBaseComponents) {
+ for (Component component : iChatBaseComponents) { + for (Component component : iChatBaseComponents) {
+ this.broadcastSystemMessage(component, false); + this.broadcastSystemMessage(component, false);
+ } + }
} + }
+ // CraftBukkit end + // CraftBukkit end
+
public void broadcastSystemMessage(Component message, boolean overlay) { public void broadcastSystemMessage(Component message, boolean overlay) {
this.broadcastSystemMessage(message, (entityplayer) -> { this.broadcastSystemMessage(message, (entityplayer) -> {
@@ -819,24 +1229,43 @@ return message;
@@ -819,24 +1262,43 @@
} }
public void broadcastChatMessage(PlayerChatMessage message, ServerPlayer sender, ChatType.Bound params) { public void broadcastChatMessage(PlayerChatMessage message, ServerPlayer sender, ChatType.Bound params) {
@@ -1050,7 +1091,7 @@
} }
if (flag1 && sender != null) { if (flag1 && sender != null) {
@@ -845,20 +1274,27 @@ @@ -845,20 +1307,27 @@
} }
@@ -1083,7 +1124,7 @@
Path path = file2.toPath(); Path path = file2.toPath();
if (FileUtil.isPathNormalized(path) && FileUtil.isPathPortable(path) && path.startsWith(file.getPath()) && file2.isFile()) { if (FileUtil.isPathNormalized(path) && FileUtil.isPathPortable(path) && path.startsWith(file.getPath()) && file2.isFile()) {
@@ -867,7 +1303,7 @@ @@ -867,7 +1336,7 @@
} }
serverstatisticmanager = new ServerStatsCounter(this.server, file1); serverstatisticmanager = new ServerStatsCounter(this.server, file1);
@@ -1092,7 +1133,7 @@
} }
return serverstatisticmanager; return serverstatisticmanager;
@@ -875,13 +1311,13 @@ @@ -875,13 +1344,13 @@
public PlayerAdvancements getPlayerAdvancements(ServerPlayer player) { public PlayerAdvancements getPlayerAdvancements(ServerPlayer player) {
UUID uuid = player.getUUID(); UUID uuid = player.getUUID();
@@ -1108,7 +1149,7 @@
} }
advancementdataplayer.setPlayer(player); advancementdataplayer.setPlayer(player);
@@ -932,15 +1368,28 @@ @@ -932,15 +1401,28 @@
} }
public void reloadResources() { public void reloadResources() {

View File

@@ -61,7 +61,7 @@
+// CraftBukkit end +// CraftBukkit end
public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess, ScoreHolder { public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess, ScoreHolder {
+
+ // CraftBukkit start + // CraftBukkit start
+ private static final int CURRENT_LEVEL = 2; + private static final int CURRENT_LEVEL = 2;
+ static boolean isLevelAtLeast(CompoundTag tag, int level) { + static boolean isLevelAtLeast(CompoundTag tag, int level) {
@@ -141,7 +141,7 @@
+ } + }
+ // Paper end - Share random for entities to make them more random + // Paper end - Share random for entities to make them more random
+ public org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason; // Paper - Entity#getEntitySpawnReason + public org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason; // Paper - Entity#getEntitySpawnReason
+
+ private CraftEntity bukkitEntity; + private CraftEntity bukkitEntity;
+ +
+ public CraftEntity getBukkitEntity() { + public CraftEntity getBukkitEntity() {
@@ -202,7 +202,7 @@
+ private org.bukkit.util.Vector origin; + private org.bukkit.util.Vector origin;
+ @javax.annotation.Nullable + @javax.annotation.Nullable
+ private UUID originWorld; + private UUID originWorld;
+
+ public void setOrigin(@javax.annotation.Nonnull Location location) { + public void setOrigin(@javax.annotation.Nonnull Location location) {
+ this.origin = location.toVector(); + this.origin = location.toVector();
+ this.originWorld = location.getWorld().getUID(); + this.originWorld = location.getWorld().getUID();
@@ -221,7 +221,7 @@
+ public float getBukkitYaw() { + public float getBukkitYaw() {
+ return this.yRot; + return this.yRot;
+ } + }
+
+ public boolean isChunkLoaded() { + public boolean isChunkLoaded() {
+ return this.level.hasChunk((int) Math.floor(this.getX()) >> 4, (int) Math.floor(this.getZ()) >> 4); + return this.level.hasChunk((int) Math.floor(this.getX()) >> 4, (int) Math.floor(this.getZ()) >> 4);
+ } + }
@@ -473,15 +473,15 @@
} }
} }
@@ -587,7 +873,23 @@ @@ -587,9 +873,25 @@
} }
public final void igniteForSeconds(float seconds) { public final void igniteForSeconds(float seconds) {
- this.igniteForTicks(Mth.floor(seconds * 20.0F)); - this.igniteForTicks(Mth.floor(seconds * 20.0F));
+ // CraftBukkit start + // CraftBukkit start
+ this.igniteForSeconds(seconds, true); + this.igniteForSeconds(seconds, true);
+ } }
+
+ public final void igniteForSeconds(float f, boolean callEvent) { + public final void igniteForSeconds(float f, boolean callEvent) {
+ if (callEvent) { + if (callEvent) {
+ EntityCombustEvent event = new EntityCombustEvent(this.getBukkitEntity(), f); + EntityCombustEvent event = new EntityCombustEvent(this.getBukkitEntity(), f);
@@ -495,9 +495,11 @@
+ } + }
+ // CraftBukkit end + // CraftBukkit end
+ this.igniteForTicks(Mth.floor(f * 20.0F)); + this.igniteForTicks(Mth.floor(f * 20.0F));
} + }
+
public void igniteForTicks(int ticks) { public void igniteForTicks(int ticks) {
if (this.remainingFireTicks < ticks) {
this.setRemainingFireTicks(ticks);
@@ -610,7 +912,7 @@ @@ -610,7 +912,7 @@
} }
@@ -536,15 +538,17 @@
if (!this.level().isClientSide() || this.isControlledByLocalInstance()) { if (!this.level().isClientSide() || this.isControlledByLocalInstance()) {
Entity.MovementEmission entity_movementemission = this.getMovementEmission(); Entity.MovementEmission entity_movementemission = this.getMovementEmission();
@@ -1133,6 +1457,20 @@ @@ -1131,8 +1455,22 @@
return SoundEvents.GENERIC_SPLASH;
}
protected SoundEvent getSwimHighSpeedSplashSound() {
return SoundEvents.GENERIC_SPLASH;
+ }
+
+ // CraftBukkit start - Add delegate methods + // CraftBukkit start - Add delegate methods
+ public SoundEvent getSwimSound0() { + public SoundEvent getSwimSound0() {
+ return this.getSwimSound(); + return this.getSwimSound();
+ } }
+
+ public SoundEvent getSwimSplashSound0() { + public SoundEvent getSwimSplashSound0() {
+ return this.getSwimSplashSound(); + return this.getSwimSplashSound();
+ } + }
@@ -631,17 +635,18 @@
} }
public CompoundTag saveWithoutId(CompoundTag nbt) { public CompoundTag saveWithoutId(CompoundTag nbt) {
- try {
- if (this.vehicle != null) {
- nbt.put("Pos", this.newDoubleList(this.vehicle.getX(), this.getY(), this.vehicle.getZ()));
- } else {
- nbt.put("Pos", this.newDoubleList(this.getX(), this.getY(), this.getZ()));
+ // CraftBukkit start - allow excluding certain data when saving + // CraftBukkit start - allow excluding certain data when saving
+ return this.saveWithoutId(nbt, true); + return this.saveWithoutId(nbt, true);
+ } + }
+ +
+ public CompoundTag saveWithoutId(CompoundTag nbttagcompound, boolean includeAll) { + public CompoundTag saveWithoutId(CompoundTag nbttagcompound, boolean includeAll) {
+ // CraftBukkit end + // CraftBukkit end
try { + try {
- if (this.vehicle != null) {
- nbt.put("Pos", this.newDoubleList(this.vehicle.getX(), this.getY(), this.vehicle.getZ()));
- } else {
- nbt.put("Pos", this.newDoubleList(this.getX(), this.getY(), this.getZ()));
+ // CraftBukkit start - selectively save position + // CraftBukkit start - selectively save position
+ if (includeAll) { + if (includeAll) {
+ if (this.vehicle != null) { + if (this.vehicle != null) {
@@ -804,7 +809,7 @@
} catch (Throwable throwable) { } catch (Throwable throwable) {
CrashReport crashreport = CrashReport.forThrowable(throwable, "Saving entity NBT"); CrashReport crashreport = CrashReport.forThrowable(throwable, "Saving entity NBT");
CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Entity being saved"); CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Entity being saved");
@@ -2080,6 +2513,87 @@ @@ -2080,6 +2513,68 @@
} else { } else {
throw new IllegalStateException("Entity has invalid position"); throw new IllegalStateException("Entity has invalid position");
} }
@@ -823,27 +828,8 @@
+ } + }
+ // CraftBukkit end + // CraftBukkit end
+ +
+ // CraftBukkit start - Reset world + // CraftBukkit start
+ if (this instanceof ServerPlayer) { + // Paper - move world parsing/loading to PlayerList#placeNewPlayer
+ Server server = Bukkit.getServer();
+ org.bukkit.World bworld = null;
+
+ // TODO: Remove World related checks, replaced with WorldUID
+ String worldName = nbt.getString("world");
+
+ if (nbt.contains("WorldUUIDMost") && nbt.contains("WorldUUIDLeast")) {
+ UUID uid = new UUID(nbt.getLong("WorldUUIDMost"), nbt.getLong("WorldUUIDLeast"));
+ bworld = server.getWorld(uid);
+ } else {
+ bworld = server.getWorld(worldName);
+ }
+
+ if (bworld == null) {
+ bworld = ((org.bukkit.craftbukkit.CraftServer) server).getServer().getLevel(Level.OVERWORLD).getWorld();
+ }
+
+ ((ServerPlayer) this).setLevel(bworld == null ? null : ((CraftWorld) bworld).getHandle());
+ }
+ this.getBukkitEntity().readBukkitValues(nbt); + this.getBukkitEntity().readBukkitValues(nbt);
+ if (nbt.contains("Bukkit.invisible")) { + if (nbt.contains("Bukkit.invisible")) {
+ boolean bukkitInvisible = nbt.getBoolean("Bukkit.invisible"); + boolean bukkitInvisible = nbt.getBoolean("Bukkit.invisible");
@@ -892,7 +878,7 @@
} catch (Throwable throwable) { } catch (Throwable throwable) {
CrashReport crashreport = CrashReport.forThrowable(throwable, "Loading entity NBT"); CrashReport crashreport = CrashReport.forThrowable(throwable, "Loading entity NBT");
CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Entity being loaded"); CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Entity being loaded");
@@ -2101,6 +2615,12 @@ @@ -2101,6 +2596,12 @@
return entitytypes.canSerialize() && minecraftkey != null ? minecraftkey.toString() : null; return entitytypes.canSerialize() && minecraftkey != null ? minecraftkey.toString() : null;
} }
@@ -905,7 +891,7 @@
protected abstract void readAdditionalSaveData(CompoundTag nbt); protected abstract void readAdditionalSaveData(CompoundTag nbt);
protected abstract void addAdditionalSaveData(CompoundTag nbt); protected abstract void addAdditionalSaveData(CompoundTag nbt);
@@ -2153,9 +2673,22 @@ @@ -2153,9 +2654,22 @@
if (stack.isEmpty()) { if (stack.isEmpty()) {
return null; return null;
} else { } else {
@@ -928,7 +914,7 @@
world.addFreshEntity(entityitem); world.addFreshEntity(entityitem);
return entityitem; return entityitem;
} }
@@ -2184,6 +2717,12 @@ @@ -2184,6 +2698,12 @@
if (this.isAlive() && this instanceof Leashable leashable) { if (this.isAlive() && this instanceof Leashable leashable) {
if (leashable.getLeashHolder() == player) { if (leashable.getLeashHolder() == player) {
if (!this.level().isClientSide()) { if (!this.level().isClientSide()) {
@@ -941,7 +927,7 @@
if (player.hasInfiniteMaterials()) { if (player.hasInfiniteMaterials()) {
leashable.removeLeash(); leashable.removeLeash();
} else { } else {
@@ -2200,6 +2739,13 @@ @@ -2200,6 +2720,13 @@
if (itemstack.is(Items.LEAD) && leashable.canHaveALeashAttachedToIt()) { if (itemstack.is(Items.LEAD) && leashable.canHaveALeashAttachedToIt()) {
if (!this.level().isClientSide()) { if (!this.level().isClientSide()) {
@@ -955,7 +941,7 @@
leashable.setLeashedTo(player, true); leashable.setLeashedTo(player, true);
} }
@@ -2265,7 +2811,7 @@ @@ -2265,7 +2792,7 @@
} }
public boolean showVehicleHealth() { public boolean showVehicleHealth() {
@@ -964,7 +950,7 @@
} }
public boolean startRiding(Entity entity, boolean force) { public boolean startRiding(Entity entity, boolean force) {
@@ -2273,7 +2819,7 @@ @@ -2273,7 +2800,7 @@
return false; return false;
} else if (!entity.couldAcceptPassenger()) { } else if (!entity.couldAcceptPassenger()) {
return false; return false;
@@ -973,7 +959,7 @@
return false; return false;
} else { } else {
for (Entity entity1 = entity; entity1.vehicle != null; entity1 = entity1.vehicle) { for (Entity entity1 = entity; entity1.vehicle != null; entity1 = entity1.vehicle) {
@@ -2285,11 +2831,32 @@ @@ -2285,11 +2812,32 @@
if (!force && (!this.canRide(entity) || !entity.canAddPassenger(this))) { if (!force && (!this.canRide(entity) || !entity.canAddPassenger(this))) {
return false; return false;
} else { } else {
@@ -1007,7 +993,7 @@
this.vehicle = entity; this.vehicle = entity;
this.vehicle.addPassenger(this); this.vehicle.addPassenger(this);
entity.getIndirectPassengersStream().filter((entity2) -> { entity.getIndirectPassengersStream().filter((entity2) -> {
@@ -2314,19 +2881,30 @@ @@ -2314,19 +2862,30 @@
} }
public void removeVehicle() { public void removeVehicle() {
@@ -1040,7 +1026,7 @@
protected void addPassenger(Entity passenger) { protected void addPassenger(Entity passenger) {
if (passenger.getVehicle() != this) { if (passenger.getVehicle() != this) {
throw new IllegalStateException("Use x.startRiding(y), not y.addPassenger(x)"); throw new IllegalStateException("Use x.startRiding(y), not y.addPassenger(x)");
@@ -2349,21 +2927,53 @@ @@ -2349,21 +2908,53 @@
} }
} }
@@ -1100,7 +1086,7 @@
} }
protected boolean canAddPassenger(Entity passenger) { protected boolean canAddPassenger(Entity passenger) {
@@ -2464,7 +3074,7 @@ @@ -2464,7 +3055,7 @@
if (teleporttransition != null) { if (teleporttransition != null) {
ServerLevel worldserver1 = teleporttransition.newLevel(); ServerLevel worldserver1 = teleporttransition.newLevel();
@@ -1109,7 +1095,7 @@
this.teleport(teleporttransition); this.teleport(teleporttransition);
} }
} }
@@ -2547,7 +3157,7 @@ @@ -2547,7 +3138,7 @@
} }
public boolean isCrouching() { public boolean isCrouching() {
@@ -1118,7 +1104,7 @@
} }
public boolean isSprinting() { public boolean isSprinting() {
@@ -2563,7 +3173,7 @@ @@ -2563,7 +3154,7 @@
} }
public boolean isVisuallySwimming() { public boolean isVisuallySwimming() {
@@ -1127,7 +1113,7 @@
} }
public boolean isVisuallyCrawling() { public boolean isVisuallyCrawling() {
@@ -2571,6 +3181,13 @@ @@ -2571,6 +3162,13 @@
} }
public void setSwimming(boolean swimming) { public void setSwimming(boolean swimming) {
@@ -1141,7 +1127,7 @@
this.setSharedFlag(4, swimming); this.setSharedFlag(4, swimming);
} }
@@ -2609,6 +3226,7 @@ @@ -2609,6 +3207,7 @@
@Nullable @Nullable
public PlayerTeam getTeam() { public PlayerTeam getTeam() {
@@ -1149,7 +1135,7 @@
return this.level().getScoreboard().getPlayersTeam(this.getScoreboardName()); return this.level().getScoreboard().getPlayersTeam(this.getScoreboardName());
} }
@@ -2624,8 +3242,12 @@ @@ -2624,8 +3223,12 @@
return this.getTeam() != null ? this.getTeam().isAlliedTo(team) : false; return this.getTeam() != null ? this.getTeam().isAlliedTo(team) : false;
} }
@@ -1163,7 +1149,7 @@
} }
public boolean getSharedFlag(int index) { public boolean getSharedFlag(int index) {
@@ -2644,7 +3266,7 @@ @@ -2644,7 +3247,7 @@
} }
public int getMaxAirSupply() { public int getMaxAirSupply() {
@@ -1172,7 +1158,7 @@
} }
public int getAirSupply() { public int getAirSupply() {
@@ -2652,7 +3274,18 @@ @@ -2652,7 +3255,18 @@
} }
public void setAirSupply(int air) { public void setAirSupply(int air) {
@@ -1192,7 +1178,7 @@
} }
public int getTicksFrozen() { public int getTicksFrozen() {
@@ -2679,11 +3312,40 @@ @@ -2679,11 +3293,40 @@
public void thunderHit(ServerLevel world, LightningBolt lightning) { public void thunderHit(ServerLevel world, LightningBolt lightning) {
this.setRemainingFireTicks(this.remainingFireTicks + 1); this.setRemainingFireTicks(this.remainingFireTicks + 1);
@@ -1235,7 +1221,7 @@
} }
public void onAboveBubbleCol(boolean drag) { public void onAboveBubbleCol(boolean drag) {
@@ -2713,7 +3375,7 @@ @@ -2713,7 +3356,7 @@
this.resetFallDistance(); this.resetFallDistance();
} }
@@ -1244,7 +1230,7 @@
return true; return true;
} }
@@ -2818,7 +3480,7 @@ @@ -2818,7 +3461,7 @@
public String toString() { public String toString() {
String s = this.level() == null ? "~NULL~" : this.level().toString(); String s = this.level() == null ? "~NULL~" : this.level().toString();
@@ -1253,7 +1239,7 @@
} }
public final boolean isInvulnerableToBase(DamageSource damageSource) { public final boolean isInvulnerableToBase(DamageSource damageSource) {
@@ -2852,6 +3514,26 @@ @@ -2852,6 +3495,26 @@
if (world instanceof ServerLevel worldserver) { if (world instanceof ServerLevel worldserver) {
if (!this.isRemoved()) { if (!this.isRemoved()) {
@@ -1280,7 +1266,7 @@
ServerLevel worldserver1 = teleportTarget.newLevel(); ServerLevel worldserver1 = teleportTarget.newLevel();
boolean flag = worldserver1.dimension() != worldserver.dimension(); boolean flag = worldserver1.dimension() != worldserver.dimension();
@@ -2920,8 +3602,12 @@ @@ -2920,8 +3583,12 @@
} else { } else {
entity.restoreFrom(this); entity.restoreFrom(this);
this.removeAfterChangingDimensions(); this.removeAfterChangingDimensions();
@@ -1294,7 +1280,7 @@
Iterator iterator1 = list1.iterator(); Iterator iterator1 = list1.iterator();
while (iterator1.hasNext()) { while (iterator1.hasNext()) {
@@ -2947,7 +3633,7 @@ @@ -2947,7 +3614,7 @@
} }
private void sendTeleportTransitionToRidingPlayers(TeleportTransition teleportTarget) { private void sendTeleportTransitionToRidingPlayers(TeleportTransition teleportTarget) {
@@ -1303,7 +1289,7 @@
Iterator iterator = this.getIndirectPassengers().iterator(); Iterator iterator = this.getIndirectPassengers().iterator();
while (iterator.hasNext()) { while (iterator.hasNext()) {
@@ -2995,8 +3681,9 @@ @@ -2995,8 +3662,9 @@
} }
protected void removeAfterChangingDimensions() { protected void removeAfterChangingDimensions() {
@@ -1314,7 +1300,7 @@
leashable.removeLeash(); leashable.removeLeash();
} }
@@ -3006,6 +3693,20 @@ @@ -3006,6 +3674,20 @@
return PortalShape.getRelativePosition(portalRect, portalAxis, this.position(), this.getDimensions(this.getPose())); return PortalShape.getRelativePosition(portalRect, portalAxis, this.position(), this.getDimensions(this.getPose()));
} }
@@ -1335,7 +1321,7 @@
public boolean canUsePortal(boolean allowVehicles) { public boolean canUsePortal(boolean allowVehicles) {
return (allowVehicles || !this.isPassenger()) && this.isAlive(); return (allowVehicles || !this.isPassenger()) && this.isAlive();
} }
@@ -3134,10 +3835,16 @@ @@ -3134,10 +3816,16 @@
return (Boolean) this.entityData.get(Entity.DATA_CUSTOM_NAME_VISIBLE); return (Boolean) this.entityData.get(Entity.DATA_CUSTOM_NAME_VISIBLE);
} }
@@ -1355,7 +1341,7 @@
return entity != null; return entity != null;
} }
@@ -3187,7 +3894,7 @@ @@ -3187,7 +3875,7 @@
/** @deprecated */ /** @deprecated */
@Deprecated @Deprecated
protected void fixupDimensions() { protected void fixupDimensions() {
@@ -1364,7 +1350,7 @@
EntityDimensions entitysize = this.getDimensions(entitypose); EntityDimensions entitysize = this.getDimensions(entitypose);
this.dimensions = entitysize; this.dimensions = entitysize;
@@ -3196,7 +3903,7 @@ @@ -3196,7 +3884,7 @@
public void refreshDimensions() { public void refreshDimensions() {
EntityDimensions entitysize = this.dimensions; EntityDimensions entitysize = this.dimensions;
@@ -1373,7 +1359,7 @@
EntityDimensions entitysize1 = this.getDimensions(entitypose); EntityDimensions entitysize1 = this.getDimensions(entitypose);
this.dimensions = entitysize1; this.dimensions = entitysize1;
@@ -3258,10 +3965,29 @@ @@ -3258,10 +3946,29 @@
} }
public final void setBoundingBox(AABB boundingBox) { public final void setBoundingBox(AABB boundingBox) {
@@ -1405,7 +1391,7 @@
return this.getDimensions(pose).eyeHeight(); return this.getDimensions(pose).eyeHeight();
} }
@@ -3335,7 +4061,7 @@ @@ -3335,7 +4042,7 @@
} }
@Nullable @Nullable
@@ -1414,7 +1400,7 @@
return null; return null;
} }
@@ -3435,7 +4161,7 @@ @@ -3435,7 +4142,7 @@
} }
public boolean isControlledByLocalInstance() { public boolean isControlledByLocalInstance() {
@@ -1423,7 +1409,7 @@
if (entityliving instanceof Player entityhuman) { if (entityliving instanceof Player entityhuman) {
return entityhuman.isLocalPlayer(); return entityhuman.isLocalPlayer();
@@ -3445,7 +4171,7 @@ @@ -3445,7 +4152,7 @@
} }
public boolean isControlledByClient() { public boolean isControlledByClient() {
@@ -1432,7 +1418,7 @@
return entityliving != null && entityliving.isControlledByClient(); return entityliving != null && entityliving.isControlledByClient();
} }
@@ -3463,7 +4189,7 @@ @@ -3463,7 +4170,7 @@
return new Vec3((double) f1 * d2 / (double) f3, 0.0D, (double) f2 * d2 / (double) f3); return new Vec3((double) f1 * d2 / (double) f3, 0.0D, (double) f2 * d2 / (double) f3);
} }
@@ -1441,7 +1427,7 @@
return new Vec3(this.getX(), this.getBoundingBox().maxY, this.getZ()); return new Vec3(this.getX(), this.getBoundingBox().maxY, this.getZ());
} }
@@ -3488,9 +4214,38 @@ @@ -3488,9 +4195,38 @@
public int getFireImmuneTicks() { public int getFireImmuneTicks() {
return 1; return 1;
} }
@@ -1481,7 +1467,7 @@
} }
public void lookAt(EntityAnchorArgument.Anchor anchorPoint, Vec3 target) { public void lookAt(EntityAnchorArgument.Anchor anchorPoint, Vec3 target) {
@@ -3551,6 +4306,11 @@ @@ -3551,6 +4287,11 @@
vec3d = vec3d.add(vec3d1); vec3d = vec3d.add(vec3d1);
++k1; ++k1;
} }
@@ -1493,7 +1479,7 @@
} }
} }
} }
@@ -3613,7 +4373,7 @@ @@ -3613,7 +4354,7 @@
return new ClientboundAddEntityPacket(this, entityTrackerEntry); return new ClientboundAddEntityPacket(this, entityTrackerEntry);
} }
@@ -1502,7 +1488,7 @@
return this.type.getDimensions(); return this.type.getDimensions();
} }
@@ -3818,8 +4578,16 @@ @@ -3818,8 +4559,16 @@
@Override @Override
public final void setRemoved(Entity.RemovalReason reason) { public final void setRemoved(Entity.RemovalReason reason) {
@@ -1520,7 +1506,7 @@
} }
if (this.removalReason.shouldDestroy()) { if (this.removalReason.shouldDestroy()) {
@@ -3827,8 +4595,8 @@ @@ -3827,8 +4576,8 @@
} }
this.getPassengers().forEach(Entity::stopRiding); this.getPassengers().forEach(Entity::stopRiding);
@@ -1531,7 +1517,7 @@
} }
public void unsetRemoved() { public void unsetRemoved() {
@@ -3887,7 +4655,7 @@ @@ -3887,7 +4636,7 @@
} }
public Vec3 getKnownMovement() { public Vec3 getKnownMovement() {