even even even even even even more work

This commit is contained in:
Spottedleaf 2020-06-25 18:53:21 -07:00
parent ec7bd6a7c6
commit cfd598512a
34 changed files with 420 additions and 408 deletions

View File

@ -5,4 +5,5 @@
* Mini: "MC-50319": fix if still works
* Mini: I definetly dropped a patch I didnt want to drop, we need to go thru in the end and see if all patches are still in, lol
* Make sure the flat bedrock setting doesn't do anything stupid
* Check DataBits foreach
* Check DataBits foreach
* Update MobGoalHelper

View File

@ -12,7 +12,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
EntityDamageEvent event = CraftEventFactory.handleLivingEntityDamageEvent(this, damagesource, originalDamage, hardHatModifier, blockingModifier, armorModifier, resistanceModifier, magicModifier, absorptionModifier, hardHat, blocking, armor, resistance, magic, absorption);
if (damagesource.getEntity() instanceof EntityHuman) {
- ((EntityHuman) damagesource.getEntity()).ey(); // Moved from EntityHuman in order to make the cooldown reset get called after the damage event is fired
- ((EntityHuman) damagesource.getEntity()).resetAttackCooldown(); // Moved from EntityHuman in order to make the cooldown reset get called after the damage event is fired
+ // Paper start - PlayerAttackEntityCooldownResetEvent
+ if (damagesource.getEntity() instanceof EntityPlayer) {
+ EntityPlayer player = (EntityPlayer) damagesource.getEntity();
@ -23,7 +23,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ ((EntityHuman) damagesource.getEntity()).resetCooldown();
+ }
+ // Paper end
+
}
if (event.isCancelled()) {
return false;

View File

@ -37,23 +37,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/IEntitySelector.java
+++ b/src/main/java/net/minecraft/server/IEntitySelector.java
@@ -0,0 +0,0 @@ public final class IEntitySelector {
public static final Predicate<Entity> f = (entity) -> {
public static final Predicate<Entity> g = (entity) -> {
return !entity.isSpectator();
};
+ public static Predicate<EntityHuman> isInsomniac = (player) -> MathHelper.clamp(((EntityPlayer) player).getStatisticManager().getStatisticValue(StatisticList.CUSTOM.get(StatisticList.TIME_SINCE_REST)), 1, Integer.MAX_VALUE) >= 72000; // Paper
public static Predicate<Entity> a(double d0, double d1, double d2, double d3) {
double d4 = d3 * d3;
// Paper start
public static final Predicate<Entity> affectsSpawning = (entity) -> {
diff --git a/src/main/java/net/minecraft/server/MobSpawnerPhantom.java b/src/main/java/net/minecraft/server/MobSpawnerPhantom.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/MobSpawnerPhantom.java
+++ b/src/main/java/net/minecraft/server/MobSpawnerPhantom.java
@@ -0,0 +0,0 @@ public class MobSpawnerPhantom {
@@ -0,0 +0,0 @@ public class MobSpawnerPhantom implements MobSpawner {
while (iterator.hasNext()) {
EntityHuman entityhuman = (EntityHuman) iterator.next();
- if (!entityhuman.isSpectator()) {
+ if (!entityhuman.isSpectator() && (!worldserver.paperConfig.phantomIgnoreCreative || !entityhuman.isCreative())) { // Paper
BlockPosition blockposition = new BlockPosition(entityhuman);
BlockPosition blockposition = entityhuman.getChunkCoordinates();
if (!worldserver.worldProvider.f() || blockposition.getY() >= worldserver.getSeaLevel() && worldserver.f(blockposition)) {
if (!worldserver.getDimensionManager().hasSkyLight() || blockposition.getY() >= worldserver.getSeaLevel() && worldserver.f(blockposition)) {

View File

@ -91,19 +91,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
private int F;
private int G;
private int H;
public final long[] f = new long[100]; public long[] getTickTimes() { return f; } // Paper - OBFHELPER
public final long[] h; public long[] getTickTimes() { return h; } // Paper - OBFHELPER
+ // Paper start
+ public final TickTimes tickTimes5s = new TickTimes(100);
+ public final TickTimes tickTimes10s = new TickTimes(200);
+ public final TickTimes tickTimes60s = new TickTimes(1200);
+ // Paper end
@Nullable
private KeyPair I;
private KeyPair H;
@Nullable
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
this.av = this.av * 0.8F + (float) l / 1000000.0F * 0.19999999F;
this.ag = this.ag * 0.8F + (float) l / 1000000.0F * 0.19999999F;
long i1 = SystemUtils.getMonotonicNanos();
+ // Paper start
@ -116,9 +116,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
this.methodProfiler.exit();
org.spigotmc.WatchdogThread.tick(); // Spigot
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
return SERVER; // Paper
public SaveData getSaveData() {
return this.saveData;
}
// CraftBukkit end
+
+ // Paper start
+ public static class TickTimes {

View File

@ -1,23 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Mariell Hoversholm <proximyst@proximyst.com>
Date: Sun, 19 Apr 2020 12:25:20 +0200
Subject: [PATCH] Allow sleeping players to float
This change lets players who are in their bed have a position which is above
ground for a longer period of time. This is because of the server not setting
their position to the ground/exit location when entering the bed, resulting in
the server believing they're still in the air.
diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/PlayerConnection.java
+++ b/src/main/java/net/minecraft/server/PlayerConnection.java
@@ -0,0 +0,0 @@ public class PlayerConnection implements PacketListenerPlayIn {
this.player.setLocation(this.l, this.m, this.n, this.player.yaw, this.player.pitch);
++this.e;
this.processedMovePackets = this.receivedMovePackets;
- if (this.B) {
+ if (this.B && !this.player.isSleeping()) { // Paper - #3176 Allow sleeping players to float
if (++this.C > 80) {
PlayerConnection.LOGGER.warn("{} was kicked for floating too long!", this.player.getDisplayName().getString());
this.disconnect(com.destroystokyo.paper.PaperConfig.flyingKickPlayerMessage); // Paper - use configurable kick message

View File

@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (joinMessage != null && joinMessage.length() > 0) {
- for (IChatBaseComponent line : org.bukkit.craftbukkit.util.CraftChatMessage.fromString(joinMessage)) {
- server.getPlayerList().sendAll(new PacketPlayOutChat(line));
- server.getPlayerList().sendAll(new PacketPlayOutChat(line, ChatMessageType.SYSTEM, SystemUtils.b));
- }
+ // Paper start - Removed sendAll for loop and broadcasted to console also
+ server.getPlayerList().sendMessage(CraftChatMessage.fromString(joinMessage));

View File

@ -9,9 +9,9 @@ diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -0,0 +0,0 @@ public class WorldServer extends World {
private final Queue<Entity> entitiesToAdd = Queues.newArrayDeque();
@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed {
public final List<EntityPlayer> players = Lists.newArrayList(); // Paper - private -> public
public final ChunkProviderServer chunkProvider; // Paper - public
boolean tickingEntities;
+ // Paper start
+ List<java.lang.Runnable> afterEntityTickingTasks = Lists.newArrayList();
@ -24,9 +24,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ // Paper end
private final MinecraftServer server;
private final WorldNBTStorage dataManager;
public final WorldDataServer worldDataServer; // CraftBukkit - type
public boolean savingDisabled;
@@ -0,0 +0,0 @@ public class WorldServer extends World {
@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed {
timings.entityTick.stopTiming(); // Spigot
this.tickingEntities = false;
@ -42,4 +42,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper end
this.getMinecraftServer().midTickLoadChunks(); // Paper
try (co.aikar.timings.Timing ignored = this.timings.newEntities.startTiming()) { // Paper - timings
Entity entity2;

View File

@ -11,7 +11,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/ChunkMapDistance.java
+++ b/src/main/java/net/minecraft/server/ChunkMapDistance.java
@@ -0,0 +0,0 @@ public abstract class ChunkMapDistance {
long i = sectionposition.u().pair();
long i = sectionposition.r().pair();
ObjectSet<EntityPlayer> objectset = (ObjectSet) this.c.get(i);
- objectset.remove(entityplayer);
@ -19,5 +19,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ if (objectset != null) objectset.remove(entityplayer); // Paper - some state corruption happens here, don't crash, clean up gracefully.
+ if (objectset == null || objectset.isEmpty()) { // Paper
this.c.remove(i);
this.f.b(i, Integer.MAX_VALUE, false);
this.g.b(i, Integer.MAX_VALUE, false);
this.f.update(i, Integer.MAX_VALUE, false);
this.g.update(i, Integer.MAX_VALUE, false);

View File

@ -9,11 +9,20 @@ diff --git a/src/main/java/net/minecraft/server/BlockFire.java b/src/main/java/n
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/BlockFire.java
+++ b/src/main/java/net/minecraft/server/BlockFire.java
@@ -0,0 +0,0 @@ public class BlockFire extends Block {
@@ -0,0 +0,0 @@ public class BlockFire extends BlockFireAbstract {
@Override
public IBlockData updateState(IBlockData iblockdata, EnumDirection enumdirection, IBlockData iblockdata1, GeneratorAccess generatoraccess, BlockPosition blockposition, BlockPosition blockposition1) {
// CraftBukkit start
+ if (!(generatoraccess instanceof WorldServer)) return this.canPlace(iblockdata, generatoraccess, blockposition) ? (IBlockData) this.a((IBlockAccess) generatoraccess, blockposition).set(BlockFire.AGE, iblockdata.get(BlockFire.AGE)) : Blocks.AIR.getBlockData(); // Paper - don't fire events in world generation
if (!iblockdata.canPlace(generatoraccess, blockposition)) {
+ if (!(generatoraccess instanceof WorldServer)) return this.canPlace(iblockdata, generatoraccess, blockposition) ? (IBlockData) this.a(generatoraccess, blockposition, (Integer) iblockdata.get(BlockFire.AGE)) : Blocks.AIR.getBlockData(); // Paper - don't fire events in world generation
if (!this.canPlace(iblockdata, generatoraccess, blockposition)) {
CraftBlockState blockState = CraftBlockState.getBlockState(generatoraccess, blockposition);
blockState.setData(Blocks.AIR.getBlockData());
@@ -0,0 +0,0 @@ public class BlockFire extends BlockFireAbstract {
return blockState.getHandle();
}
}
- return this.a(generatoraccess, blockposition, (Integer) iblockdata.get(BlockFire.AGE));
+ return this.a(generatoraccess, blockposition, (Integer) iblockdata.get(BlockFire.AGE)); // Paper - diff on change, see "don't fire events in world generation"
// CraftBukkit end
}

View File

@ -16,9 +16,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
this.serverStatisticManager = minecraftserver.getPlayerList().getStatisticManager(this);
this.advancementDataPlayer = minecraftserver.getPlayerList().f(this);
this.H = 1.0F;
- this.a(worldserver);
+ //this.a(worldserver); // Paper - don't move to spawn on login, only first join
this.G = 1.0F;
- this.b(worldserver);
+ //this.b(worldserver); // Paper - don't move to spawn on login, only first join
this.cachedSingleHashSet = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<>(this); // Paper
@ -26,28 +26,29 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
// CraftBukkit end
+ public void moveToSpawn(WorldServer worldserver) { a(worldserver); } // Paper - OBFHELPER
private void a(WorldServer worldserver) {
+ public final void moveToSpawn(WorldServer worldserver) { b(worldserver); } // Paper - OBFHELPER
private void b(WorldServer worldserver) {
BlockPosition blockposition = worldserver.getSpawn();
@@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
position = new Vec3D(world.getSpawn());
position = Vec3D.a(((WorldServer) world).getSpawn());
}
this.world = world;
- this.setPosition(position.getX(), position.getY(), position.getZ());
+ this.setPositionRaw(position.getX(), position.getY(), position.getZ()); // Paper - don't register to chunks yet
}
this.dimension = ((WorldServer) this.world).getWorldProvider().getDimensionManager();
this.playerInteractManager.a((WorldServer) world);
}
diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/PlayerList.java
+++ b/src/main/java/net/minecraft/server/PlayerList.java
@@ -0,0 +0,0 @@ public abstract class PlayerList {
NBTTagCompound bukkit = nbttagcompound.getCompound("bukkit");
s = bukkit.hasKeyOfType("lastKnownName", 8) ? bukkit.getString("lastKnownName") : s;
worldserver1 = worldserver;
}
+ if (nbttagcompound == null) entityplayer.moveToSpawn(worldserver); // Paper - only move to spawn on first login, otherwise, stay where you are....
// CraftBukkit end
entityplayer.spawnIn(worldserver);
+ if (nbttagcompound == null) entityplayer.moveToSpawn(worldserver1); // Paper - only move to spawn on first login, otherwise, stay where you are....
+
entityplayer.spawnIn(worldserver1);
entityplayer.playerInteractManager.a((WorldServer) entityplayer.world);
String s1 = "local";

View File

@ -14,8 +14,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public void playerTick() {
try {
- if (!this.isSpectator() || this.world.isLoaded(new BlockPosition(this))) {
+ if (valid && (!this.isSpectator() || this.world.isLoaded(new BlockPosition(this)))) { // Paper - don't tick dead players that are not in the world currently (pending respawn)
- if (!this.isSpectator() || this.world.isLoaded(this.getChunkCoordinates())) {
+ if (valid && !this.isSpectator() || this.world.isLoaded(this.getChunkCoordinates())) { // Paper - don't tick dead players that are not in the world currently (pending respawn)
super.tick();
}

View File

@ -53,8 +53,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return Either.left(chunk);
});
}, (runnable) -> {
- this.mailboxMain.a(ChunkTaskQueueSorter.a(playerchunk, runnable)); // CraftBukkit - decompile error
+ this.mailboxMain.a(ChunkTaskQueueSorter.a(playerchunk, () -> PlayerChunkMap.this.chunkLoadConversionCallbackExecutor.execute(runnable))); // CraftBukkit - decompile error // Paper - delay running Chunk post processing until outside of the sorter to prevent a deadlock scenario when post processing causes another chunk request.
- this.mailboxMain.a(ChunkTaskQueueSorter.a(playerchunk, runnable));
+ this.mailboxMain.a(ChunkTaskQueueSorter.a(playerchunk, () -> PlayerChunkMap.this.chunkLoadConversionCallbackExecutor.execute(runnable))); // Paper - delay running Chunk post processing until outside of the sorter to prevent a deadlock scenario when post processing causes another chunk request.
});
completablefuture1.thenAcceptAsync((either) -> {

View File

@ -50,7 +50,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ if (entity instanceof EntityPlayer && ((EntityPlayer) entity).supressTrackerForLogin) return; // Delay adding to tracker until after list packets
// Paper end
if (!(entity instanceof EntityComplexPart)) {
if (!(entity instanceof EntityLightning)) {
EntityTypes<?> entitytypes = entity.getEntityType();
diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/PlayerList.java

View File

@ -36,17 +36,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// CraftBukkit start
@@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
@Nullable
public Entity teleportTo(DimensionManager dimensionmanager, BlockPosition location) {
public Entity teleportTo(WorldServer worldserver, BlockPosition location) {
// CraftBukkit end
+ // Paper start - fix bad state entities causing dupes
+ if (!isAlive() || !valid) {
+ LOGGER.warn("Illegal Entity Teleport " + this + " to " + dimensionmanager + ":" + location, new Throwable());
+ LOGGER.warn("Illegal Entity Teleport " + this + " to " + worldserver + ":" + location, new Throwable());
+ return null;
+ }
+ // Paper end
if (!this.world.isClientSide && !this.dead) {
if (this.world instanceof WorldServer && !this.dead) {
this.world.getMethodProfiler().enter("changeDimension");
MinecraftServer minecraftserver = this.getMinecraftServer();
// CraftBukkit start
@@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
entity.bukkitEntity = this.getBukkitEntity();
@ -75,7 +75,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (!itemstack.isEmpty()) {
- drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(itemstack)); // CraftBukkit - add to drops
+ drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack)); // CraftBukkit - add to drops // Paper - mirror so we can destroy it later - though this call site was safe
this.handItems.set(i, ItemStack.a);
this.handItems.set(i, ItemStack.b);
}
}
@@ -0,0 +0,0 @@ public class EntityArmorStand extends EntityLiving {
@ -84,7 +84,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (!itemstack.isEmpty()) {
- drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(itemstack)); // CraftBukkit - add to drops
+ drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack)); // CraftBukkit - add to drops // Paper - mirror so we can destroy it later - though this call site was safe
this.armorItems.set(i, ItemStack.a);
this.armorItems.set(i, ItemStack.b);
}
}
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java

View File

@ -40,8 +40,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
-public class CommandListenerWrapper implements ICompletionProvider {
+public class CommandListenerWrapper implements ICompletionProvider, com.destroystokyo.paper.brigadier.BukkitBrigadierCommandSource { // Paper
public static final SimpleCommandExceptionType a = new SimpleCommandExceptionType(new ChatMessage("permissions.requires.player", new Object[0]));
public static final SimpleCommandExceptionType b = new SimpleCommandExceptionType(new ChatMessage("permissions.requires.entity", new Object[0]));
public static final SimpleCommandExceptionType a = new SimpleCommandExceptionType(new ChatMessage("permissions.requires.player"));
public static final SimpleCommandExceptionType b = new SimpleCommandExceptionType(new ChatMessage("permissions.requires.entity"));
@@ -0,0 +0,0 @@ public class CommandListenerWrapper implements ICompletionProvider {
return this.g;
}
@ -73,19 +73,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/PlayerConnection.java
+++ b/src/main/java/net/minecraft/server/PlayerConnection.java
@@ -0,0 +0,0 @@ public class PlayerConnection implements PacketListenerPlayIn {
ParseResults<CommandListenerWrapper> parseresults = this.minecraftServer.getCommandDispatcher().a().parse(stringreader, this.player.getCommandListener());
ParseResults<CommandListenerWrapper> parseresults = this.minecraftServer.getCommandDispatcher().a().parse(stringreader, this.player.getCommandListener());
this.minecraftServer.getCommandDispatcher().a().getCompletionSuggestions(parseresults).thenAccept((suggestions) -> {
- if (((Suggestions) suggestions).isEmpty()) return; // CraftBukkit - don't send through empty suggestions - prevents [<args>] from showing for plugins with nothing more to offer
- this.networkManager.sendPacket(new PacketPlayOutTabComplete(packetplayintabcomplete.b(), (Suggestions) suggestions)); // CraftBukkit - decompile error
+ // Paper start
+ com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent suggestEvent = new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent(this.getPlayer(), suggestions, buffer);
+ suggestEvent.setCancelled(suggestions.isEmpty());
+ if (!suggestEvent.callEvent()) return;
+ this.networkManager.sendPacket(new PacketPlayOutTabComplete(packetplayintabcomplete.b(), (Suggestions) suggestEvent.getSuggestions())); // CraftBukkit - decompile error // Paper
+ // Paper end
});
}); // Paper - This needs to be on main
this.minecraftServer.getCommandDispatcher().a().getCompletionSuggestions(parseresults).thenAccept((suggestions) -> {
- if (suggestions.isEmpty()) return; // CraftBukkit - don't send through empty suggestions - prevents [<args>] from showing for plugins with nothing more to offer
- this.networkManager.sendPacket(new PacketPlayOutTabComplete(packetplayintabcomplete.b(), suggestions));
+ // Paper start
+ com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent suggestEvent = new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent(this.getPlayer(), suggestions, buffer);
+ suggestEvent.setCancelled(suggestions.isEmpty());
+ if (!suggestEvent.callEvent()) return;
+ this.networkManager.sendPacket(new PacketPlayOutTabComplete(packetplayintabcomplete.b(), (Suggestions) suggestEvent.getSuggestions())); // CraftBukkit - decompile error // Paper
+ // Paper end
});
});
}
@@ -0,0 +0,0 @@ public class PlayerConnection implements PacketListenerPlayIn {
@ -99,7 +99,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ this.networkManager.sendPacket(new PacketPlayOutTabComplete(packetplayintabcomplete.b(), suggestEvent.getSuggestions()));
}
// Paper end - async tab completion
}
diff --git a/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java b/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java

View File

@ -787,13 +787,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
};
private final Map<PathfinderGoal.Type, PathfinderGoalWrapped> c = new EnumMap(PathfinderGoal.Type.class);
- private final Set<PathfinderGoalWrapped> d = Sets.newLinkedHashSet();private Set<PathfinderGoalWrapped> getTasks() { return d; }// Paper - OBFHELPER
+ private final Set<PathfinderGoalWrapped> d = Sets.newLinkedHashSet();public Set<PathfinderGoalWrapped> getTasks() { return d; }// Paper - OBFHELPER
private final GameProfilerFiller e;
- private final Set<PathfinderGoalWrapped> d = Sets.newLinkedHashSet(); private Set<PathfinderGoalWrapped> getTasks() { return d; }// Paper - OBFHELPER
+ private final Set<PathfinderGoalWrapped> d = Sets.newLinkedHashSet(); public final Set<PathfinderGoalWrapped> getTasks() { return d; }// Paper - OBFHELPER // Paper - private -> public
private final Supplier<GameProfilerFiller> e;
private final EnumSet<PathfinderGoal.Type> f = EnumSet.noneOf(PathfinderGoal.Type.class); // Paper unused, but dummy to prevent plugins from crashing as hard. Theyll need to support paper in a special case if this is super important, but really doesn't seem like it would be.
private final OptimizedSmallEnumSet<PathfinderGoal.Type> goalTypes = new OptimizedSmallEnumSet<>(PathfinderGoal.Type.class); // Paper - remove streams from pathfindergoalselector
@@ -0,0 +0,0 @@ public class PathfinderGoalSelector {
this.e = gameprofilerfiller;
this.e = supplier;
}
- public void a(int i, PathfinderGoal pathfindergoal) {
@ -811,11 +811,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
for (Iterator<PathfinderGoalWrapped> iterator = this.d.iterator(); iterator.hasNext();) {
PathfinderGoalWrapped goalWrapped = iterator.next();
@@ -0,0 +0,0 @@ public class PathfinderGoalSelector {
this.e.exit();
gameprofilerfiller.exit();
}
+ public Stream<PathfinderGoalWrapped> getExecutingGoals() {return c();} // Paper - OBFHELPER
public Stream<PathfinderGoalWrapped> c() {
+ public final Stream<PathfinderGoalWrapped> getExecutingGoals() { return d(); } // Paper - OBFHELPER
public Stream<PathfinderGoalWrapped> d() {
return this.d.stream().filter(PathfinderGoalWrapped::g);
}
diff --git a/src/main/java/net/minecraft/server/PathfinderGoalWrapped.java b/src/main/java/net/minecraft/server/PathfinderGoalWrapped.java

View File

@ -89,14 +89,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/EntityHuman.java
+++ b/src/main/java/net/minecraft/server/EntityHuman.java
@@ -0,0 +0,0 @@ public abstract class EntityHuman extends EntityLiving {
private static final Map<EntityPose, EntitySize> b = ImmutableMap.<EntityPose, EntitySize>builder().put(EntityPose.STANDING, EntityHuman.bp).put(EntityPose.SLEEPING, EntityHuman.ap).put(EntityPose.FALL_FLYING, EntitySize.b(0.6F, 0.6F)).put(EntityPose.SWIMMING, EntitySize.b(0.6F, 0.6F)).put(EntityPose.SPIN_ATTACK, EntitySize.b(0.6F, 0.6F)).put(EntityPose.CROUCHING, EntitySize.b(0.6F, 1.5F)).put(EntityPose.DYING, EntitySize.c(0.2F, 0.2F)).build();
private static final Map<EntityPose, EntitySize> b = ImmutableMap.<EntityPose, EntitySize>builder().put(EntityPose.STANDING, EntityHuman.bo).put(EntityPose.SLEEPING, EntityHuman.ao).put(EntityPose.FALL_FLYING, EntitySize.b(0.6F, 0.6F)).put(EntityPose.SWIMMING, EntitySize.b(0.6F, 0.6F)).put(EntityPose.SPIN_ATTACK, EntitySize.b(0.6F, 0.6F)).put(EntityPose.CROUCHING, EntitySize.b(0.6F, 1.5F)).put(EntityPose.DYING, EntitySize.c(0.2F, 0.2F)).build();
private static final DataWatcherObject<Float> c = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.c);
private static final DataWatcherObject<Integer> d = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.b);
- protected static final DataWatcherObject<Byte> bq = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.a);
+ protected static final DataWatcherObject<Byte> bq = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.a); public static DataWatcherObject<Byte> getSkinPartsWatcher() { return bq; } // Paper - OBFHELPER
protected static final DataWatcherObject<Byte> br = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.a);
- protected static final DataWatcherObject<Byte> bp = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.a);
+ protected static final DataWatcherObject<Byte> bp = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.a); public static DataWatcherObject<Byte> getSkinPartsWatcher() { return bp; } // Paper - OBFHELPER
protected static final DataWatcherObject<Byte> bq = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.a);
protected static final DataWatcherObject<NBTTagCompound> br = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.p);
protected static final DataWatcherObject<NBTTagCompound> bs = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.p);
protected static final DataWatcherObject<NBTTagCompound> bt = DataWatcher.a(EntityHuman.class, DataWatcherRegistry.p);
diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/EntityPlayer.java
@ -108,19 +108,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import com.destroystokyo.paper.event.player.PlayerClientOptionsChangeEvent; // Paper
import com.mojang.authlib.GameProfile;
import com.mojang.datafixers.util.Either;
import io.netty.util.concurrent.Future;
import com.mojang.serialization.DataResult;
@@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
public int lastSentExp = -99999999;
public int invulnerableTicks = 60;
private EnumChatVisibility ch;
- private boolean ci = true;
+ private boolean ci = true; public boolean hasChatColorsEnabled() { return this.ci; } // Paper - OBFHELPER
private long cj = SystemUtils.getMonotonicMillis();
private EnumChatVisibility cf;
- private boolean cg = true;
+ private boolean cg = true; public boolean hasChatColorsEnabled() { return this.cg; } // Paper - OBFHELPER
private long ch = SystemUtils.getMonotonicMillis();
private Entity spectatedEntity;
public boolean worldChangeInvuln;
@@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
}
public String locale = null; // CraftBukkit - lowercase // Paper - default to null
public void a(PacketPlayInSettings packetplayinsettings) {
+ new PlayerClientOptionsChangeEvent(getBukkitEntity(), packetplayinsettings.getLocale(), packetplayinsettings.viewDistance, com.destroystokyo.paper.ClientOption.ChatVisibility.valueOf(packetplayinsettings.getChatVisibility().name()), packetplayinsettings.hasChatColorsEnabled(), new com.destroystokyo.paper.PaperSkinParts(packetplayinsettings.getSkinParts()), packetplayinsettings.getMainHand() == EnumMainHand.LEFT ? MainHand.LEFT : MainHand.RIGHT).callEvent(); // Paper - settings event
// CraftBukkit start
@ -130,15 +130,19 @@ diff --git a/src/main/java/net/minecraft/server/PacketPlayInSettings.java b/src/
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/PacketPlayInSettings.java
+++ b/src/main/java/net/minecraft/server/PacketPlayInSettings.java
@@ -0,0 +0,0 @@ import java.io.IOException;
public class PacketPlayInSettings implements Packet<PacketListenerPlayIn> {
- public String locale;
+ public String locale; public String getLocale() { return this.locale; } // Paper - OBFHELPER
public int viewDistance;
private EnumChatVisibility c;
private boolean d;
@@ -0,0 +0,0 @@ public class PacketPlayInSettings implements Packet<PacketListenerPlayIn> {
packetlistenerplayin.a(this);
}
+ public String getLocale() { return b(); } // Paper - OBFHELPER
public String b() {
return this.a;
}
+ public EnumChatVisibility getChatVisibility() { return d(); } // Paper - OBFHELPER
public EnumChatVisibility d() {
return this.c;
@ -166,14 +170,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
import com.destroystokyo.paper.Title;
import com.destroystokyo.paper.profile.CraftPlayerProfile;
import com.destroystokyo.paper.profile.PlayerProfile;
@@ -0,0 +0,0 @@ import net.minecraft.server.BlockPosition;
import net.minecraft.server.ChatComponentText;
import net.minecraft.server.Container;
import net.minecraft.server.Entity;
+import net.minecraft.server.EntityHuman;
import net.minecraft.server.EntityLiving;
import net.minecraft.server.EntityPlayer;
import net.minecraft.server.EnumColor;
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
public void setViewDistance(int viewDistance) {
throw new NotImplementedException("Per-Player View Distance APIs need further understanding to properly implement (There are per world view distances though!)"); // TODO

View File

@ -71,11 +71,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/DedicatedServer.java
@@ -0,0 +0,0 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer
long l = SystemUtils.getMonotonicNanos() - i;
String s2 = String.format(Locale.ROOT, "%.3fs", (double) l / 1.0E9D);
long j = SystemUtils.getMonotonicNanos() - i;
String s = String.format(Locale.ROOT, "%.3fs", (double) j / 1.0E9D);
- DedicatedServer.LOGGER.info("Done ({})! For help, type \"help\"", s2);
+ //DedicatedServer.LOGGER.info("Done ({})! For help, type \"help\"", s2); // Paper moved to after init
- DedicatedServer.LOGGER.info("Done ({})! For help, type \"help\"", s);
+ //DedicatedServer.LOGGER.info("Done ({})! For help, type \"help\"", s); // Paper moved to after init
if (dedicatedserverproperties.announcePlayerAchievements != null) {
((GameRules.GameRuleBoolean) this.getGameRules().get(GameRules.ANNOUNCE_ADVANCEMENTS)).a(dedicatedserverproperties.announcePlayerAchievements, (MinecraftServer) this);
}
@ -91,8 +91,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override
public void stop() {
super.stop();
- SystemUtils.f();
+ //SystemUtils.f(); // Paper - moved into super
- SystemUtils.h();
+ //SystemUtils.h(); // Paper - moved into super
}
@Override
@ -105,21 +105,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
r0.run();
} catch (Exception exception) {
+ if (exception.getCause() instanceof ThreadDeath) throw exception; // Paper
IAsyncTaskHandler.LOGGER.fatal("Error executing task on {}", this.bi(), exception);
IAsyncTaskHandler.LOGGER.fatal("Error executing task on {}", this.bh(), exception);
}
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
private final ResourcePackRepository<ResourcePackLoader> resourcePackRepository;
@Nullable
private ResourcePackSourceFolder resourcePackFolder;
+ public volatile Thread shutdownThread; // Paper
public CommandDispatcher commandDispatcher;
private final CraftingManager craftingManager;
private final TagRegistry tagRegistry;
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
public boolean serverAutoSave = false; // Paper
public File bukkitDataPackFolder;
@ -130,6 +122,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// Spigot start
public static final int TPS = 20;
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
public final SlackActivityAccountant slackActivityAccountant = new SlackActivityAccountant();
// Spigot end
+ public volatile Thread shutdownThread; // Paper
+
public static <S extends MinecraftServer> S a(Function<Thread, S> function) {
AtomicReference<S> atomicreference = new AtomicReference();
Thread thread = new Thread(() -> {
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
// CraftBukkit start
private boolean hasStopped = false;
@ -182,7 +183,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public String getServerIp() {
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
public void run() {
protected void v() {
try {
+ long serverStartTime = SystemUtils.getMonotonicNanos(); // Paper
if (this.init()) {
@ -252,13 +253,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
midTickLoadChunks(); // Paper
} catch (Throwable throwable) {
// Spigot Start
+ if (throwable instanceof ThreadDeath) { throw throwable; } // Paper
CrashReport crashreport;
try {
crashreport = CrashReport.a(throwable, "Exception ticking world");
try {
crashreport = CrashReport.a(throwable, "Exception ticking world");
} catch (Throwable t) {
+ if (throwable instanceof ThreadDeath) { throw (ThreadDeath)throwable; } // Paper
throw new RuntimeException("Error generating crash report", t);
}
// Spigot End
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
@ -289,13 +290,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/SystemUtils.java
+++ b/src/main/java/net/minecraft/server/SystemUtils.java
@@ -0,0 +0,0 @@ public class SystemUtils {
return SystemUtils.c;
return SystemUtils.f;
}
+ public static void shutdownServerThreadPool() { f(); } // Paper - OBFHELPER
public static void f() {
SystemUtils.c.shutdown();
+ public static void shutdownServerThreadPool() { h(); } // Paper - OBFHELPER
public static void h() {
a(SystemUtils.e);
a(SystemUtils.f);
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/World.java

View File

@ -37,6 +37,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
worldloadlistener.b();
- chunkproviderserver.getLightEngine().a(5);
+ chunkproviderserver.getLightEngine().a(worldserver.paperConfig.lightQueueSize); // Paper - increase light queue size
this.ba();
// CraftBukkit start
this.forceTicks = false;

View File

@ -4,6 +4,19 @@ Date: Sun, 19 Apr 2020 04:28:29 -0400
Subject: [PATCH] Load Chunks for Login Asynchronously
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
@@ -0,0 +0,0 @@ public class ChunkProviderServer extends IChunkProvider {
return this.serverThreadQueue.executeNext();
}
- private boolean tickDistanceManager() {
+ public boolean tickDistanceManager() { // Paper - private -> public
boolean flag = this.chunkMapDistance.a(this.playerChunkMap);
boolean flag1 = this.playerChunkMap.b();
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/Entity.java
@ -12,18 +25,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
this.pitch = MathHelper.a(f1, -90.0F, 90.0F) % 360.0F;
this.lastYaw = this.yaw;
this.lastPitch = this.pitch;
- world.getChunkAt((int) Math.floor(this.locX) >> 4, (int) Math.floor(this.locZ) >> 4); // CraftBukkit
+ if (valid) world.getChunkAt((int) Math.floor(this.locX) >> 4, (int) Math.floor(this.locZ) >> 4); // CraftBukkit // Paper
- world.getChunkAt((int) Math.floor(this.locX()) >> 4, (int) Math.floor(this.locZ()) >> 4); // CraftBukkit
+ if (valid) world.getChunkAt((int) Math.floor(this.locX()) >> 4, (int) Math.floor(this.locZ()) >> 4); // CraftBukkit // Paper
}
public void setPositionRotation(BlockPosition blockposition, float f, float f1) {
public void c(Vec3D vec3d) {
diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/EntityPlayer.java
+++ b/src/main/java/net/minecraft/server/EntityPlayer.java
@@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
private static final Logger LOGGER = LogManager.getLogger();
public String locale = null; // CraftBukkit - lowercase // Paper - default to null
public PlayerConnection playerConnection;
+ public NetworkManager networkManager; // Paper
public final MinecraftServer server;
@ -45,7 +58,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
// Paper end
} else if (this.g == LoginListener.EnumProtocolState.DELAY_ACCEPT) {
- EntityPlayer entityplayer = this.server.getPlayerList().a(this.i.getId());
- EntityPlayer entityplayer = this.server.getPlayerList().getPlayer(this.i.getId());
+ EntityPlayer entityplayer = this.server.getPlayerList().getActivePlayer(this.i.getId()); // Paper
if (entityplayer == null) {
@ -54,7 +67,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
this.networkManager.sendPacket(new PacketLoginOutSuccess(this.i));
- EntityPlayer entityplayer = this.server.getPlayerList().a(this.i.getId());
- EntityPlayer entityplayer = this.server.getPlayerList().getPlayer(this.i.getId());
+ EntityPlayer entityplayer = this.server.getPlayerList().getActivePlayer(this.i.getId()); // Paper
if (entityplayer != null) {
@ -140,15 +153,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
s = bukkit.hasKeyOfType("lastKnownName", 8) ? bukkit.getString("lastKnownName") : s;
- }
+ }String lastKnownName = s; // Paper
if (nbttagcompound == null) entityplayer.moveToSpawn(worldserver); // Paper - only move to spawn on first login, otherwise, stay where you are....
// CraftBukkit end
if (nbttagcompound != null) {
@@ -0,0 +0,0 @@ public abstract class PlayerList {
entityplayer.B().a(entityplayer);
this.sendScoreboard(worldserver.getScoreboard(), entityplayer);
this.sendScoreboard(worldserver1.getScoreboard(), entityplayer);
this.server.invalidatePingSample();
+ // Paper start - async load spawn in chunk
+ WorldServer finalWorldserver = worldserver;
+ WorldServer finalWorldserver1 = worldserver1;
+ int chunkX = loc.getBlockX() >> 4;
+ int chunkZ = loc.getBlockZ() >> 4;
+ final ChunkCoordIntPair pos = new ChunkCoordIntPair(chunkX, chunkZ);
@ -165,7 +179,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }).thenAccept(chunk -> {
+ playerconnection.playerJoinReady = () -> {
+ postChunkLoadJoin(
+ entityplayer, finalWorldserver, networkmanager, playerconnection,
+ entityplayer, finalWorldserver, finalWorldserver1, networkmanager, playerconnection,
+ nbttagcompound, networkmanager.getSocketAddress().toString(), lastKnownName
+ );
+ //playerChunkMap.chunkDistanceManager.removeTicketAtLevel(TicketType.LOGIN, pos, 31, pos.pair());
@ -186,7 +200,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ });
+ }
+
+ private void postChunkLoadJoin(EntityPlayer entityplayer, WorldServer worldserver, NetworkManager networkmanager, PlayerConnection playerconnection, NBTTagCompound nbttagcompound, String s1, String s) {
+ private void postChunkLoadJoin(EntityPlayer entityplayer, WorldServer worldserver, WorldServer worldserver1, NetworkManager networkmanager, PlayerConnection playerconnection, NBTTagCompound nbttagcompound, String s1, String s) {
+ pendingPlayers.remove(entityplayer.getUniqueID(), entityplayer);
+ if (!networkmanager.isConnected()) {
+ return;
@ -196,6 +210,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
ChatMessage chatmessage;
if (entityplayer.getProfile().getName().equalsIgnoreCase(s)) {
@@ -0,0 +0,0 @@ public abstract class PlayerList {
entityplayer.supressTrackerForLogin = true;
worldserver.addPlayerJoin(entityplayer);
this.server.getBossBattleCustomData().a(entityplayer); // see commented out section below worldserver.addPlayerJoin(entityplayer);
- mountSavedVehicle(entityplayer, worldserver, nbttagcompound);
+ mountSavedVehicle(entityplayer, worldserver, worldserver1, nbttagcompound);
// Paper end
// CraftBukkit start
PlayerJoinEvent playerJoinEvent = new PlayerJoinEvent(cserver.getPlayer(entityplayer), joinMessage);
@@ -0,0 +0,0 @@ public abstract class PlayerList {
}
entityplayer.sentListPacket = true;
@ -211,7 +234,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ ((WorldServer)entityplayer.world).getChunkProvider().playerChunkMap.addEntity(entityplayer); // track entity now
onPlayerJoinFinish(entityplayer, worldserver, s1);
}
private void mountSavedVehicle(EntityPlayer entityplayer, WorldServer worldserver, NBTTagCompound nbttagcompound) {
- private void mountSavedVehicle(EntityPlayer entityplayer, WorldServer worldserver, NBTTagCompound nbttagcompound) {
+ private void mountSavedVehicle(EntityPlayer entityplayer, WorldServer worldserver, WorldServer worldserver1, NBTTagCompound nbttagcompound) {
// Paper end
if (nbttagcompound != null && nbttagcompound.hasKeyOfType("RootVehicle", 10)) {
NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("RootVehicle");
@@ -0,0 +0,0 @@ public abstract class PlayerList {
protected void savePlayerFile(EntityPlayer entityplayer) {
@ -242,7 +269,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper end
// CraftBukkit start
// this.sendAll(new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.REMOVE_PLAYER, new EntityPlayer[]{entityplayer}));
// this.sendAll(new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, new EntityPlayer[]{entityplayer}));
@@ -0,0 +0,0 @@ public abstract class PlayerList {
cserver.getScoreboardManager().removePlayer(entityplayer.getBukkitEntity());
// CraftBukkit end

View File

@ -81,17 +81,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// Paper end
- this.playerChunkMap.forEachVisibleChunk((playerchunk) -> { // Paper - safe iterator incase chunk loads, also no wrapping
+ final int[] chunksTicked = {0}; this.playerChunkMap.forEachVisibleChunk((playerchunk) -> { // Paper - safe iterator incase chunk loads, also no wrapping
Optional<Chunk> optional = ((Either) playerchunk.b().getNow(PlayerChunk.UNLOADED_CHUNK)).left();
Optional<Chunk> optional = ((Either) playerchunk.a().getNow(PlayerChunk.UNLOADED_CHUNK)).left();
if (optional.isPresent()) {
@@ -0,0 +0,0 @@ public class ChunkProviderServer extends IChunkProvider {
this.world.timings.chunkTicks.startTiming(); // Spigot // Paper
this.world.a(chunk, k);
this.world.timings.chunkTicks.stopTiming(); // Spigot // Paper
+ if (chunksTicked[0]++ % 10 == 0) this.world.getMinecraftServer().midTickLoadChunks(); // Paper
this.world.timings.chunkTicks.startTiming(); // Spigot // Paper
this.world.a(chunk, k);
this.world.timings.chunkTicks.stopTiming(); // Spigot // Paper
+ if (chunksTicked[0]++ % 10 == 0) this.world.getMinecraftServer().midTickLoadChunks(); // Paper
}
}
}
});
@@ -0,0 +0,0 @@ public class ChunkProviderServer extends IChunkProvider {
super.executeTask(runnable);
}
@ -154,7 +154,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ public boolean canSleepForTick() { // Paper
// CraftBukkit start
if (isOversleep) return canOversleep();// Paper - because of our changes, this logic is broken
return this.forceTicks || this.isEntered() || SystemUtils.getMonotonicMillis() < (this.ac ? this.ab : this.nextTick);
return this.forceTicks || this.isEntered() || SystemUtils.getMonotonicMillis() < (this.X ? this.W : this.nextTick);
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
});
}
@ -214,48 +214,48 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// Send time updates to everyone, it will get the right time from the world the player is in.
// Paper start - optimize time updates
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
this.methodProfiler.enter("tick");
this.methodProfiler.enter("tick");
try {
+ midTickLoadChunks(); // Paper
worldserver.timings.doTick.startTiming(); // Spigot
worldserver.doTick(booleansupplier);
worldserver.timings.doTick.stopTiming(); // Spigot
+ midTickLoadChunks(); // Paper
} catch (Throwable throwable) {
// Spigot Start
CrashReport crashreport;
try {
+ midTickLoadChunks(); // Paper
worldserver.timings.doTick.startTiming(); // Spigot
worldserver.doTick(booleansupplier);
worldserver.timings.doTick.stopTiming(); // Spigot
+ midTickLoadChunks(); // Paper
} catch (Throwable throwable) {
// Spigot Start
CrashReport crashreport;
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -0,0 +0,0 @@ public class WorldServer extends World {
@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed {
}
timings.scheduledBlocks.stopTiming(); // Spigot
timings.scheduledBlocks.stopTiming(); // Paper
+ this.getMinecraftServer().midTickLoadChunks(); // Paper
gameprofilerfiller.exitEnter("raid");
this.timings.raids.startTiming(); // Paper - timings
this.persistentRaid.a();
@@ -0,0 +0,0 @@ public class WorldServer extends World {
@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed {
timings.doSounds.startTiming(); // Spigot
this.ad();
this.ah();
timings.doSounds.stopTiming(); // Spigot
+ this.getMinecraftServer().midTickLoadChunks(); // Paper
this.ticking = false;
gameprofilerfiller.exitEnter("entities");
boolean flag3 = true || !this.players.isEmpty() || !this.getForceLoadedChunks().isEmpty(); // CraftBukkit - this prevents entity cleanup, other issues on servers with no players
@@ -0,0 +0,0 @@ public class WorldServer extends World {
@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed {
timings.entityTick.stopTiming(); // Spigot
this.tickingEntities = false;
+ this.getMinecraftServer().midTickLoadChunks(); // Paper
try (co.aikar.timings.Timing ignored = this.timings.newEntities.startTiming()) { // Paper - timings
while ((entity = (Entity) this.entitiesToAdd.poll()) != null) {
@@ -0,0 +0,0 @@ public class WorldServer extends World {
Entity entity2;
@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed {
}
gameprofilerfiller.exit();
timings.tickEntities.stopTiming(); // Spigot
+ this.getMinecraftServer().midTickLoadChunks(); // Paper
this.tickBlockEntities();

View File

@ -15,13 +15,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
- if (bworld == null) {
- bworld = ((org.bukkit.craftbukkit.CraftServer) server).getServer().getWorldServer(DimensionManager.OVERWORLD).getWorld();
- bworld = ((org.bukkit.craftbukkit.CraftServer) server).getServer().getWorldServer(World.OVERWORLD).getWorld();
- }
+ // Paper start - Move player to spawn point if spawn in unloaded world
+ // if (bworld == null) {
+ // bworld = ((org.bukkit.craftbukkit.CraftServer) server).getServer().getWorldServer(DimensionManager.OVERWORLD).getWorld();
+ // }
+ // Paper end
+// if (bworld == null) {
+// bworld = ((org.bukkit.craftbukkit.CraftServer) server).getServer().getWorldServer(World.OVERWORLD).getWorld();
+// }
+ // Paper end - Move player to spawn point if spawn in unloaded world
spawnIn(bworld == null ? null : ((CraftWorld) bworld).getHandle());
}

View File

@ -113,7 +113,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ Ticket<?> ticket = new Ticket<>(TicketType.PLAYER, 33, new ChunkCoordIntPair(i)); // Paper - no-tick view distance
if (flag1) {
ChunkMapDistance.this.j.a(ChunkTaskQueueSorter.a(() -> { // CraftBukkit - decompile error
ChunkMapDistance.this.j.a(ChunkTaskQueueSorter.a(() -> {
diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/EntityPlayer.java
@ -125,8 +125,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ boolean needsChunkCenterUpdate; // Paper - no-tick view distance
+
public EntityPlayer(MinecraftServer minecraftserver, WorldServer worldserver, GameProfile gameprofile, PlayerInteractManager playerinteractmanager) {
super((World) worldserver, gameprofile);
playerinteractmanager.player = this;
super(worldserver, worldserver.getSpawn(), gameprofile);
this.spawnDimension = World.OVERWORLD;
diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/PlayerChunk.java
@ -306,7 +306,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ player.needsChunkCenterUpdate = false;
+ // Paper end - no-tick view distance
}
// Paper end
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
}
@ -367,18 +367,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return Either.left(chunk);
});
}, (runnable) -> {
- this.mailboxMain.a(ChunkTaskQueueSorter.a(playerchunk, runnable)); // CraftBukkit - decompile error
+ this.mailboxMain.a(ChunkTaskQueueSorter.a(playerchunk, runnable)); // CraftBukkit - decompile error // Paper - diff on change, this is the scheduling method copied in Chunk used to schedule chunk broadcasts (on change it needs to be copied again)
- this.mailboxMain.a(ChunkTaskQueueSorter.a(playerchunk, runnable));
+ this.mailboxMain.a(ChunkTaskQueueSorter.a(playerchunk, runnable)); // Paper - diff on change, this is the scheduling method copied in Chunk used to schedule chunk broadcasts (on change it needs to be copied again)
});
return completablefuture1;
}
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
} // Paper
}
- protected void setViewDistance(int i) {
protected void setViewDistance(int i) {
- int j = MathHelper.clamp(i + 1, 3, 33);
+ public final void setViewDistance(int i) { // Paper - public
+ int j = MathHelper.clamp(i + 1, 3, 33); // Paper - diff on change, these make the lower view distance limit 2 and the upper 32
if (j != this.viewDistance) {
@ -501,7 +499,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return Stream.empty();
+ }
+ // all current cases are inlined so we wont hit this code, it's just in case plugins or future updates use it
+ List<EntityPlayer> players = new ArrayList<>();
+ List<EntityPlayer> players = new java.util.ArrayList<>();
+ Object[] backingSet = inRange.getBackingSet();
+
+ if (flag) { // flag -> border only
@ -542,7 +540,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ final void sendChunk(EntityPlayer entityplayer, Packet<?>[] apacket, Chunk chunk) { this.a(entityplayer, apacket, chunk); } // Paper - OBFHELPER
private void a(EntityPlayer entityplayer, Packet<?>[] apacket, Chunk chunk) {
if (apacket[0] == null) {
apacket[0] = new PacketPlayOutMapChunk(chunk, 65535);
apacket[0] = new PacketPlayOutMapChunk(chunk, 65535, true);
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(this.tracker.chunkX, this.tracker.chunkZ);
PlayerChunk playerchunk = PlayerChunkMap.this.getVisibleChunk(chunkcoordintpair.pair());
@ -557,23 +555,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/PlayerList.java
+++ b/src/main/java/net/minecraft/server/PlayerList.java
@@ -0,0 +0,0 @@ public abstract class PlayerList {
// CraftBukkit - getType()
// Spigot - view distance
networkmanager.queueImmunity = true; // Paper
- playerconnection.sendPacket(new PacketPlayOutLogin(entityplayer.getId(), entityplayer.playerInteractManager.getGameMode(), WorldData.c(worlddata.getSeed()), worlddata.isHardcore(), worldserver.worldProvider.getDimensionManager().getType(), this.getMaxPlayers(), worlddata.getType(), worldserver.spigotConfig.viewDistance, flag1, !flag));
+ playerconnection.sendPacket(new PacketPlayOutLogin(entityplayer.getId(), entityplayer.playerInteractManager.getGameMode(), WorldData.c(worlddata.getSeed()), worlddata.isHardcore(), worldserver.worldProvider.getDimensionManager().getType(), this.getMaxPlayers(), worlddata.getType(), worldserver.getChunkProvider().playerChunkMap.getLoadViewDistance(), flag1, !flag)); // Paper - no-tick view distance
- playerconnection.sendPacket(new PacketPlayOutLogin(entityplayer.getId(), entityplayer.playerInteractManager.getGameMode(), entityplayer.playerInteractManager.c(), BiomeManager.a(worldserver1.getSeed()), worlddata.isHardcore(), this.server.E(), this.s, worldserver1.getTypeKey(), worldserver1.getDimensionKey(), this.getMaxPlayers(), worldserver.spigotConfig.viewDistance, flag1, !flag, worldserver1.isDebugWorld(), worldserver1.isFlatWorld()));
+ playerconnection.sendPacket(new PacketPlayOutLogin(entityplayer.getId(), entityplayer.playerInteractManager.getGameMode(), entityplayer.playerInteractManager.c(), BiomeManager.a(worldserver1.getSeed()), worlddata.isHardcore(), this.server.E(), this.s, worldserver1.getTypeKey(), worldserver1.getDimensionKey(), this.getMaxPlayers(), worldserver1.getChunkProvider().playerChunkMap.getLoadViewDistance(), flag1, !flag, worldserver1.isDebugWorld(), worldserver1.isFlatWorld())); // Paper - no-tick view distance
entityplayer.getBukkitEntity().sendSupportedChannels(); // CraftBukkit
playerconnection.sendPacket(new PacketPlayOutCustomPayload(PacketPlayOutCustomPayload.a, (new PacketDataSerializer(Unpooled.buffer())).a(this.getServer().getServerModName())));
playerconnection.sendPacket(new PacketPlayOutServerDifficulty(worlddata.getDifficulty(), worlddata.isDifficultyLocked()));
@@ -0,0 +0,0 @@ public abstract class PlayerList {
WorldData worlddata = worldserver.getWorldData();
entityplayer1.playerConnection.sendPacket(new PacketPlayOutRespawn(worldserver.worldProvider.getDimensionManager().getType(), WorldData.c(worldserver.getWorldData().getSeed()), worldserver.getWorldData().getType(), entityplayer1.playerInteractManager.getGameMode()));
- entityplayer1.playerConnection.sendPacket(new PacketPlayOutViewDistance(worldserver.spigotConfig.viewDistance)); // Spigot
+ entityplayer1.playerConnection.sendPacket(new PacketPlayOutViewDistance(worldserver.getChunkProvider().playerChunkMap.getLoadViewDistance())); // Paper - no-tick view distance
entityplayer1.spawnIn(worldserver);
// CraftBukkit start
WorldData worlddata = worldserver1.getWorldData();
entityplayer1.playerConnection.sendPacket(new PacketPlayOutRespawn(worldserver1.getTypeKey(), worldserver1.getDimensionKey(), BiomeManager.a(worldserver1.getSeed()), entityplayer1.playerInteractManager.getGameMode(), entityplayer1.playerInteractManager.c(), worldserver1.isDebugWorld(), worldserver1.isFlatWorld(), flag));
- entityplayer1.playerConnection.sendPacket(new PacketPlayOutViewDistance(worldserver1.spigotConfig.viewDistance)); // Spigot
+ entityplayer1.playerConnection.sendPacket(new PacketPlayOutViewDistance(worldserver1.getChunkProvider().playerChunkMap.getLoadViewDistance())); // Spigot // Paper - no-tick view distance
entityplayer1.spawnIn(worldserver1);
entityplayer1.dead = false;
entityplayer1.playerConnection.teleport(new Location(worldserver.getWorld(), entityplayer1.locX(), entityplayer1.locY(), entityplayer1.locZ(), entityplayer1.yaw, entityplayer1.pitch));
entityplayer1.playerConnection.teleport(new Location(worldserver1.getWorld(), entityplayer1.locX(), entityplayer1.locY(), entityplayer1.locZ(), entityplayer1.yaw, entityplayer1.pitch));
@@ -0,0 +0,0 @@ public abstract class PlayerList {
public void a(int i) {

View File

@ -27,7 +27,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ }
+
+ public final void getHardCollidingEntities(@Nullable Entity entity, AxisAlignedBB axisalignedbb, List<Entity> into) {
+ public final void getHardCollidingEntities(@Nullable Entity entity, AxisAlignedBB axisalignedbb, List<Entity> into, Predicate<Entity> predicate) {
+ // copied from getEntities
+ int min = MathHelper.floor((axisalignedbb.minY - 2.0D) / 16.0D);
+ int max = MathHelper.floor((axisalignedbb.maxY + 2.0D) / 16.0D);
@ -43,7 +43,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ Entity entity1 = entities[i];
+ if (entity1.shouldBeRemoved) continue; // Paper
+
+ if (entity1 != entity && entity1.getBoundingBox().intersects(axisalignedbb)) {
+ if (entity1 != entity && entity1.getBoundingBox().intersects(axisalignedbb) && (predicate == null || predicate.test(entity1))) {
+ into.add(entity1);
+
+ if (!(entity1 instanceof EntityEnderDragon)) {
@ -56,7 +56,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ for (int i1 = 0; i1 < l; ++i1) {
+ EntityComplexPart entitycomplexpart = aentitycomplexpart[i1];
+
+ if (entitycomplexpart != entity && entitycomplexpart.getBoundingBox().intersects(axisalignedbb)) {
+ if (entitycomplexpart != entity && entitycomplexpart.getBoundingBox().intersects(axisalignedbb) && (predicate == null || predicate.test(entitycomplexpart))) {
+ into.add(entitycomplexpart);
+ }
+ }
@ -106,9 +106,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ Boolean hardCollides = cachedOverrides.get(this.getClass());
+ if (hardCollides == null) {
+ try {
+ Object getHardCollisionBoxMethod = Entity.class.getMethod("au");
+ Object getHardCollisionBoxMethod = Entity.class.getMethod("ay");
+ Object getHardCollisionBoxEntityMethod = Entity.class.getMethod("j", Entity.class);
+ if (!this.getClass().getMethod("au").equals(getHardCollisionBoxMethod)) {
+ if (!this.getClass().getMethod("ay").equals(getHardCollisionBoxMethod)) {
+ hardCollides = Boolean.TRUE;
+ } else if (!this.getClass().getMethod("j", Entity.class).equals(getHardCollisionBoxEntityMethod)) {
+ hardCollides = Boolean.TRUE;
@ -140,8 +140,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override
public void checkDespawn() {}
+ public final EntityComplexPart[] getComplexParts() { return this.eo(); } // Paper - OBFHELPER
public EntityComplexPart[] eo() {
+ public final EntityComplexPart[] getComplexParts() { return this.eK(); } // Paper - OBFHELPER
public EntityComplexPart[] eK() {
return this.children;
}
diff --git a/src/main/java/net/minecraft/server/IEntityAccess.java b/src/main/java/net/minecraft/server/IEntityAccess.java
@ -149,34 +149,46 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/IEntityAccess.java
+++ b/src/main/java/net/minecraft/server/IEntityAccess.java
@@ -0,0 +0,0 @@ public interface IEntityAccess {
return this.b(oclass, axisalignedbb, IEntitySelector.f);
return this.b(oclass, axisalignedbb, IEntitySelector.g);
}
+ // Paper start - optimise hard collision
+ /**
+ * Not guaranteed to only return hard colliding entites
+ */
+ default List<Entity> getHardCollidingEntities(@Nullable Entity entity, AxisAlignedBB axisalignedbb) {
+ default List<Entity> getHardCollidingEntities(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Predicate<Entity> predicate) {
+ return this.getEntities(entity, axisalignedbb);
+ }
+ // Paper end - optimise hard collision
+
default Stream<VoxelShape> b(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set<Entity> set) {
default Stream<VoxelShape> c(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Predicate<Entity> predicate) {
if (axisalignedbb.a() < 1.0E-7D) {
return Stream.empty();
} else {
AxisAlignedBB axisalignedbb1 = axisalignedbb.g(1.0E-7D);
- Stream<AxisAlignedBB> stream = this.getEntities(entity, axisalignedbb1).stream().filter((entity1) -> { // Paper - decompile fix
+ Stream<AxisAlignedBB> stream = ((entity != null && entity.hardCollides()) ? this.getEntities(entity, axisalignedbb) : this.getHardCollidingEntities(entity, axisalignedbb1)).stream().filter((entity1) -> { // Paper - decompile fix // Paper - optimise hard collision
return !set.contains(entity1);
}).filter((entity1) -> {
return entity == null || !entity.isSameVehicle(entity1);
}).flatMap((entity1) -> {
- return Stream.of(entity1.au(), entity == null ? null : entity.j(entity1));
+ return Stream.of(entity1.au(), entity == null ? null : entity.j(entity1)); // Paper - optimise hard collision - diff on change, these are the methods that only hard colliding entities override
}).filter(Objects::nonNull);
return stream.filter(axisalignedbb1::c).map(VoxelShapes::a);
- return this.getEntities(entity, axisalignedbb1, predicate.and((entity1) -> {
+ // Paper start
+ Predicate<Entity> effectivePredicate = predicate.and((entity1) -> {
return entity == null || !entity.isSameVehicle(entity1);
- })).stream().flatMap((entity1) -> {
+ });
+
+ return ((entity != null && entity.hardCollides()) ? this.getEntities(entity, axisalignedbb, effectivePredicate) : this.getHardCollidingEntities(entity, axisalignedbb1, effectivePredicate)).stream().flatMap((entity1) -> {
if (entity != null) {
- AxisAlignedBB axisalignedbb2 = entity.j(entity1);
+ AxisAlignedBB axisalignedbb2 = entity.j(entity1); // Paper - diff on change, hard collision box method
if (axisalignedbb2 != null && axisalignedbb2.c(axisalignedbb1)) {
return Stream.of(entity1.ay(), axisalignedbb2);
}
}
- return Stream.of(entity1.ay());
+ return Stream.of(entity1.ay()); // Paper - diff on change, hard collision box method
}).filter(Objects::nonNull).map(VoxelShapes::a);
}
}
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/World.java
@ -187,7 +199,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper start - optimise hard collision handling
+ @Override
+ public List<Entity> getHardCollidingEntities(@Nullable Entity entity, AxisAlignedBB axisalignedbb) {
+ public List<Entity> getHardCollidingEntities(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Predicate<Entity> predicate) {
+ // copied from below
+ List<Entity> list = Lists.newArrayList();
+ int i = MathHelper.floor((axisalignedbb.minX - 2.0D) / 16.0D);
@ -195,14 +207,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ int k = MathHelper.floor((axisalignedbb.minZ - 2.0D) / 16.0D);
+ int l = MathHelper.floor((axisalignedbb.maxZ + 2.0D) / 16.0D);
+
+ ChunkProviderServer chunkProvider = ((ChunkProviderServer)this.chunkProvider);
+ ChunkProviderServer chunkProvider = ((WorldServer)this).getChunkProvider();
+
+ for (int i1 = i; i1 <= j; ++i1) {
+ for (int j1 = k; j1 <= l; ++j1) {
+ Chunk chunk = chunkProvider.getChunkAtIfLoadedMainThread(i1, j1);
+
+ if (chunk != null) {
+ chunk.getHardCollidingEntities(entity, axisalignedbb, list);
+ chunk.getHardCollidingEntities(entity, axisalignedbb, list, predicate);
+ }
+ }
+ }

View File

@ -18,7 +18,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override public boolean a(Entity entity) {
- long i = ChunkCoordIntPair.pair(MathHelper.floor(entity.locX()) >> 4, MathHelper.floor(entity.locZ()) >> 4);
-
- return this.a(i, PlayerChunk::b);
- return this.a(i, (Function<PlayerChunk, CompletableFuture<Either<Chunk, PlayerChunk.Failure>>>) PlayerChunk::b); // CraftBukkit - decompile error
+ // Paper start - optimize is ticking ready type functions
+ // entity ticking
+ PlayerChunk playerChunk = this.getChunk(MCUtil.getCoordinateKey(entity));
@ -28,7 +28,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public final boolean isEntityTickingChunk(ChunkCoordIntPair chunkcoordintpair) { return this.a(chunkcoordintpair); } // Paper - OBFHELPER
@Override public boolean a(ChunkCoordIntPair chunkcoordintpair) {
- return this.a(chunkcoordintpair.pair(), PlayerChunk::b);
- return this.a(chunkcoordintpair.pair(), (Function<PlayerChunk, CompletableFuture<Either<Chunk, PlayerChunk.Failure>>>) PlayerChunk::b); // CraftBukkit - decompile error
+ // Paper start - optimize is ticking ready type functions
+ // is entity ticking ready
+ PlayerChunk playerChunk = this.getChunk(MCUtil.getCoordinateKey(chunkcoordintpair));
@ -40,7 +40,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public boolean a(BlockPosition blockposition) {
- long i = ChunkCoordIntPair.pair(blockposition.getX() >> 4, blockposition.getZ() >> 4);
-
- return this.a(i, PlayerChunk::a);
- return this.a(i, (Function<PlayerChunk, CompletableFuture<Either<Chunk, PlayerChunk.Failure>>>) PlayerChunk::a); // CraftBukkit - decompile error
+ // Paper start - optimize is ticking ready type functions
+ // is ticking ready
+ PlayerChunk playerChunk = this.getChunk(MCUtil.getCoordinateKey(blockposition));
@ -48,15 +48,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper end - optimize is ticking ready type functions
}
public boolean b(Entity entity) {
- long i = ChunkCoordIntPair.pair(MathHelper.floor(entity.locX()) >> 4, MathHelper.floor(entity.locZ()) >> 4);
-
- return this.a(i, PlayerChunk::c);
+ // Paper start - optimize is ticking ready type functions
+ // is full chunk ready
+ PlayerChunk playerChunk = this.getChunk(MCUtil.getCoordinateKey(entity));
+ return playerChunk != null && playerChunk.isFullChunkReady();
+ // Paper end - optimize is ticking ready type functions
}
private boolean a(long i, Function<PlayerChunk, CompletableFuture<Either<Chunk, PlayerChunk.Failure>>> function) {

View File

@ -32,57 +32,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public interface ICollisionAccess extends IBlockAccess {
}
default boolean a(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set<Entity> set) {
default boolean b(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Predicate<Entity> predicate) {
+ try { if (entity != null) entity.collisionLoadChunks = true; // Paper
return this.c(entity, axisalignedbb, set).allMatch(VoxelShape::isEmpty);
return this.d(entity, axisalignedbb, predicate).allMatch(VoxelShape::isEmpty);
+ } finally { if (entity != null) entity.collisionLoadChunks = false; } // Paper
}
default Stream<VoxelShape> b(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Set<Entity> set) {
@@ -0,0 +0,0 @@ public interface ICollisionAccess extends IBlockAccess {
}
while (cursorposition.a()) {
- int k1 = cursorposition.b();
- int l1 = cursorposition.c();
- int i2 = cursorposition.d();
+ int k1 = cursorposition.b();int x = k1; // Paper
+ int l1 = cursorposition.c();int y = l1; // Paper
+ int i2 = cursorposition.d();int z = i2; // Paper
int j2 = cursorposition.e();
if (j2 != 3) {
- int k2 = k1 >> 4;
- int l2 = i2 >> 4;
- IBlockAccess iblockaccess = ICollisionAccess.this.c(k2, l2);
-
- if (iblockaccess != null) {
- blockposition_mutableblockposition.d(k1, l1, i2);
- IBlockData iblockdata = iblockaccess.getType(blockposition_mutableblockposition);
+ // Paper start - ensure we don't load chunks
+ //int k2 = k1 >> 4;
+ //int l2 = i2 >> 4;
+ boolean far = entity != null && MCUtil.distanceSq(entity.locX(), y, entity.locZ(), x, y, z) > 14;
+ blockposition_mutableblockposition.setValues(x, y, z);
+
+ boolean isRegionLimited = ICollisionAccess.this instanceof RegionLimitedWorldAccess;
+ IBlockData iblockdata = isRegionLimited ? Blocks.VOID_AIR.getBlockData() : ((!far && entity instanceof EntityPlayer) || (entity != null && entity.collisionLoadChunks)
+ ? ICollisionAccess.this.getType(blockposition_mutableblockposition)
+ : ICollisionAccess.this.getTypeIfLoaded(blockposition_mutableblockposition)
+ );
+ if (iblockdata == null) {
+ if (!(entity instanceof EntityPlayer) || entity.world.paperConfig.preventMovingIntoUnloadedChunks) {
+ VoxelShape voxelshape3 = VoxelShapes.of(far ? entity.getBoundingBox() : new AxisAlignedBB(new BlockPosition(x, y, z)));
+ consumer.accept(voxelshape3);
+ return true;
+ }
+ } else {
+ //blockposition_mutableblockposition.d(k1, l1, i2); // moved up
+ //IBlockData iblockdata = iblockaccess.getType(blockposition_mutableblockposition); // moved up
+ // Paper end
if ((j2 != 1 || iblockdata.f()) && (j2 != 2 || iblockdata.getBlock() == Blocks.MOVING_PISTON)) {
VoxelShape voxelshape2 = iblockdata.b((IBlockAccess) ICollisionAccess.this, blockposition_mutableblockposition, voxelshapecollision);
Stream<VoxelShape> c(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Predicate<Entity> predicate);
diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/PlayerList.java
@ -92,9 +48,77 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// CraftBukkit end
+ worldserver.getChunkProvider().addTicket(TicketType.POST_TELEPORT, new ChunkCoordIntPair(location.getBlockX() >> 4, location.getBlockZ() >> 4), 1, entityplayer.getId()); // Paper
while (avoidSuffocation && !worldserver.getCubes(entityplayer1) && entityplayer1.locY() < 256.0D) {
while (avoidSuffocation && !worldserver1.getCubes(entityplayer1) && entityplayer1.locY() < 256.0D) {
entityplayer1.setPosition(entityplayer1.locX(), entityplayer1.locY() + 1.0D, entityplayer1.locZ());
}
diff --git a/src/main/java/net/minecraft/server/VoxelShapeSpliterator.java b/src/main/java/net/minecraft/server/VoxelShapeSpliterator.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/VoxelShapeSpliterator.java
+++ b/src/main/java/net/minecraft/server/VoxelShapeSpliterator.java
@@ -0,0 +0,0 @@ import javax.annotation.Nullable;
public class VoxelShapeSpliterator extends AbstractSpliterator<VoxelShape> {
@Nullable
- private final Entity a;
+ private final Entity a; final Entity getEntity() { return this.a; } // Paper - OBFHELPER
private final AxisAlignedBB b;
private final VoxelShapeCollision c;
private final CursorPosition d;
- private final BlockPosition.MutableBlockPosition e;
+ private final BlockPosition.MutableBlockPosition e; final BlockPosition.MutableBlockPosition getMutablePos() { return this.e; } // Paper - OBFHELPER
private final VoxelShape f;
- private final ICollisionAccess g;
+ private final ICollisionAccess g; final ICollisionAccess getCollisionAccess() { return this.g; } // Paper - OBFHELPER
private boolean h;
private final BiPredicate<IBlockData, BlockPosition> i;
@@ -0,0 +0,0 @@ public class VoxelShapeSpliterator extends AbstractSpliterator<VoxelShape> {
boolean a(Consumer<? super VoxelShape> consumer) {
while (true) {
if (this.d.a()) {
- int i = this.d.b();
- int j = this.d.c();
- int k = this.d.d();
+ int i = this.d.b(); final int x = i;
+ int j = this.d.c(); final int y = j;
+ int k = this.d.d(); final int z = k;
int l = this.d.e();
if (l == 3) {
continue;
}
- IBlockAccess iblockaccess = this.a(i, k);
-
- if (iblockaccess == null) {
+ // Paper start - ensure we don't load chunks
+ Entity entity = this.getEntity();
+ BlockPosition.MutableBlockPosition blockposition_mutableblockposition = this.getMutablePos();
+ boolean far = entity != null && MCUtil.distanceSq(entity.locX(), y, entity.locZ(), x, y, z) > 14;
+ blockposition_mutableblockposition.setValues(x, y, z);
+
+ boolean isRegionLimited = this.getCollisionAccess() instanceof RegionLimitedWorldAccess;
+ IBlockData iblockdata = isRegionLimited ? Blocks.VOID_AIR.getBlockData() : ((!far && entity instanceof EntityPlayer) || (entity != null && entity.collisionLoadChunks)
+ ? this.getCollisionAccess().getType(blockposition_mutableblockposition)
+ : this.getCollisionAccess().getTypeIfLoaded(blockposition_mutableblockposition)
+ );
+
+ if (iblockdata == null) {
+ if (!(entity instanceof EntityPlayer) || entity.world.paperConfig.preventMovingIntoUnloadedChunks) {
+ VoxelShape voxelshape3 = VoxelShapes.of(far ? entity.getBoundingBox() : new AxisAlignedBB(new BlockPosition(x, y, z)));
+ consumer.accept(voxelshape3);
+ return true;
+ }
continue;
}
-
- this.e.d(i, j, k);
- IBlockData iblockdata = iblockaccess.getType(this.e);
+ // Paper - moved up
+ // Paper end
if (!this.i.test(iblockdata, this.e) || l == 1 && !iblockdata.d() || l == 2 && !iblockdata.a(Blocks.MOVING_PISTON)) {
continue;
diff --git a/src/main/java/net/minecraft/server/VoxelShapes.java b/src/main/java/net/minecraft/server/VoxelShapes.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/VoxelShapes.java
@ -107,5 +131,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ IBlockData iblockdata = iworldreader.getTypeIfLoaded(blockposition_mutableblockposition); // Paper
+ if (iblockdata == null) return 0.0D; // Paper
if ((k2 != 1 || iblockdata.f()) && (k2 != 2 || iblockdata.getBlock() == Blocks.MOVING_PISTON)) {
if ((k2 != 1 || iblockdata.d()) && (k2 != 2 || iblockdata.a(Blocks.MOVING_PISTON))) {
d0 = iblockdata.b((IBlockAccess) iworldreader, blockposition_mutableblockposition, voxelshapecollision).a(enumdirection_enumaxis2, axisalignedbb.d((double) (-blockposition_mutableblockposition.getX()), (double) (-blockposition_mutableblockposition.getY()), (double) (-blockposition_mutableblockposition.getZ())), d0);

View File

@ -17,8 +17,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- protected PathEntity c;
+ protected PathEntity c; protected final PathEntity getCurrentPath() { return this.c; } // Paper - OBFHELPER
protected double d;
private final AttributeInstance p;
protected int e;
protected int f;
@@ -0,0 +0,0 @@ public abstract class NavigationAbstract {
return this.a(this.a(d0, d1, d2, 1), d3);
}

View File

@ -64,9 +64,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
entityPlayer.playerNaturallySpawnedEvent.callEvent();
};
// Paper end
- this.playerChunkMap.f().forEach((playerchunk) -> {
- this.playerChunkMap.f().forEach((playerchunk) -> { // Paper - no... just no...
+ this.playerChunkMap.forEachVisibleChunk((playerchunk) -> { // Paper - safe iterator incase chunk loads, also no wrapping
Optional<Chunk> optional = ((Either) playerchunk.b().getNow(PlayerChunk.UNLOADED_CHUNK)).left();
Optional<Chunk> optional = ((Either) playerchunk.a().getNow(PlayerChunk.UNLOADED_CHUNK)).left();
if (optional.isPresent()) {
diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java
@ -124,8 +124,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public final WorldServer world;
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
public PlayerChunkMap(WorldServer worldserver, File file, DataFixer datafixer, DefinedStructureManager definedstructuremanager, Executor executor, IAsyncTaskHandler<Runnable> iasynctaskhandler, ILightAccess ilightaccess, ChunkGenerator<?> chunkgenerator, WorldLoadListener worldloadlistener, Supplier<WorldPersistentData> supplier, int i) {
super(new File(worldserver.getWorldProvider().getDimensionManager().a(file), "region"), datafixer);
public PlayerChunkMap(WorldServer worldserver, Convertable.ConversionSession convertable_conversionsession, DataFixer datafixer, DefinedStructureManager definedstructuremanager, Executor executor, IAsyncTaskHandler<Runnable> iasynctaskhandler, ILightAccess ilightaccess, ChunkGenerator chunkgenerator, WorldLoadListener worldloadlistener, Supplier<WorldPersistentData> supplier, int i, boolean flag) {
super(new File(convertable_conversionsession.a(worldserver.getDimensionKey()), "region"), datafixer, flag);
- this.visibleChunks = this.updatingChunks.clone();
+ //this.visibleChunks = this.updatingChunks.clone(); // Paper - no more cloning
this.pendingUnload = new Long2ObjectLinkedOpenHashMap();

View File

@ -12,9 +12,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public abstract class ChunkMapDistance {
private final Long2ObjectMap<ObjectSet<EntityPlayer>> c = new Long2ObjectOpenHashMap();
public final Long2ObjectOpenHashMap<ArraySetSorted<Ticket<?>>> tickets = new Long2ObjectOpenHashMap();
private final ChunkMapDistance.a e = new ChunkMapDistance.a();
private final ChunkMapDistance.a ticketLevelTracker = new ChunkMapDistance.a();
- private final ChunkMapDistance.b f = new ChunkMapDistance.b(8);
+ public static final int MOB_SPAWN_RANGE = 8; //private final ChunkMapDistance.b f = new ChunkMapDistance.b(8); // Paper - no longer used
+ public static final int MOB_SPAWN_RANGE = 8; // private final ChunkMapDistance.b f = new ChunkMapDistance.b(8); // Paper - no longer used
private final ChunkMapDistance.c g = new ChunkMapDistance.c(33);
// Paper start use a queue, but still keep unique requirement
public final java.util.Queue<PlayerChunk> pendingChunkUpdates = new java.util.ArrayDeque<PlayerChunk>() {
@ -34,24 +34,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- this.f.a();
+ //this.f.a(); // Paper - no longer used
this.g.a();
int i = Integer.MAX_VALUE - this.e.a(Integer.MAX_VALUE);
int i = Integer.MAX_VALUE - this.ticketLevelTracker.a(Integer.MAX_VALUE);
boolean flag = i != 0;
@@ -0,0 +0,0 @@ public abstract class ChunkMapDistance {
((ObjectSet) this.c.computeIfAbsent(i, (j) -> {
return new ObjectOpenHashSet();
})).add(entityplayer);
- this.f.b(i, 0, true);
+ //this.f.b(i, 0, true); // Paper - no longer used
this.g.b(i, 0, true);
- this.f.update(i, 0, true);
+ //this.f.update(i, 0, true); // Paper - no longer used
this.g.update(i, 0, true);
}
@@ -0,0 +0,0 @@ public abstract class ChunkMapDistance {
if (objectset != null) objectset.remove(entityplayer); // Paper - some state corruption happens here, don't crash, clean up gracefully.
if (objectset == null || objectset.isEmpty()) { // Paper
this.c.remove(i);
- this.f.b(i, Integer.MAX_VALUE, false);
+ //this.f.b(i, Integer.MAX_VALUE, false); // Paper - no longer used
this.g.b(i, Integer.MAX_VALUE, false);
- this.f.update(i, Integer.MAX_VALUE, false);
+ //this.f.update(i, Integer.MAX_VALUE, false); // Paper - no longer used
this.g.update(i, Integer.MAX_VALUE, false);
}
@@ -0,0 +0,0 @@ public abstract class ChunkMapDistance {
@ -116,37 +116,36 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper end - optimize isOutisdeRange
this.world.getMethodProfiler().enter("pollingChunks");
int k = this.world.getGameRules().getInt(GameRules.RANDOM_TICK_SPEED);
BlockPosition blockposition = this.world.getSpawn();
boolean flag2 = world.ticksPerAnimalSpawns != 0L && worlddata.getTime() % world.ticksPerAnimalSpawns == 0L; // CraftBukkit
@@ -0,0 +0,0 @@ public class ChunkProviderServer extends IChunkProvider {
this.world.timings.countNaturalMobs.stopTiming(); // Paper - timings
this.world.getMethodProfiler().exit();
//List<PlayerChunk> list = Lists.newArrayList(this.playerChunkMap.f()); // Paper
//Collections.shuffle(list); // Paper
- //Paper start - call player naturally spawn event
- int chunkRange = world.spigotConfig.mobSpawnRange;
- chunkRange = (chunkRange > world.spigotConfig.viewDistance) ? (byte) world.spigotConfig.viewDistance : chunkRange;
- chunkRange = Math.min(chunkRange, 8);
- for (EntityPlayer entityPlayer : this.world.players) {
- for (EntityPlayer entityPlayer : this.world.getPlayers()) {
- entityPlayer.playerNaturallySpawnedEvent = new com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent(entityPlayer.getBukkitEntity(), (byte) chunkRange);
- entityPlayer.playerNaturallySpawnedEvent.callEvent();
- };
- // Paper end
+ // Paper - replaced by above
+ // Paper - moved up
final int[] chunksTicked = {0}; this.playerChunkMap.forEachVisibleChunk((playerchunk) -> { // Paper - safe iterator incase chunk loads, also no wrapping
Optional<Chunk> optional = ((Either) playerchunk.b().getNow(PlayerChunk.UNLOADED_CHUNK)).left();
Optional<Chunk> optional = ((Either) playerchunk.a().getNow(PlayerChunk.UNLOADED_CHUNK)).left();
@@ -0,0 +0,0 @@ public class ChunkProviderServer extends IChunkProvider {
this.world.getMethodProfiler().exit();
ChunkCoordIntPair chunkcoordintpair = playerchunk.i();
Chunk chunk = (Chunk) optional1.get();
ChunkCoordIntPair chunkcoordintpair = playerchunk.i();
- if (!this.playerChunkMap.isOutsideOfRange(chunkcoordintpair)) {
+ if (!this.playerChunkMap.isOutsideOfRange(playerchunk, chunkcoordintpair, false)) { // Paper - optimise isOutsideOfRange
chunk.setInhabitedTime(chunk.getInhabitedTime() + j);
- if (flag1 && (this.allowMonsters || this.allowAnimals) && this.world.getWorldBorder().isInBounds(chunk.getPos()) && !this.playerChunkMap.isOutsideOfRange(chunkcoordintpair, true)) { // Spigot
+ if (flag1 && (this.allowMonsters || this.allowAnimals) && this.world.getWorldBorder().isInBounds(chunk.getPos()) && !this.playerChunkMap.isOutsideOfRange(playerchunk, chunkcoordintpair, true)) { // Spigot // Paper - optimise isOutsideOfRange
SpawnerCreature.a(this.world, chunk, spawnercreature_d, this.allowAnimals, this.allowMonsters, flag2);
}
- if (!this.playerChunkMap.isOutsideOfRange(chunkcoordintpair)) {
+ if (!this.playerChunkMap.isOutsideOfRange(playerchunk, chunkcoordintpair, false)) { // Paper - optimise isOutsideOfRange
// Paper end
chunk.setInhabitedTime(chunk.getInhabitedTime() + j);
- if (flag1 && (this.allowMonsters || this.allowAnimals) && this.world.getWorldBorder().isInBounds(chunk.getPos()) && !this.playerChunkMap.isOutsideOfRange(chunkcoordintpair, true)) { // Spigot
+ if (flag1 && (this.allowMonsters || this.allowAnimals) && this.world.getWorldBorder().isInBounds(chunk.getPos()) && !this.playerChunkMap.isOutsideOfRange(playerchunk, chunkcoordintpair, true)) { // Spigot // Paper - optimise isOutsideOfRange
this.world.getMethodProfiler().enter("spawner");
this.world.timings.mobSpawn.startTiming(); // Spigot
EnumCreatureType[] aenumcreaturetype1 = aenumcreaturetype;
diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/EntityPlayer.java
@ -158,8 +157,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ double lastEntitySpawnRadiusSquared; // Paper - optimise isOutsideRange, this field is in blocks
+
public EntityPlayer(MinecraftServer minecraftserver, WorldServer worldserver, GameProfile gameprofile, PlayerInteractManager playerinteractmanager) {
super((World) worldserver, gameprofile);
playerinteractmanager.player = this;
super(worldserver, worldserver.getSpawn(), gameprofile);
this.spawnDimension = World.OVERWORLD;
diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/PlayerChunk.java
@ -196,8 +195,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
final com.destroystokyo.paper.util.misc.PlayerAreaMap[] playerEntityTrackerTrackMaps;
final int[] entityTrackerTrackRanges;
return MinecraftServer.getServer().applyTrackingRangeScale(vanilla);
}
// Paper end - use distance map to optimise tracker
+ // Paper start - optimise PlayerChunkMap#isOutsideRange
+ // A note about the naming used here:
@ -242,16 +241,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ this.playerChunkTickRangeMap.update(player, chunkX, chunkZ, ChunkMapDistance.MOB_SPAWN_RANGE);
+ // Paper end - optimise PlayerChunkMap#isOutsideRange
}
// Paper end
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
this.mailboxWorldGen = this.p.a(threadedmailbox, false);
this.mailboxMain = this.p.a(mailbox, false);
this.lightEngine = new LightEngineThreaded(ilightaccess, this, this.world.getWorldProvider().f(), threadedmailbox1, this.p.a(threadedmailbox1, false));
this.lightEngine = new LightEngineThreaded(ilightaccess, this, this.world.getDimensionManager().hasSkyLight(), threadedmailbox1, this.p.a(threadedmailbox1, false));
- this.chunkDistanceManager = new PlayerChunkMap.a(executor, iasynctaskhandler);
+ this.chunkDistanceManager = new PlayerChunkMap.a(executor, iasynctaskhandler); this.chunkDistanceManager.chunkMap = this; // Paper
this.l = supplier;
this.m = new VillagePlace(new File(this.w, "poi"), datafixer, this.world); // Paper
this.m = new VillagePlace(new File(this.w, "poi"), datafixer, flag, this.world); // Paper
this.setViewDistance(i);
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
this.playerEntityTrackerTrackMaps[ordinal] = new com.destroystokyo.paper.util.misc.PlayerAreaMap(this.pooledLinkedPlayerHashSets);

View File

@ -1,47 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <spottedleaf@spottedleaf.dev>
Date: Mon, 6 Apr 2020 18:06:24 -0700
Subject: [PATCH] Remove streams from MinecraftKey
They produce a lot of garbage.
diff --git a/src/main/java/net/minecraft/server/MinecraftKey.java b/src/main/java/net/minecraft/server/MinecraftKey.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/MinecraftKey.java
+++ b/src/main/java/net/minecraft/server/MinecraftKey.java
@@ -0,0 +0,0 @@ public class MinecraftKey implements Comparable<MinecraftKey> {
}
private static boolean c(String s) {
- return s.chars().allMatch((i) -> {
- return i == 95 || i == 45 || i >= 97 && i <= 122 || i >= 48 && i <= 57 || i == 47 || i == 46;
- });
+ // Paper start - remove streams
+ for (int index = 0, len = s.length(); index < len; ++index) {
+ int i = (int)s.charAt(index);
+ boolean condition = i == 95 || i == 45 || i >= 97 && i <= 122 || i >= 48 && i <= 57 || i == 47 || i == 46; // this is copied from the replaced code.
+ if (!condition) {
+ return false;
+ }
+ }
+ return true;
+ // Paper end - remove streams
}
private static boolean d(String s) {
- return s.chars().allMatch((i) -> {
- return i == 95 || i == 45 || i >= 97 && i <= 122 || i >= 48 && i <= 57 || i == 46;
- });
+ // Paper start - remove streams
+ for (int index = 0, len = s.length(); index < len; ++index) {
+ int i = (int)s.charAt(index);
+ boolean condition = i == 95 || i == 45 || i >= 97 && i <= 122 || i >= 48 && i <= 57 || i == 46; // this is copied from the replaced code.
+ if (!condition) {
+ return false;
+ }
+ }
+ return true;
+ // Paper end - remove streams
}
public static class a implements JsonDeserializer<MinecraftKey>, JsonSerializer<MinecraftKey> {

View File

@ -66,11 +66,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import java.util.Iterator; // Paper - remove streams from pathfindergoalselector
import java.util.Map;
import java.util.Set;
import java.util.stream.Stream;
import java.util.function.Supplier;
@@ -0,0 +0,0 @@ public class PathfinderGoalSelector {
private final Map<PathfinderGoal.Type, PathfinderGoalWrapped> c = new EnumMap(PathfinderGoal.Type.class);
private final Set<PathfinderGoalWrapped> d = Sets.newLinkedHashSet();private Set<PathfinderGoalWrapped> getTasks() { return d; }// Paper - OBFHELPER
private final GameProfilerFiller e;
private final Set<PathfinderGoalWrapped> d = Sets.newLinkedHashSet(); private Set<PathfinderGoalWrapped> getTasks() { return d; }// Paper - OBFHELPER
private final Supplier<GameProfilerFiller> e;
- private final EnumSet<PathfinderGoal.Type> f = EnumSet.noneOf(PathfinderGoal.Type.class);
+ private final EnumSet<PathfinderGoal.Type> f = EnumSet.noneOf(PathfinderGoal.Type.class); // Paper unused, but dummy to prevent plugins from crashing as hard. Theyll need to support paper in a special case if this is super important, but really doesn't seem like it would be.
+ private final OptimizedSmallEnumSet<PathfinderGoal.Type> goalTypes = new OptimizedSmallEnumSet<>(PathfinderGoal.Type.class); // Paper - remove streams from pathfindergoalselector
@ -104,8 +104,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ private static final PathfinderGoal.Type[] PATHFINDER_GOAL_TYPES = PathfinderGoal.Type.values(); // Paper - remove streams from pathfindergoalselector
+
public void doTick() {
this.e.enter("goalCleanup");
- this.c().filter((pathfindergoalwrapped) -> {
GameProfilerFiller gameprofilerfiller = (GameProfilerFiller) this.e.get();
gameprofilerfiller.enter("goalCleanup");
- this.d().filter((pathfindergoalwrapped) -> {
- boolean flag;
-
- if (pathfindergoalwrapped.g()) {
@ -138,8 +140,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
this.c.remove(pathfindergoal_type);
@@ -0,0 +0,0 @@ public class PathfinderGoalSelector {
});
this.e.exit();
this.e.enter("goalUpdate");
gameprofilerfiller.exit();
gameprofilerfiller.enter("goalUpdate");
- this.d.stream().filter((pathfindergoalwrapped) -> {
- return !pathfindergoalwrapped.g();
- }).filter((pathfindergoalwrapped) -> {
@ -203,9 +205,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ wrappedGoal.c();
+ }
+ // Paper end - remove streams from pathfindergoalselector
this.e.exit();
this.e.enter("goalTick");
- this.c().forEach(PathfinderGoalWrapped::e);
gameprofilerfiller.exit();
gameprofilerfiller.enter("goalTick");
- this.d().forEach(PathfinderGoalWrapped::e);
+ // Paper start - remove streams from pathfindergoalselector
+ for (Iterator<PathfinderGoalWrapped> iterator = this.d.iterator(); iterator.hasNext();) {
+ PathfinderGoalWrapped wrappedGoal = iterator.next();
@ -214,7 +216,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ }
+ // Paper end - remove streams from pathfindergoalselector
this.e.exit();
gameprofilerfiller.exit();
}
@@ -0,0 +0,0 @@ public class PathfinderGoalSelector {

View File

@ -10,15 +10,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/CommandTeleport.java
+++ b/src/main/java/net/minecraft/server/CommandTeleport.java
@@ -0,0 +0,0 @@ public class CommandTeleport {
}
private static void a(CommandListenerWrapper commandlistenerwrapper, Entity entity, WorldServer worldserver, double d0, double d1, double d2, Set<PacketPlayOutPosition.EnumPlayerTeleportFlags> set, float f, float f1, @Nullable CommandTeleport.a commandteleport_a) {
private static void a(CommandListenerWrapper commandlistenerwrapper, Entity entity, WorldServer worldserver, double d0, double d1, double d2, Set<PacketPlayOutPosition.EnumPlayerTeleportFlags> set, float f, float f1, @Nullable CommandTeleport.a commandteleport_a) throws CommandSyntaxException {
BlockPosition blockposition = new BlockPosition(d0, d1, d2);
+ // Paper start - Don't allow teleport command to invalid locations
+ if (d0 <= -30000000 || d2 <= -30000000 || d0 > 30000000 || d2 > 30000000 || d1 > 30000000 || d1 <= -30000000) { // Copy/pasta from BaseBlockPosition#isValidLocation
+ org.bukkit.Bukkit.getLogger().warning("Refused to teleport " + entity.getName() + " to " + d0 + ", " + d1 + ", " + d2);
+ return;
+ }
+ // Paper end
if (entity instanceof EntityPlayer) {
ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(new BlockPosition(d0, d1, d2));
if (!World.k(blockposition)) {
throw CommandTeleport.a.create();

View File

@ -36,13 +36,25 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/EntityTrackerEntry.java
+++ b/src/main/java/net/minecraft/server/EntityTrackerEntry.java
@@ -0,0 +0,0 @@ public class EntityTrackerEntry {
this.r = entity.onGround;
this.r = entity.isOnGround();
}
+ public final void tick() { this.a(); } // Paper - OBFHELPER
public void a() {
List<Entity> list = this.tracker.getPassengers();
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
}
}
+ public final int applyTrackingRangeScale(int value) { return this.b(i); } // Paper - OBFHELPER
public int b(int i) {
return i;
}
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
@ -60,6 +72,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ static final org.spigotmc.TrackingRange.TrackingRangeType[] TRACKING_RANGE_TYPES = org.spigotmc.TrackingRange.TrackingRangeType.values();
+ final com.destroystokyo.paper.util.misc.PlayerAreaMap[] playerEntityTrackerTrackMaps;
+ final int[] entityTrackerTrackRanges;
+
+ private int convertSpigotRangeToVanilla(final int vanilla) {
+ return MinecraftServer.getServer().applyTrackingRangeScale(vanilla);
+ }
+ // Paper end - use distance map to optimise tracker
void addPlayerToDistanceMaps(EntityPlayer player) {
@ -98,10 +114,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }
+ // Paper end - use distance map to optimise entity tracker
}
// Paper end
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
this.m = new VillagePlace(new File(this.w, "poi"), datafixer, this.world); // Paper
this.m = new VillagePlace(new File(this.w, "poi"), datafixer, flag, this.world); // Paper
this.setViewDistance(i);
this.playerMobDistanceMap = this.world.paperConfig.perPlayerMobSpawns ? new com.destroystokyo.paper.util.PlayerMobDistanceMap() : null; // Paper
+ // Paper start - use distance map to optimise entity tracker
@ -135,6 +151,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ default:
+ throw new IllegalStateException("Missing case for enum " + trackingRangeType);
+ }
+ configuredSpigotValue = convertSpigotRangeToVanilla(configuredSpigotValue);
+
+ int trackRange = (configuredSpigotValue >>> 4) + ((configuredSpigotValue & 15) != 0 ? 1 : 0);
+ this.entityTrackerTrackRanges[ordinal] = trackRange;
@ -166,12 +183,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
int j = MathHelper.floor(entityplayer.locZ()) >> 4;
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
entity.tracker = playerchunkmap_entitytracker; // Paper - Fast access to tracker
this.trackedEntities.put(entity.getId(), playerchunkmap_entitytracker);
- playerchunkmap_entitytracker.track(this.world.getPlayers());
+ playerchunkmap_entitytracker.updatePlayers(entity.getPlayersInTrackRange()); // Paper - don't search all players
if (entity instanceof EntityPlayer) {
EntityPlayer entityplayer = (EntityPlayer) entity;
entity.tracker = playerchunkmap_entitytracker; // Paper - Fast access to tracker
this.trackedEntities.put(entity.getId(), playerchunkmap_entitytracker);
- playerchunkmap_entitytracker.track(this.world.getPlayers());
+ playerchunkmap_entitytracker.updatePlayers(entity.getPlayersInTrackRange()); // Paper - don't search all players
if (entity instanceof EntityPlayer) {
EntityPlayer entityplayer = (EntityPlayer) entity;
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
entity.tracker = null; // Paper - We're no longer tracked
@ -321,6 +338,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/org/spigotmc/TrackingRange.java
+++ b/src/main/java/org/spigotmc/TrackingRange.java
@@ -0,0 +0,0 @@ public class TrackingRange
return config.miscTrackingRange;
} else
{
- if (entity instanceof EntityEnderDragon) return ((WorldServer)(entity.getWorld())).getChunkProvider().playerChunkMap.getLoadViewDistance(); // Paper - enderdragon is exempt
+ if (entity instanceof EntityEnderDragon) return defaultRange; // Paper - enderdragon is exempt
return config.otherTrackingRange;
}
}
@ -337,8 +359,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ switch (entity.activationType) {
+ case RAIDER:
+ case MONSTER:
+ case FLYING_MONSTER:
+ return TrackingRangeType.MONSTER;
+ case WATER:
+ case VILLAGER:
+ case ANIMAL:
+ return TrackingRangeType.ANIMAL;
+ case MISC:

View File

@ -10,7 +10,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+++ b/src/main/java/net/minecraft/server/EntityVillager.java
@@ -0,0 +0,0 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation
return optional.isPresent() && optional1.isPresent() ? i - ((MinecraftSerializableLong) optional.get()).a() < 24000L && i - ((MinecraftSerializableLong) optional1.get()).a() < 36000L : false;
return optional.isPresent() ? i - (Long) optional.get() < 24000L : false;
}
+
+ // Paper start