diff --git a/sources/pom.xml b/sources/pom.xml
index 94a15ae9e..95dd3a78c 100644
--- a/sources/pom.xml
+++ b/sources/pom.xml
@@ -3,15 +3,15 @@
4.0.0
akarin
jar
- 1.13-R0.1-SNAPSHOT
+ 1.13.1-R0.1-SNAPSHOT
Akarin
https://github.com/Akarin-project/Akarin
UTF-8
- 1.13-R0.1-SNAPSHOT
- 1.13
- 1_13_R1
+ 1.13.1-R0.1-SNAPSHOT
+ 1.13.1
+ 1_13_R2
git-Bukkit-
yyyyMMdd-HHmm
@@ -44,6 +44,59 @@
${minecraft.version}-SNAPSHOT
compile
+
+ net.minecrell
+ terminalconsoleappender
+ 1.1.1
+
+
+ net.java.dev.jna
+ jna
+ 4.5.2
+ runtime
+
+
+
+ org.apache.logging.log4j
+ log4j-core
+ 2.8.1
+ compile
+
+
+ org.apache.logging.log4j
+ log4j-slf4j-impl
+ 2.8.1
+ runtime
+
+
+ org.apache.logging.log4j
+ log4j-iostreams
+ 2.8.1
+
+
+
+ org.apache.logging.log4j
+ log4j-slf4j-impl
+ 2.8.1
+ runtime
+
+
+ org.apache.logging.log4j
+ log4j-iostreams
+ 2.8.1
+
+
+
+ com.lmax
+ disruptor
+ 3.4.2
+ runtime
+
org.ow2.asm
asm
@@ -68,53 +121,6 @@
3.0.3
compile
-
-
- net.minecrell
- terminalconsoleappender
- 1.1.1
-
-
- net.java.dev.jna
- jna
- 4.5.2
- runtime
-
-
-
-
- org.apache.logging.log4j
- log4j-core
- 2.8.1
- compile
-
-
-
-
- org.apache.logging.log4j
- log4j-slf4j-impl
- 2.8.1
- runtime
-
-
- org.apache.logging.log4j
- log4j-iostreams
- 2.8.1
-
-
-
-
- com.lmax
- disruptor
- 3.4.2
- runtime
-
-
junit
@@ -128,12 +134,11 @@
1.3
test
-
io.akarin
legacylauncher
- 2.0
+ 2.1
org.spongepowered
@@ -210,6 +215,7 @@
net.minecraft.launchwrapper.Launch
CraftBukkit
+
${describe}
${maven.build.timestamp}
Bukkit
diff --git a/sources/src/main/java/com/destroystokyo/paper/antixray/ChunkPacketInfo.java b/sources/src/main/java/com/destroystokyo/paper/antixray/ChunkPacketInfo.java
new file mode 100644
index 000000000..599ea3267
--- /dev/null
+++ b/sources/src/main/java/com/destroystokyo/paper/antixray/ChunkPacketInfo.java
@@ -0,0 +1,82 @@
+package com.destroystokyo.paper.antixray;
+
+import io.netty.buffer.ByteBuf;
+import net.minecraft.server.Chunk;
+import net.minecraft.server.DataPalette;
+import net.minecraft.server.PacketPlayOutMapChunk;
+
+public class ChunkPacketInfo {
+
+ private final PacketPlayOutMapChunk packetPlayOutMapChunk;
+ private final Chunk chunk;
+ private final int chunkSectionSelector;
+ private ByteBuf data; // Akarin
+ private final int[] bitsPerObject = new int[16];
+ private final Object[] dataPalettes = new Object[16];
+ private final int[] dataBitsIndexes = new int[16];
+ private final Object[][] predefinedObjects = new Object[16][];
+
+ public ChunkPacketInfo(PacketPlayOutMapChunk packetPlayOutMapChunk, Chunk chunk, int chunkSectionSelector) {
+ this.packetPlayOutMapChunk = packetPlayOutMapChunk;
+ this.chunk = chunk;
+ this.chunkSectionSelector = chunkSectionSelector;
+ }
+
+ public PacketPlayOutMapChunk getPacketPlayOutMapChunk() {
+ return packetPlayOutMapChunk;
+ }
+
+ public Chunk getChunk() {
+ return chunk;
+ }
+
+ public int getChunkSectionSelector() {
+ return chunkSectionSelector;
+ }
+
+ public ByteBuf getData() { // Akarin
+ return data;
+ }
+
+ public void setData(ByteBuf data) { // Akarin
+ this.data = data;
+ }
+
+ public int getBitsPerObject(int chunkSectionIndex) {
+ return bitsPerObject[chunkSectionIndex];
+ }
+
+ public void setBitsPerObject(int chunkSectionIndex, int bitsPerObject) {
+ this.bitsPerObject[chunkSectionIndex] = bitsPerObject;
+ }
+
+ @SuppressWarnings("unchecked")
+ public DataPalette getDataPalette(int chunkSectionIndex) {
+ return (DataPalette) dataPalettes[chunkSectionIndex];
+ }
+
+ public void setDataPalette(int chunkSectionIndex, DataPalette dataPalette) {
+ dataPalettes[chunkSectionIndex] = dataPalette;
+ }
+
+ public int getDataBitsIndex(int chunkSectionIndex) {
+ return dataBitsIndexes[chunkSectionIndex];
+ }
+
+ public void setDataBitsIndex(int chunkSectionIndex, int dataBitsIndex) {
+ dataBitsIndexes[chunkSectionIndex] = dataBitsIndex;
+ }
+
+ @SuppressWarnings("unchecked")
+ public T[] getPredefinedObjects(int chunkSectionIndex) {
+ return (T[]) predefinedObjects[chunkSectionIndex];
+ }
+
+ public void setPredefinedObjects(int chunkSectionIndex, T[] predefinedObjects) {
+ this.predefinedObjects[chunkSectionIndex] = predefinedObjects;
+ }
+
+ public boolean isWritten(int chunkSectionIndex) {
+ return bitsPerObject[chunkSectionIndex] != 0;
+ }
+}
diff --git a/sources/src/main/java/com/destroystokyo/paper/antixray/DataBitsReader.java b/sources/src/main/java/com/destroystokyo/paper/antixray/DataBitsReader.java
new file mode 100644
index 000000000..49178aad1
--- /dev/null
+++ b/sources/src/main/java/com/destroystokyo/paper/antixray/DataBitsReader.java
@@ -0,0 +1,62 @@
+package com.destroystokyo.paper.antixray;
+
+import io.netty.buffer.ByteBuf;
+
+public class DataBitsReader {
+
+ private ByteBuf dataBits; // Akarin
+ private int bitsPerObject;
+ private int mask;
+ private int longInDataBitsIndex;
+ private int bitInLongIndex;
+ private long current;
+
+ public void setDataBits(ByteBuf dataBits) { // Akarin
+ this.dataBits = dataBits;
+ }
+
+ public void setBitsPerObject(int bitsPerObject) {
+ this.bitsPerObject = bitsPerObject;
+ mask = (1 << bitsPerObject) - 1;
+ }
+
+ public void setIndex(int index) {
+ this.longInDataBitsIndex = index;
+ bitInLongIndex = 0;
+ init();
+ }
+
+ private void init() {
+ if (dataBits.capacity() > longInDataBitsIndex + 7) { // Akarin
+ // Akarin start
+ dataBits.getLong(longInDataBitsIndex);
+ /*
+ current = ((((long) dataBits[longInDataBitsIndex]) << 56)
+ | (((long) dataBits[longInDataBitsIndex + 1] & 0xff) << 48)
+ | (((long) dataBits[longInDataBitsIndex + 2] & 0xff) << 40)
+ | (((long) dataBits[longInDataBitsIndex + 3] & 0xff) << 32)
+ | (((long) dataBits[longInDataBitsIndex + 4] & 0xff) << 24)
+ | (((long) dataBits[longInDataBitsIndex + 5] & 0xff) << 16)
+ | (((long) dataBits[longInDataBitsIndex + 6] & 0xff) << 8)
+ | (((long) dataBits[longInDataBitsIndex + 7] & 0xff)));
+ */ // Akarin end
+ }
+ }
+
+ public int read() {
+ int value = (int) (current >>> bitInLongIndex) & mask;
+ bitInLongIndex += bitsPerObject;
+
+ if (bitInLongIndex > 63) {
+ bitInLongIndex -= 64;
+ longInDataBitsIndex += 8;
+ init();
+
+ if (bitInLongIndex > 0) {
+ value |= current << bitsPerObject - bitInLongIndex & mask;
+ }
+ }
+
+ return value;
+ }
+}
diff --git a/sources/src/main/java/com/destroystokyo/paper/antixray/DataBitsWriter.java b/sources/src/main/java/com/destroystokyo/paper/antixray/DataBitsWriter.java
new file mode 100644
index 000000000..481669677
--- /dev/null
+++ b/sources/src/main/java/com/destroystokyo/paper/antixray/DataBitsWriter.java
@@ -0,0 +1,94 @@
+package com.destroystokyo.paper.antixray;
+
+import io.netty.buffer.ByteBuf;
+
+public class DataBitsWriter {
+
+ private ByteBuf dataBits; // Akarin
+ private int bitsPerObject;
+ private long mask;
+ private int longInDataBitsIndex;
+ private int bitInLongIndex;
+ private long current;
+ private boolean dirty;
+
+ public void setDataBits(ByteBuf dataBits) { // Akarin
+ this.dataBits = dataBits;
+ }
+
+ public void setBitsPerObject(int bitsPerObject) {
+ this.bitsPerObject = bitsPerObject;
+ mask = (1 << bitsPerObject) - 1;
+ }
+
+ public void setIndex(int index) {
+ this.longInDataBitsIndex = index;
+ bitInLongIndex = 0;
+ init();
+ }
+
+ private void init() {
+ if (dataBits.capacity() > longInDataBitsIndex + 7) { // Akarin
+ // Akarin start
+ current = dataBits.getLong(longInDataBitsIndex);
+ /*
+ current = ((((long) dataBits[longInDataBitsIndex]) << 56)
+ | (((long) dataBits[longInDataBitsIndex + 1] & 0xff) << 48)
+ | (((long) dataBits[longInDataBitsIndex + 2] & 0xff) << 40)
+ | (((long) dataBits[longInDataBitsIndex + 3] & 0xff) << 32)
+ | (((long) dataBits[longInDataBitsIndex + 4] & 0xff) << 24)
+ | (((long) dataBits[longInDataBitsIndex + 5] & 0xff) << 16)
+ | (((long) dataBits[longInDataBitsIndex + 6] & 0xff) << 8)
+ | (((long) dataBits[longInDataBitsIndex + 7] & 0xff)));
+ */ // Akarin end
+ }
+
+ dirty = false;
+ }
+
+ public void finish() {
+ if (dirty && dataBits.capacity() > longInDataBitsIndex + 7) { // Akarin
+ // Akarin start
+ dataBits.setLong(longInDataBitsIndex, current);
+ /*
+ dataBits[longInDataBitsIndex] = (byte) (current >> 56 & 0xff);
+ dataBits[longInDataBitsIndex + 1] = (byte) (current >> 48 & 0xff);
+ dataBits[longInDataBitsIndex + 2] = (byte) (current >> 40 & 0xff);
+ dataBits[longInDataBitsIndex + 3] = (byte) (current >> 32 & 0xff);
+ dataBits[longInDataBitsIndex + 4] = (byte) (current >> 24 & 0xff);
+ dataBits[longInDataBitsIndex + 5] = (byte) (current >> 16 & 0xff);
+ dataBits[longInDataBitsIndex + 6] = (byte) (current >> 8 & 0xff);
+ dataBits[longInDataBitsIndex + 7] = (byte) (current & 0xff);
+ */ // Akarin end
+ }
+ }
+
+ public void write(int value) {
+ current = current & ~(mask << bitInLongIndex) | (value & mask) << bitInLongIndex;
+ dirty = true;
+ bitInLongIndex += bitsPerObject;
+
+ if (bitInLongIndex > 63) {
+ finish();
+ bitInLongIndex -= 64;
+ longInDataBitsIndex += 8;
+ init();
+
+ if (bitInLongIndex > 0) {
+ current = current & ~(mask >>> bitsPerObject - bitInLongIndex) | (value & mask) >>> bitsPerObject - bitInLongIndex;
+ dirty = true;
+ }
+ }
+ }
+
+ public void skip() {
+ bitInLongIndex += bitsPerObject;
+
+ if (bitInLongIndex > 63) {
+ finish();
+ bitInLongIndex -= 64;
+ longInDataBitsIndex += 8;
+ init();
+ }
+ }
+}
diff --git a/sources/src/main/java/io/akarin/server/core/AkarinSlackScheduler.java b/sources/src/main/java/io/akarin/server/core/AkarinSlackScheduler.java
index 5549afd10..57baf007b 100644
--- a/sources/src/main/java/io/akarin/server/core/AkarinSlackScheduler.java
+++ b/sources/src/main/java/io/akarin/server/core/AkarinSlackScheduler.java
@@ -77,7 +77,7 @@ public class AkarinSlackScheduler extends Thread {
// Force hardcore difficulty, from WorldServer#doTick
if (AkarinGlobalConfig.forceHardcoreDifficulty)
- for (WorldServer world : server.worlds) {
+ for (WorldServer world : server.getWorlds()) {
if (world.getWorldData().isHardcore() && world.getDifficulty() != EnumDifficulty.HARD) {
world.getWorldData().setDifficulty(EnumDifficulty.HARD);
}
diff --git a/sources/src/main/java/io/akarin/server/mixin/core/MixinMinecraftServer.java b/sources/src/main/java/io/akarin/server/mixin/core/MixinMinecraftServer.java
index a29789cc8..6b8aa2363 100644
--- a/sources/src/main/java/io/akarin/server/mixin/core/MixinMinecraftServer.java
+++ b/sources/src/main/java/io/akarin/server/mixin/core/MixinMinecraftServer.java
@@ -5,6 +5,7 @@ import java.util.List;
import java.util.Queue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
+import java.util.function.BooleanSupplier;
import javax.activation.FileDataSource;
@@ -80,11 +81,11 @@ public abstract class MixinMinecraftServer {
* Parallel world ticking
*/
@Shadow public CraftServer server;
- @Shadow @Mutable protected Queue> g;
+ @Shadow @Mutable protected Queue> f;
@Shadow public Queue processQueue;
@Shadow private int ticks;
@Shadow public List worlds;
- @Shadow(aliases = "l") @Final private List tickables;
+ @Shadow(aliases = "k") @Final private List tickables;
@Shadow public abstract CustomFunctionData getFunctionData();
@Shadow public abstract ServerConnection getServerConnection();
@@ -109,10 +110,10 @@ public abstract class MixinMinecraftServer {
return true;
}
- private void tickWorld(WorldServer world) {
+ private void tickWorld(WorldServer world, BooleanSupplier supplier) {
try {
world.timings.doTick.startTiming();
- world.doTick();
+ world.doTick(supplier);
world.timings.doTick.stopTiming();
} catch (Throwable throwable) {
CrashReport crashreport;
@@ -127,7 +128,7 @@ public abstract class MixinMinecraftServer {
}
@Overwrite
- public void w() throws InterruptedException, ExecutionException {
+ public void b(BooleanSupplier supplier) throws InterruptedException, ExecutionException {
Runnable runnable;
MinecraftTimings.bukkitSchedulerTimer.startTiming();
this.server.getScheduler().mainThreadHeartbeat(this.ticks);
@@ -135,8 +136,8 @@ public abstract class MixinMinecraftServer {
MinecraftTimings.minecraftSchedulerTimer.startTiming();
FutureTask> task;
- int count = g.size();
- while (count-- > 0 && (task = g.poll()) != null) {
+ int count = f.size();
+ while (count-- > 0 && (task = f.poll()) != null) {
SystemUtils.a(task, MinecraftServer.LOGGER);
}
MinecraftTimings.minecraftSchedulerTimer.stopTiming();
@@ -176,7 +177,7 @@ public abstract class MixinMinecraftServer {
Akari.STAGE_TICK.submit(() -> {
WorldServer world = worlds.get(fi);
synchronized (((IMixinWorldServer) world).tickLock()) {
- tickWorld(world);
+ tickWorld(world, supplier);
}
}, null);
}
@@ -187,7 +188,7 @@ public abstract class MixinMinecraftServer {
for (int i = 0; i < cachedWorldSize; i++) {
WorldServer world = worlds.get(i);
synchronized (((IMixinWorldServer) world).tickLock()) {
- tickWorld(world);
+ tickWorld(world, supplier);
}
}
}, null);
@@ -218,7 +219,7 @@ public abstract class MixinMinecraftServer {
for (int i = 0; i < cachedWorldSize; ++i) {
WorldServer world = worlds.get(i);
synchronized (((IMixinWorldServer) world).tickLock()) {
- tickWorld(world);
+ tickWorld(world, supplier);
}
}
}, null);
@@ -229,7 +230,7 @@ public abstract class MixinMinecraftServer {
case -1:
for (int i = 0; i < cachedWorldSize; ++i) {
WorldServer world = worlds.get(i);
- tickWorld(world);
+ tickWorld(world, supplier);
tickEntities(world);
}
break;
diff --git a/sources/src/main/java/io/akarin/server/mixin/cps/MixinChunkProviderServer.java b/sources/src/main/java/io/akarin/server/mixin/cps/MixinChunkProviderServer.java
deleted file mode 100644
index 43ec58823..000000000
--- a/sources/src/main/java/io/akarin/server/mixin/cps/MixinChunkProviderServer.java
+++ /dev/null
@@ -1,89 +0,0 @@
-package io.akarin.server.mixin.cps;
-
-import org.spigotmc.SlackActivityAccountant;
-import org.spongepowered.asm.mixin.Final;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Overwrite;
-import org.spongepowered.asm.mixin.Shadow;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Redirect;
-
-import it.unimi.dsi.fastutil.longs.Long2ObjectMap.Entry;
-import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
-import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
-import it.unimi.dsi.fastutil.objects.ObjectIterator;
-import net.minecraft.server.Chunk;
-import net.minecraft.server.ChunkProviderServer;
-import net.minecraft.server.ChunkTaskScheduler;
-import net.minecraft.server.IChunkLoader;
-import net.minecraft.server.WorldServer;
-
-@Mixin(value = ChunkProviderServer.class, remap = false)
-public abstract class MixinChunkProviderServer {
- @Shadow @Final public WorldServer world;
- @Shadow public Long2ObjectMap chunks;
- @Shadow(aliases = "f") @Final private ChunkTaskScheduler scheduler;
-
- public void unload(Chunk chunk) {
- if (this.world.worldProvider.a(chunk.locX, chunk.locZ)) {
- // Akarin - avoid using the queue and simply check the unloaded flag during unloads
- // this.unloadQueue.add(Long.valueOf(ChunkCoordIntPair.a(chunk.locX, chunk.locZ)));
- chunk.setShouldUnload(true);
- }
- }
-
- @Shadow public abstract boolean unloadChunk(Chunk chunk, boolean save);
- @Shadow @Final private IChunkLoader chunkLoader;
- @Shadow @Final private static double UNLOAD_QUEUE_RESIZE_FACTOR;
-
- @Overwrite
- public boolean unloadChunks() {
- if (!this.world.savingDisabled) {
- long now = System.currentTimeMillis();
- long unloadAfter = world.paperConfig.delayChunkUnloadsBy;
- SlackActivityAccountant activityAccountant = world.getMinecraftServer().slackActivityAccountant;
- activityAccountant.startActivity(0.5);
-
- ObjectIterator> it = chunks.long2ObjectEntrySet().iterator();
- int remainingChunks = chunks.size();
- int targetSize = Math.min(remainingChunks - 100, (int) (remainingChunks * UNLOAD_QUEUE_RESIZE_FACTOR)); // Paper - Make more aggressive
-
- while (it.hasNext()) {
- Entry entry = it.next();
- Chunk chunk = entry.getValue();
-
- if (chunk != null && chunk.isUnloading()) {
- if (chunk.scheduledForUnload != null) {
- if (now - chunk.scheduledForUnload <= unloadAfter) continue;
- }
-
- if (unloadChunk(chunk, true)) {
- it.remove();
- }
- chunk.setShouldUnload(false);
- chunk.scheduledForUnload = null;
-
- if (--remainingChunks <= targetSize && activityAccountant.activityTimeIsExhausted()) break;
- }
- }
- activityAccountant.endActivity();
-
- this.scheduler.a();
- this.chunkLoader.b(); // OBFHELPER: chunkTick
- }
- return false;
- }
-
- @Redirect(method = "unloadChunk", at = @At(
- value = "INVOKE",
- target = "it/unimi/dsi/fastutil/longs/Long2ObjectMap.remove(J)Ljava/lang/Object;"
- ))
- private Object remove(Long2ObjectOpenHashMap chunks, long chunkHash) {
- return null;
- }
-
- @Overwrite
- public String getName() {
- return "ServerChunkCache: " + chunks.size();
- }
-}
diff --git a/sources/src/main/java/io/akarin/server/mixin/cps/MixinCraftWorld.java b/sources/src/main/java/io/akarin/server/mixin/cps/MixinCraftWorld.java
deleted file mode 100644
index 0415e3d76..000000000
--- a/sources/src/main/java/io/akarin/server/mixin/cps/MixinCraftWorld.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package io.akarin.server.mixin.cps;
-
-import java.util.Set;
-
-import org.bukkit.craftbukkit.CraftWorld;
-import org.spongepowered.asm.lib.Opcodes;
-import org.spongepowered.asm.mixin.Final;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Shadow;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Redirect;
-
-import net.minecraft.server.Chunk;
-import net.minecraft.server.WorldServer;
-
-@Mixin(value = CraftWorld.class, remap = false)
-public abstract class MixinCraftWorld {
- @Shadow @Final private WorldServer world;
-
- @Redirect(method = "processChunkGC()V", at = @At(
- value = "INVOKE",
- target = "it/unimi/dsi/fastutil/longs/LongSet.contains(J)Z",
- opcode = Opcodes.INVOKEINTERFACE
- ))
- public boolean checkUnloading(Set set, Object chunkHash) {
- return false;
- }
-
- @Redirect(method = "regenerateChunk", at = @At(
- value = "INVOKE",
- target = "it/unimi/dsi/fastutil/longs/LongSet.remove(J)Z",
- opcode = Opcodes.INVOKEINTERFACE
- ))
- public boolean regenChunk(Set set, Object chunkHash) {
- Chunk chunk = world.getChunkProviderServer().chunks.get(chunkHash);
- if (chunk != null) chunk.setShouldUnload(false);
- return true;
- }
-}
diff --git a/sources/src/main/java/io/akarin/server/mixin/nsc/NonblockingServerConnection.java b/sources/src/main/java/io/akarin/server/mixin/nsc/NonblockingServerConnection.java
index 66e1d00e2..1f10fdc48 100644
--- a/sources/src/main/java/io/akarin/server/mixin/nsc/NonblockingServerConnection.java
+++ b/sources/src/main/java/io/akarin/server/mixin/nsc/NonblockingServerConnection.java
@@ -75,7 +75,7 @@ public abstract class NonblockingServerConnection {
Class extends ServerChannel> channelClass;
EventLoopGroup loopGroup;
- if (Epoll.isAvailable() && this.server.X()) { // OBFHELPER: MinecraftServer::useNativeTransport
+ if (Epoll.isAvailable() && this.server.V()) { // OBFHELPER: MinecraftServer::useNativeTransport
channelClass = EpollServerSocketChannel.class;
loopGroup = ServerConnection.b.a();
logger.info("Using epoll channel type");
diff --git a/sources/src/main/java/io/akarin/server/mixin/nsc/OptimisticNetworkManager.java b/sources/src/main/java/io/akarin/server/mixin/nsc/OptimisticNetworkManager.java
new file mode 100644
index 000000000..b0a3f2c59
--- /dev/null
+++ b/sources/src/main/java/io/akarin/server/mixin/nsc/OptimisticNetworkManager.java
@@ -0,0 +1,61 @@
+package io.akarin.server.mixin.nsc;
+
+import java.util.Queue;
+import org.spongepowered.asm.mixin.Final;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Overwrite;
+import org.spongepowered.asm.mixin.Shadow;
+
+import com.googlecode.concurentlocks.ReentrantReadWriteUpdateLock;
+
+import io.akarin.api.internal.utils.CheckedConcurrentLinkedQueue;
+import io.netty.channel.Channel;
+import io.netty.util.concurrent.Future;
+import io.netty.util.concurrent.GenericFutureListener;
+import net.minecraft.server.NetworkManager;
+import net.minecraft.server.NetworkManager.QueuedPacket;
+import net.minecraft.server.Packet;
+import net.minecraft.server.PacketPlayOutMapChunk;
+
+@Mixin(value = NetworkManager.class, remap = false)
+public abstract class OptimisticNetworkManager {
+ @Shadow public Channel channel;
+ @Shadow(aliases = "i") @Final private Queue packets;
+ @Shadow(aliases = "j") @Final private ReentrantReadWriteUpdateLock queueLock;
+
+ @Shadow public abstract Queue getPacketQueue();
+ @Shadow public abstract void dispatchPacket(Packet> packet, GenericFutureListener extends Future super Void>> genericFutureListener);
+
+ private static final QueuedPacket SIGNAL_PACKET = new QueuedPacket(null, null);
+
+ @Overwrite // OBFHELPER: trySendQueue
+ private boolean o() {
+ if (this.channel != null && this.channel.isOpen()) {
+ if (this.packets.isEmpty()) { // return if the packet queue is empty so that the write lock by Anti-Xray doesn't affect the vanilla performance at all
+ return true;
+ }
+
+ this.queueLock.updateLock().lock();
+ try {
+ while (!this.packets.isEmpty()) {
+ NetworkManager.QueuedPacket packet = ((CheckedConcurrentLinkedQueue) getPacketQueue()).poll(item -> {
+ return item.getPacket() instanceof PacketPlayOutMapChunk && !((PacketPlayOutMapChunk) item.getPacket()).isReady();
+ }, SIGNAL_PACKET);
+
+ if (packet != null) { // Fix NPE (Spigot bug caused by handleDisconnection())
+ if (packet == SIGNAL_PACKET) {
+ return false; // Return false if the peeked packet is a chunk packet which is not ready
+ } else {
+ dispatchPacket(packet.getPacket(), packet.getGenericFutureListener()); // dispatch the packet
+ }
+ }
+ }
+ } finally {
+ this.queueLock.updateLock().unlock();
+ }
+
+ }
+ return true; // Return true if all packets were dispatched
+ }
+
+}
diff --git a/sources/src/main/java/io/akarin/server/mixin/optimization/MixinPersistentCollection.java b/sources/src/main/java/io/akarin/server/mixin/optimization/MixinPersistentCollection.java
deleted file mode 100644
index bedd37b97..000000000
--- a/sources/src/main/java/io/akarin/server/mixin/optimization/MixinPersistentCollection.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package io.akarin.server.mixin.optimization;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import org.spongepowered.asm.mixin.Final;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Overwrite;
-import org.spongepowered.asm.mixin.Shadow;
-
-import com.destroystokyo.paper.exception.ServerInternalException;
-
-import net.minecraft.server.IDataManager;
-import net.minecraft.server.MCUtil;
-import net.minecraft.server.NBTCompressedStreamTools;
-import net.minecraft.server.NBTTagCompound;
-import net.minecraft.server.PersistentBase;
-import net.minecraft.server.PersistentCollection;
-
-@Mixin(value = PersistentCollection.class, remap = false)
-public abstract class MixinPersistentCollection {
- @Shadow(aliases = "c") @Final private IDataManager dataManager;
-
- @Overwrite
- private void a(PersistentBase persistentbase) {
- if (this.dataManager == null) return;
-
- File file = this.dataManager.getDataFile(persistentbase.getId());
- if (file == null) return;
-
- NBTTagCompound nbttagcompound = new NBTTagCompound();
- nbttagcompound.set("data", persistentbase.b(new NBTTagCompound()));
-
- // Akarin start
- MCUtil.scheduleAsyncTask(() -> {
- try {
- nbttagcompound.setInt("DataVersion", 1519);
- FileOutputStream fileoutputstream = new FileOutputStream(file);
-
- NBTCompressedStreamTools.a(nbttagcompound, fileoutputstream);
- fileoutputstream.close();
- } catch (Exception exception) {
- exception.printStackTrace();
- ServerInternalException.reportInternalException(exception); // Paper
- }
- });
- // Akarin end
- }
-}
diff --git a/sources/src/main/java/net/minecraft/server/ChunkProviderServer.java b/sources/src/main/java/net/minecraft/server/ChunkProviderServer.java
index 7c3d918f2..32ddfb6fd 100644
--- a/sources/src/main/java/net/minecraft/server/ChunkProviderServer.java
+++ b/sources/src/main/java/net/minecraft/server/ChunkProviderServer.java
@@ -1,8 +1,5 @@
package net.minecraft.server;
-import com.google.common.collect.Lists;
-
-import io.akarin.api.internal.Akari;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectMaps;
import it.unimi.dsi.fastutil.longs.LongIterator;
@@ -10,15 +7,17 @@ import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
import it.unimi.dsi.fastutil.longs.LongSet;
import it.unimi.dsi.fastutil.objects.ObjectIterator;
import java.io.IOException;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
+import java.util.function.BooleanSupplier;
import java.util.function.Consumer;
import javax.annotation.Nullable;
import com.destroystokyo.paper.exception.ServerInternalException;
+
+import io.akarin.api.internal.Akari;
+
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -35,22 +34,28 @@ public class ChunkProviderServer implements IChunkProvider {
public final LongSet unloadQueue = new LongOpenHashSet();
public final ChunkGenerator> chunkGenerator;
private final IChunkLoader chunkLoader;
- public final Long2ObjectMap chunks = Long2ObjectMaps.synchronize(new ChunkMap(8192));
- private final ChunkTaskScheduler f;
- private final SchedulerBatch g;
// Paper start - chunk save stats
private long lastQueuedSaves = 0L; // Paper
private long lastProcessedSaves = 0L; // Paper
private long lastSaveStatPrinted = System.currentTimeMillis();
+ public boolean isChunkGenerated(int x, int z) {
+ return this.chunks.containsKey(ChunkCoordIntPair.asLong(x, z)) || ((ChunkRegionLoader) this.chunkLoader).chunkExists(x, z);
+ }
// Paper end
+ public final Long2ObjectMap chunks = Long2ObjectMaps.synchronize(new ChunkMap(8192));
+ private Chunk lastChunk;
+ private final ChunkTaskScheduler chunkScheduler;
+ private final SchedulerBatch batchScheduler;
public final WorldServer world;
+ private final IAsyncTaskHandler asyncTaskHandler;
public ChunkProviderServer(WorldServer worldserver, IChunkLoader ichunkloader, ChunkGenerator> chunkgenerator, IAsyncTaskHandler iasynctaskhandler) {
this.world = worldserver;
this.chunkLoader = ichunkloader;
this.chunkGenerator = chunkgenerator;
- this.f = new ChunkTaskScheduler(0, worldserver, chunkgenerator, ichunkloader, iasynctaskhandler); // CraftBukkit - very buggy, broken in lots of __subtle__ ways. Same goes for async chunk loading. Also Bukkit API / plugins can't handle async events at all anyway.
- this.g = new SchedulerBatch(this.f);
+ this.asyncTaskHandler = iasynctaskhandler;
+ this.chunkScheduler = new ChunkTaskScheduler(0, worldserver, chunkgenerator, ichunkloader, iasynctaskhandler); // CraftBukkit - very buggy, broken in lots of __subtle__ ways. Same goes for async chunk loading. Also Bukkit API / plugins can't handle async events at all anyway.
+ this.batchScheduler = new SchedulerBatch(this.chunkScheduler);
}
public Collection a() {
@@ -60,7 +65,6 @@ public class ChunkProviderServer implements IChunkProvider {
public void unload(Chunk chunk) {
if (this.world.worldProvider.a(chunk.locX, chunk.locZ)) {
this.unloadQueue.add(ChunkCoordIntPair.a(chunk.locX, chunk.locZ));
- chunk.d = true;
}
}
@@ -76,119 +80,99 @@ public class ChunkProviderServer implements IChunkProvider {
}
- @Nullable
- public Chunk getLoadedChunkAt(int i, int j) {
- long k = ChunkCoordIntPair.a(i, j);
- Chunk chunk = (Chunk) this.chunks.get(k);
-
- if (chunk != null) {
- chunk.d = false;
- }
-
- return chunk;
+ public void a(int i, int j) {
+ this.unloadQueue.remove(ChunkCoordIntPair.a(i, j));
}
@Nullable
- private Chunk loadChunkAt(int i, int j) {
- try {
- // CraftBukkit - decompile error
- Chunk chunk = this.chunkLoader.a(this.world, i, j, (chunk1) -> {
- chunk1.setLastSaved(this.world.getTime());
- this.chunks.put(ChunkCoordIntPair.a(i, j), chunk1);
- });
+ public Chunk getChunkAt(int i, int j, boolean flag, boolean flag1) {
+ IChunkLoader ichunkloader = this.chunkLoader;
+ Chunk chunk;
+ synchronized (this.chunkLoader) {
+ // Paper start - remove vanilla lastChunk, we do it more accurately
+ /* if (this.lastChunk != null && this.lastChunk.locX == i && this.lastChunk.locZ == j) {
+ return this.lastChunk;
+ }*/ // Paper end
+
+ long k = ChunkCoordIntPair.a(i, j);
+
+ chunk = (Chunk) this.chunks.get(k);
if (chunk != null) {
- chunk.addEntities();
+ //this.lastChunk = chunk; // Paper remove vanilla lastChunk
+ return chunk;
}
+ if (flag) {
+ try (co.aikar.timings.Timing timing = world.timings.syncChunkLoadTimer.startTiming()) { // Paper
+ // CraftBukkit - decompile error
+ chunk = this.chunkLoader.a(this.world, i, j, (chunk1) -> {
+ chunk1.setLastSaved(this.world.getTime());
+ this.chunks.put(ChunkCoordIntPair.a(i, j), chunk1);
+ });
+ } catch (Exception exception) {
+ ChunkProviderServer.a.error("Couldn\'t load chunk", exception);
+ }
+ }
+ }
+
+ if (chunk != null) {
+ this.asyncTaskHandler.postToMainThread(chunk::addEntities);
return chunk;
- } catch (Exception exception) {
- ChunkProviderServer.a.error("Couldn\'t load chunk", exception);
+ } else if (flag1) {
+ try (co.aikar.timings.Timing timing = world.timings.chunkGeneration.startTiming()) { // Paper
+ this.batchScheduler.b();
+ this.batchScheduler.a(new ChunkCoordIntPair(i, j));
+ CompletableFuture completablefuture = this.batchScheduler.c(); // CraftBukkit - decompile error
+
+ return (Chunk) completablefuture.thenApply(this::a).join();
+ } catch (RuntimeException runtimeexception) {
+ throw this.a(i, j, (Throwable) runtimeexception);
+ }
+ // finally { world.timings.syncChunkLoadTimer.stopTiming(); } // Spigot // Paper
+ } else {
return null;
}
}
- @Nullable
- public Chunk getOrLoadChunkAt(int i, int j) {
- Long2ObjectMap long2objectmap = this.chunks;
-
- Akari.eventLock.lock(); // Akarin
- try { // Akarin
- synchronized (this.chunks) {
- Chunk chunk = world.paperConfig.allowPermaChunkLoaders ? getLoadedChunkAt(i, j) : getChunkIfLoaded(i, j); // Paper - Configurable perma chunk loaders
-
- return chunk != null ? chunk : this.loadChunkAt(i, j);
- }
- } finally { Akari.eventLock.unlock(); } // Akarin
- }
-
// CraftBukkit start
- public Chunk getChunkIfLoaded(int x, int z) {
- return chunks.get(ChunkCoordIntPair.a(x, z));
+ public Chunk generateChunk(int x, int z) {
+ try {
+ this.batchScheduler.b();
+ ChunkCoordIntPair pos = new ChunkCoordIntPair(x, z);
+ this.chunkScheduler.forcePolluteCache(pos);
+ this.batchScheduler.a(pos);
+ CompletableFuture completablefuture = this.batchScheduler.c();
+
+ return (Chunk) completablefuture.thenApply(this::a).join();
+ } catch (RuntimeException runtimeexception) {
+ throw this.a(x, z, (Throwable) runtimeexception);
+ }
}
// CraftBukkit end
- public Chunk getChunkAt(int i, int j) {
- Chunk chunk = this.getOrLoadChunkAt(i, j);
+ public IChunkAccess a(int i, int j, boolean flag) {
+ Chunk chunk = this.getChunkAt(i, j, true, false);
- if (chunk != null) {
- return chunk;
- } else {
- try (co.aikar.timings.Timing timing = world.timings.chunkGeneration.startTiming()) {
- ; // Spigot
- chunk = (Chunk) this.generateChunk(i, j).get();
- return chunk;
- } catch (ExecutionException | InterruptedException interruptedexception) {
- throw this.a(i, j, (Throwable) interruptedexception);
- }
- }
- }
-
- public IChunkAccess d(int i, int j) {
- Long2ObjectMap long2objectmap = this.chunks;
-
- synchronized (this.chunks) {
- IChunkAccess ichunkaccess = (IChunkAccess) this.chunks.get(ChunkCoordIntPair.a(i, j));
-
- return ichunkaccess != null ? ichunkaccess : (IChunkAccess) this.f.c((new ChunkCoordIntPair(i, j))); // CraftBukkit - decompile error
- }
+ return (IChunkAccess) (chunk != null ? chunk : (IChunkAccess) this.chunkScheduler.b(new ChunkCoordIntPair(i, j), flag));
}
public CompletableFuture a(Iterable iterable, Consumer consumer) {
- this.g.b();
+ this.batchScheduler.b();
Iterator iterator = iterable.iterator();
while (iterator.hasNext()) {
ChunkCoordIntPair chunkcoordintpair = (ChunkCoordIntPair) iterator.next();
- Chunk chunk = this.getOrLoadChunkAt(chunkcoordintpair.x, chunkcoordintpair.z);
+ Chunk chunk = this.getChunkAt(chunkcoordintpair.x, chunkcoordintpair.z, true, false);
if (chunk != null) {
consumer.accept(chunk);
} else {
- this.g.a(chunkcoordintpair).thenApply(this::a).thenAccept(consumer);
+ this.batchScheduler.a(chunkcoordintpair).thenApply(this::a).thenAccept(consumer);
}
}
- return this.g.c();
- }
-
- // CraftBukkit start
- public CompletableFuture generateChunk(int i, int j) {
- return this.generateChunk(i, j, false);
- }
-
- public CompletableFuture generateChunk(int i, int j, boolean force) {
- this.g.b();
-
- ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(i, j);
- if (force) {
- this.f.forcePolluteCache(chunkcoordintpair);
- }
- this.g.a(chunkcoordintpair);
- // CraftBukkit end
- CompletableFuture completablefuture = this.g.c(); // CraftBukkit - decompile error
-
- return completablefuture.thenApply(this::a);
+ return this.batchScheduler.c();
}
private ReportedException a(int i, int j, Throwable throwable) {
@@ -229,26 +213,14 @@ public class ChunkProviderServer implements IChunkProvider {
}
this.chunks.put(k, chunk);
+ //this.lastChunk = chunk; // Paper
}
} finally { Akari.eventLock.unlock(); } // Akarin
- chunk.addEntities();
+ this.asyncTaskHandler.postToMainThread(chunk::addEntities);
return chunk;
}
- public void saveChunkNOP(Chunk chunk) {
- try {
- // this.chunkLoader.a(this.world, chunk); // Spigot
- } catch (Exception exception) {
- // Paper start
- String msg = "Couldn\'t save entities";
- ChunkProviderServer.a.error(msg, exception);
- ServerInternalException.reportInternalException(exception);
- // Paper end
- }
-
- }
-
public void saveChunk(IChunkAccess ichunkaccess, boolean unloaded) { // Spigot
try (co.aikar.timings.Timing timed = world.timings.chunkSaveData.startTiming()) { // Paper - Timings
ichunkaccess.setLastSaved(this.world.getTime());
@@ -269,65 +241,64 @@ public class ChunkProviderServer implements IChunkProvider {
public boolean a(boolean flag) {
int i = 0;
- this.f.a();
- ArrayList arraylist = Lists.newArrayList(this.chunks.values());
- Iterator iterator = arraylist.iterator();
+ this.chunkScheduler.a(() -> {
+ return true;
+ });
+ IChunkLoader ichunkloader = this.chunkLoader;
- // Paper start
- final ChunkRegionLoader chunkLoader = (ChunkRegionLoader) world.getChunkProviderServer().chunkLoader;
- final int queueSize = chunkLoader.getQueueSize();
+ synchronized (this.chunkLoader) {
+ ObjectIterator objectiterator = this.chunks.values().iterator();
- final long now = System.currentTimeMillis();
- final long timeSince = (now - lastSaveStatPrinted) / 1000;
- final Integer printRateSecs = Integer.getInteger("printSaveStats");
- if (printRateSecs != null && timeSince >= printRateSecs) {
- final String timeStr = "/" + timeSince +"s";
- final long queuedSaves = chunkLoader.getQueuedSaves();
- long queuedDiff = queuedSaves - lastQueuedSaves;
- lastQueuedSaves = queuedSaves;
+ // Paper start
+ final ChunkRegionLoader chunkLoader = (ChunkRegionLoader) world.getChunkProviderServer().chunkLoader;
+ final int queueSize = chunkLoader.getQueueSize();
- final long processedSaves = chunkLoader.getProcessedSaves();
- long processedDiff = processedSaves - lastProcessedSaves;
- lastProcessedSaves = processedSaves;
+ final long now = System.currentTimeMillis();
+ final long timeSince = (now - lastSaveStatPrinted) / 1000;
+ final Integer printRateSecs = Integer.getInteger("printSaveStats");
+ if (printRateSecs != null && timeSince >= printRateSecs) {
+ final String timeStr = "/" + timeSince +"s";
+ final long queuedSaves = chunkLoader.getQueuedSaves();
+ long queuedDiff = queuedSaves - lastQueuedSaves;
+ lastQueuedSaves = queuedSaves;
- lastSaveStatPrinted = now;
- if (processedDiff > 0 || queueSize > 0 || queuedDiff > 0) {
- System.out.println("[Chunk Save Stats] " + world.worldData.getName() +
- " - Current: " + queueSize +
- " - Queued: " + queuedDiff + timeStr +
- " - Processed: " +processedDiff + timeStr
- );
- }
- }
+ final long processedSaves = chunkLoader.getProcessedSaves();
+ long processedDiff = processedSaves - lastProcessedSaves;
+ lastProcessedSaves = processedSaves;
- if (queueSize > world.paperConfig.queueSizeAutoSaveThreshold){
- return false;
- }
- final int autoSaveLimit = world.paperConfig.maxAutoSaveChunksPerTick;
- // Paper end
- while (iterator.hasNext()) {
- Chunk chunk = (Chunk) iterator.next();
-
- if (flag) {
- this.saveChunkNOP(chunk);
- }
-
- if (chunk.c(flag)) {
- this.saveChunk(chunk, false); // Spigot
- chunk.a(false);
- ++i;
- if (!flag && i >= autoSaveLimit) { // Spigot - // Paper - Incremental Auto Save - cap max per tick
- return false;
+ lastSaveStatPrinted = now;
+ if (processedDiff > 0 || queueSize > 0 || queuedDiff > 0) {
+ System.out.println("[Chunk Save Stats] " + world.worldData.getName() +
+ " - Current: " + queueSize +
+ " - Queued: " + queuedDiff + timeStr +
+ " - Processed: " +processedDiff + timeStr
+ );
}
}
- }
+ if (queueSize > world.paperConfig.queueSizeAutoSaveThreshold){
+ return false;
+ }
+ // Paper end
+ while (objectiterator.hasNext()) {
+ Chunk chunk = (Chunk) objectiterator.next();
- return true;
+ if (chunk.c(flag)) {
+ this.saveChunk(chunk, false); // Spigot
+ chunk.a(false);
+ ++i;
+ if (!flag && i >= world.paperConfig.maxAutoSaveChunksPerTick) { // Spigot - // Paper - Incremental Auto Save - cap max
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
}
public void close() {
try {
- this.g.a();
+ this.batchScheduler.a();
} catch (InterruptedException interruptedexception) {
ChunkProviderServer.a.error("Couldn\'t stop taskManager", interruptedexception);
}
@@ -335,12 +306,16 @@ public class ChunkProviderServer implements IChunkProvider {
}
public void c() {
- this.chunkLoader.c();
+ IChunkLoader ichunkloader = this.chunkLoader;
+
+ synchronized (this.chunkLoader) {
+ this.chunkLoader.b();
+ }
}
- private static final double UNLOAD_QUEUE_RESIZE_FACTOR = 0.96;
+ private static final double UNLOAD_QUEUE_RESIZE_FACTOR = 0.96; // Spigot
- public boolean unloadChunks() {
+ public boolean unloadChunks(BooleanSupplier booleansupplier) {
if (!this.world.savingDisabled) {
if (!this.unloadQueue.isEmpty()) {
// Spigot start
@@ -354,24 +329,26 @@ public class ChunkProviderServer implements IChunkProvider {
while (longiterator.hasNext()) { // Spigot
Long olong = (Long) longiterator.next();
longiterator.remove(); // Spigot
- Chunk chunk = (Chunk) this.chunks.get(olong);
+ IChunkLoader ichunkloader = this.chunkLoader;
- if (chunk != null && chunk.d) {
- // CraftBukkit start - move unload logic to own method
- chunk.setShouldUnload(false); // Paper
- if (!unloadChunk(chunk, true)) {
- continue;
- }
- // CraftBukkit end
+ synchronized (this.chunkLoader) {
+ Chunk chunk = (Chunk) this.chunks.get(olong);
- // Spigot start
- if (this.unloadQueue.size() <= targetSize && activityAccountant.activityTimeIsExhausted()) {
- break;
+ if (chunk != null) {
+ // CraftBukkit start - move unload logic to own method
+ if (!unloadChunk(chunk, true)) {
+ continue;
+ }
+ // CraftBukkit end
+
+ // Spigot start
+ if (!booleansupplier.getAsBoolean() && this.unloadQueue.size() <= targetSize && activityAccountant.activityTimeIsExhausted()) {
+ break;
+ }
+ // Spigot end
}
- // Spigot end
}
}
-
activityAccountant.endActivity(); // Spigot
}
// Paper start - delayed chunk unloads
@@ -388,8 +365,7 @@ public class ChunkProviderServer implements IChunkProvider {
}
// Paper end
- this.f.a();
- this.chunkLoader.b();
+ this.chunkScheduler.a(booleansupplier);
}
return false;
@@ -412,7 +388,7 @@ public class ChunkProviderServer implements IChunkProvider {
continue;
}
- Chunk neighbor = this.getChunkIfLoaded(chunk.locX + x, chunk.locZ + z);
+ Chunk neighbor = this.getChunkAt(chunk.locX + x, chunk.locZ + z, false, false);
if (neighbor != null) {
neighbor.setNeighborUnloaded(-x, -z);
chunk.setNeighborUnloaded(x, z);
@@ -423,14 +399,14 @@ public class ChunkProviderServer implements IChunkProvider {
chunk.removeEntities();
if (save) {
this.saveChunk(chunk, true); // Spigot
- this.saveChunkNOP(chunk);
}
this.chunks.remove(chunk.chunkKey);
+ //this.lastChunk = null; // Paper
return true;
}
// CraftBukkit end
- public boolean e() {
+ public boolean d() {
return !this.world.savingDisabled;
}
@@ -447,23 +423,19 @@ public class ChunkProviderServer implements IChunkProvider {
}
@Nullable
- public BlockPosition a(World world, String s, BlockPosition blockposition, int i) {
- return this.chunkGenerator.findNearestMapFeature(world, s, blockposition, i);
+ public BlockPosition a(World world, String s, BlockPosition blockposition, int i, boolean flag) {
+ return this.chunkGenerator.findNearestMapFeature(world, s, blockposition, i, flag);
}
public ChunkGenerator> getChunkGenerator() {
return this.chunkGenerator;
}
- public int h() {
+ public int g() {
return this.chunks.size();
}
public boolean isLoaded(int i, int j) {
return this.chunks.containsKey(ChunkCoordIntPair.a(i, j));
}
-
- public boolean f(int i, int j) {
- return this.chunks.containsKey(ChunkCoordIntPair.a(i, j)) || this.chunkLoader.chunkExists(i, j);
- }
}
diff --git a/sources/src/main/java/net/minecraft/server/Entity.java b/sources/src/main/java/net/minecraft/server/Entity.java
index 480a28664..3177aab41 100644
--- a/sources/src/main/java/net/minecraft/server/Entity.java
+++ b/sources/src/main/java/net/minecraft/server/Entity.java
@@ -57,7 +57,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
// CraftBukkit start
private static final int CURRENT_LEVEL = 2;
// Paper start
- public static Random SHARED_RANDOM = new java.util.Random() {
+ public static Random SHARED_RANDOM = new Random() {
private boolean locked = false;
@Override
public synchronized void setSeed(long seed) {
@@ -69,12 +69,13 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
}
}
};
- Object entitySlice = null;
+ List entitySlice = null;
// Paper end
static boolean isLevelAtLeast(NBTTagCompound tag, int level) {
return tag.hasKey("Bukkit.updateLevel") && tag.getInt("Bukkit.updateLevel") >= level;
}
+ public com.destroystokyo.paper.loottable.PaperLootableInventoryData lootableData; // Paper
protected CraftEntity bukkitEntity;
EntityTrackerEntry tracker; // Paper
@@ -102,7 +103,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
public boolean j; public boolean blocksEntitySpawning() { return j; } // Paper - OBFHELPER
public final List passengers;
protected int k;
- private Entity ax;
+ private Entity vehicle;
public boolean attachedToPlayer;
public World world;
public double lastX;
@@ -168,7 +169,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
public int portalCooldown;
protected boolean an; public boolean inPortal() { return an; } // Paper - OBFHELPER
protected int ao;
- public int dimension;
+ public DimensionManager dimension;
protected BlockPosition aq;
protected Vec3D ar;
protected EnumDirection as;
@@ -221,7 +222,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
this.world = world;
this.setPosition(0.0D, 0.0D, 0.0D);
if (world != null) {
- this.dimension = world.worldProvider.getDimensionManager().getDimensionID();
+ this.dimension = world.worldProvider.getDimensionManager();
// Spigot start
this.defaultActivationState = org.spigotmc.ActivationRange.initializeEntityActivationState(this, world.spigotConfig);
} else {
@@ -247,7 +248,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
return this.id;
}
- public void f(int i) {
+ public void e(int i) {
this.id = i;
}
@@ -376,15 +377,15 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
if (this.ao++ >= i) {
this.ao = i;
this.portalCooldown = this.aQ();
- byte b0;
+ DimensionManager dimensionmanager;
- if (this.world.worldProvider.getDimensionManager().getDimensionID() == -1) {
- b0 = 0;
+ if (this.world.worldProvider.getDimensionManager() == DimensionManager.NETHER) {
+ dimensionmanager = DimensionManager.OVERWORLD;
} else {
- b0 = -1;
+ dimensionmanager = DimensionManager.NETHER;
}
- this.d(b0);
+ this.a(dimensionmanager);
}
}
@@ -436,15 +437,15 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
if (this.ao++ >= i) {
this.ao = i;
this.portalCooldown = this.aQ();
- byte b0;
+ DimensionManager dimensionmanager;
- if (this.world.worldProvider.getDimensionManager().getDimensionID() == -1) {
- b0 = 0;
+ if (this.world.worldProvider.getDimensionManager() == DimensionManager.NETHER) {
+ dimensionmanager = DimensionManager.OVERWORLD;
} else {
- b0 = -1;
+ dimensionmanager = DimensionManager.NETHER;
}
- this.d(b0);
+ this.a(dimensionmanager);
}
}
@@ -528,29 +529,24 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
protected void burnFromLava() {
if (!this.fireProof) {
- this.damageEntity(DamageSource.LAVA, 4.0F);
-
// CraftBukkit start - Fallen in lava TODO: this event spams!
- if (this instanceof EntityLiving) {
- if (fireTicks <= 0) {
- // not on fire yet
- // TODO: shouldn't be sending null for the block
- org.bukkit.block.Block damager = null; // ((WorldServer) this.l).getWorld().getBlockAt(i, j, k);
- org.bukkit.entity.Entity damagee = this.getBukkitEntity();
- EntityCombustEvent combustEvent = new org.bukkit.event.entity.EntityCombustByBlockEvent(damager, damagee, 15);
- this.world.getServer().getPluginManager().callEvent(combustEvent);
+ if (this instanceof EntityLiving && fireTicks <= 0) {
+ // not on fire yet
+ // TODO: shouldn't be sending null for the block
+ org.bukkit.block.Block damager = null; // ((WorldServer) this.l).getWorld().getBlockAt(i, j, k);
+ org.bukkit.entity.Entity damagee = this.getBukkitEntity();
+ EntityCombustEvent combustEvent = new org.bukkit.event.entity.EntityCombustByBlockEvent(damager, damagee, 15);
+ this.world.getServer().getPluginManager().callEvent(combustEvent);
- if (!combustEvent.isCancelled()) {
- this.setOnFire(combustEvent.getDuration());
- }
- } else {
- // This will be called every single tick the entity is in lava, so don't throw an event
- this.setOnFire(15);
+ if (!combustEvent.isCancelled()) {
+ this.setOnFire(combustEvent.getDuration());
}
- return;
+ } else {
+ // This will be called every single tick the entity is in lava, so don't throw an event
+ this.setOnFire(15);
}
// CraftBukkit end - we also don't throw an event unless the object in lava is living, to save on some event calls
- this.setOnFire(15);
+ this.damageEntity(DamageSource.LAVA, 4.0F);
}
}
@@ -694,22 +690,22 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
AxisAlignedBB axisalignedbb = this.getBoundingBox();
if (d0 != 0.0D || d1 != 0.0D || d2 != 0.0D) {
- VoxelShape voxelshape = this.world.a(this, this.getBoundingBox(), d0, d1, d2);
+ StreamAccumulator streamaccumulator = new StreamAccumulator(this.world.a(this, this.getBoundingBox(), d0, d1, d2));
if (d1 != 0.0D) {
- d1 = VoxelShapes.a(EnumDirection.EnumAxis.Y, this.getBoundingBox(), voxelshape, d1);
+ d1 = VoxelShapes.a(EnumDirection.EnumAxis.Y, this.getBoundingBox(), streamaccumulator.a(), d1);
this.a(this.getBoundingBox().d(0.0D, d1, 0.0D));
}
if (d0 != 0.0D) {
- d0 = VoxelShapes.a(EnumDirection.EnumAxis.X, this.getBoundingBox(), voxelshape, d0);
+ d0 = VoxelShapes.a(EnumDirection.EnumAxis.X, this.getBoundingBox(), streamaccumulator.a(), d0);
if (d0 != 0.0D) {
this.a(this.getBoundingBox().d(d0, 0.0D, 0.0D));
}
}
if (d2 != 0.0D) {
- d2 = VoxelShapes.a(EnumDirection.EnumAxis.Z, this.getBoundingBox(), voxelshape, d2);
+ d2 = VoxelShapes.a(EnumDirection.EnumAxis.Z, this.getBoundingBox(), streamaccumulator.a(), d2);
if (d2 != 0.0D) {
this.a(this.getBoundingBox().d(0.0D, 0.0D, d2));
}
@@ -730,41 +726,41 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
d1 = (double) this.Q;
d2 = d9;
if (d7 != 0.0D || d1 != 0.0D || d9 != 0.0D) {
- VoxelShape voxelshape1 = this.world.a(this, this.getBoundingBox(), d7, d1, d9);
+ StreamAccumulator streamaccumulator1 = new StreamAccumulator(this.world.a(this, this.getBoundingBox(), d7, d1, d9));
AxisAlignedBB axisalignedbb2 = this.getBoundingBox();
AxisAlignedBB axisalignedbb3 = axisalignedbb2.b(d7, 0.0D, d9);
- d11 = VoxelShapes.a(EnumDirection.EnumAxis.Y, axisalignedbb3, voxelshape1, d1);
+ d11 = VoxelShapes.a(EnumDirection.EnumAxis.Y, axisalignedbb3, streamaccumulator1.a(), d1);
if (d11 != 0.0D) {
axisalignedbb2 = axisalignedbb2.d(0.0D, d11, 0.0D);
}
- double d15 = VoxelShapes.a(EnumDirection.EnumAxis.X, axisalignedbb2, voxelshape1, d7);
+ double d15 = VoxelShapes.a(EnumDirection.EnumAxis.X, axisalignedbb2, streamaccumulator1.a(), d7);
if (d15 != 0.0D) {
axisalignedbb2 = axisalignedbb2.d(d15, 0.0D, 0.0D);
}
- double d16 = VoxelShapes.a(EnumDirection.EnumAxis.Z, axisalignedbb2, voxelshape1, d9);
+ double d16 = VoxelShapes.a(EnumDirection.EnumAxis.Z, axisalignedbb2, streamaccumulator1.a(), d9);
if (d16 != 0.0D) {
axisalignedbb2 = axisalignedbb2.d(0.0D, 0.0D, d16);
}
AxisAlignedBB axisalignedbb4 = this.getBoundingBox();
- double d17 = VoxelShapes.a(EnumDirection.EnumAxis.Y, axisalignedbb4, voxelshape1, d1);
+ double d17 = VoxelShapes.a(EnumDirection.EnumAxis.Y, axisalignedbb4, streamaccumulator1.a(), d1);
if (d17 != 0.0D) {
axisalignedbb4 = axisalignedbb4.d(0.0D, d17, 0.0D);
}
- double d18 = VoxelShapes.a(EnumDirection.EnumAxis.X, axisalignedbb4, voxelshape1, d7);
+ double d18 = VoxelShapes.a(EnumDirection.EnumAxis.X, axisalignedbb4, streamaccumulator1.a(), d7);
if (d18 != 0.0D) {
axisalignedbb4 = axisalignedbb4.d(d18, 0.0D, 0.0D);
}
- double d19 = VoxelShapes.a(EnumDirection.EnumAxis.Z, axisalignedbb4, voxelshape1, d9);
+ double d19 = VoxelShapes.a(EnumDirection.EnumAxis.Z, axisalignedbb4, streamaccumulator1.a(), d9);
if (d19 != 0.0D) {
axisalignedbb4 = axisalignedbb4.d(0.0D, 0.0D, d19);
@@ -785,7 +781,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
this.a(axisalignedbb4);
}
- d1 = VoxelShapes.a(EnumDirection.EnumAxis.Y, this.getBoundingBox(), voxelshape1, d1);
+ d1 = VoxelShapes.a(EnumDirection.EnumAxis.Y, this.getBoundingBox(), streamaccumulator1.a(), d1);
if (d1 != 0.0D) {
this.a(this.getBoundingBox().d(0.0D, d1, 0.0D));
}
@@ -908,7 +904,6 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
boolean flag1 = this.ap();
if (this.world.b(this.getBoundingBox().shrink(0.001D))) {
- this.burn(1);
if (!flag1) {
++this.fireTicks;
if (this.fireTicks == 0) {
@@ -922,6 +917,8 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
// CraftBukkit end
}
}
+
+ this.burn(1);
} else if (this.fireTicks <= 0) {
this.fireTicks = -this.getMaxFireTicks();
}
@@ -1217,7 +1214,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
public boolean at() {
if (this.getVehicle() instanceof EntityBoat) {
this.inWater = false;
- } else if (this.b(TagsFluid.a)) {
+ } else if (this.b(TagsFluid.WATER)) {
if (!this.inWater && !this.justCreated) {
this.au();
}
@@ -1233,7 +1230,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
}
private void s() {
- this.X = this.a(TagsFluid.a);
+ this.X = this.a(TagsFluid.WATER);
}
protected void au() {
@@ -1590,7 +1587,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
nbttagcompound.setShort("Fire", (short) this.fireTicks);
nbttagcompound.setShort("Air", (short) this.getAirTicks());
nbttagcompound.setBoolean("OnGround", this.onGround);
- nbttagcompound.setInt("Dimension", this.dimension);
+ nbttagcompound.setInt("Dimension", this.dimension.getDimensionID());
nbttagcompound.setBoolean("Invulnerable", this.invulnerable);
nbttagcompound.setInt("PortalCooldown", this.portalCooldown);
nbttagcompound.a("UUID", this.getUniqueID());
@@ -1721,7 +1718,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
this.setAirTicks(nbttagcompound.getShort("Air"));
this.onGround = nbttagcompound.getBoolean("OnGround");
if (nbttagcompound.hasKey("Dimension")) {
- this.dimension = nbttagcompound.getInt("Dimension");
+ this.dimension = DimensionManager.a(nbttagcompound.getInt("Dimension"));
}
this.invulnerable = nbttagcompound.getBoolean("Invulnerable");
@@ -1801,8 +1798,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
}
if (bworld == null) {
- EntityPlayer entityPlayer = (EntityPlayer) this;
- bworld = ((org.bukkit.craftbukkit.CraftServer) server).getServer().getWorldServer(entityPlayer.dimension).getWorld();
+ bworld = ((org.bukkit.craftbukkit.CraftServer) server).getServer().getWorldServer(DimensionManager.OVERWORLD).getWorld();
}
spawnIn(bworld == null? null : ((CraftWorld) bworld).getHandle());
@@ -2056,8 +2052,8 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
}
public boolean a(Entity entity, boolean flag) {
- for (Entity entity1 = entity; entity1.ax != null; entity1 = entity1.ax) {
- if (entity1.ax == this) {
+ for (Entity entity1 = entity; entity1.vehicle != null; entity1 = entity1.vehicle) {
+ if (entity1.vehicle == this) {
return false;
}
}
@@ -2069,8 +2065,8 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
this.stopRiding();
}
- this.ax = entity;
- this.ax.o(this);
+ this.vehicle = entity;
+ this.vehicle.o(this);
return true;
}
}
@@ -2087,11 +2083,11 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
}
public void stopRiding() {
- if (this.ax != null) {
- Entity entity = this.ax;
+ if (this.vehicle != null) {
+ Entity entity = this.vehicle;
- this.ax = null;
- if (!entity.p(this)) this.ax = entity; // CraftBukkit
+ this.vehicle = null;
+ if (!entity.removePassenger(this)) this.vehicle = entity; // CraftBukkit
}
}
@@ -2135,7 +2131,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
}
}
- protected boolean p(Entity entity) { // CraftBukkit
+ protected boolean removePassenger(Entity entity) { // CraftBukkit
if (entity.getVehicle() == this) {
throw new IllegalStateException("Use x.stopRiding(y), not y.removePassenger(x)");
} else {
@@ -2342,11 +2338,24 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
}
public void onLightningStrike(EntityLightning entitylightning) {
+ ++this.fireTicks;
// CraftBukkit start
final org.bukkit.entity.Entity thisBukkitEntity = this.getBukkitEntity();
final org.bukkit.entity.Entity stormBukkitEntity = entitylightning.getBukkitEntity();
final PluginManager pluginManager = Bukkit.getPluginManager();
+ // CraftBukkit end
+ if (this.fireTicks == 0) {
+ // CraftBukkit start - Call a combust event when lightning strikes
+ EntityCombustByEntityEvent entityCombustEvent = new EntityCombustByEntityEvent(stormBukkitEntity, thisBukkitEntity, 8);
+ pluginManager.callEvent(entityCombustEvent);
+ if (!entityCombustEvent.isCancelled()) {
+ this.setOnFire(entityCombustEvent.getDuration());
+ }
+ // CraftBukkit end
+ }
+
+ // CraftBukkit start
if (thisBukkitEntity instanceof Hanging) {
HangingBreakByEntityEvent hangingEvent = new HangingBreakByEntityEvent((Hanging) thisBukkitEntity, stormBukkitEntity);
pluginManager.callEvent(hangingEvent);
@@ -2365,17 +2374,6 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
return;
}
// CraftBukkit end
- ++this.fireTicks;
- if (this.fireTicks == 0) {
- // CraftBukkit start - Call a combust event when lightning strikes
- EntityCombustByEntityEvent entityCombustEvent = new EntityCombustByEntityEvent(stormBukkitEntity, thisBukkitEntity, 8);
- pluginManager.callEvent(entityCombustEvent);
- if (!entityCombustEvent.isCancelled()) {
- this.setOnFire(entityCombustEvent.getDuration());
- }
- // CraftBukkit end
- }
-
}
public void j(boolean flag) {
@@ -2472,12 +2470,12 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
IChatBaseComponent ichatbasecomponent = this.getCustomName();
if (ichatbasecomponent != null) {
- IChatBaseComponent ichatbasecomponent1 = ichatbasecomponent.e();
+ IChatBaseComponent ichatbasecomponent1 = ichatbasecomponent.h();
c(ichatbasecomponent1);
return ichatbasecomponent1;
} else {
- return new ChatMessage(this.g.d(), new Object[0]);
+ return this.g.e();
}
}
@@ -2538,22 +2536,17 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
}
@Nullable
- public Entity d(int i) {
+ public Entity a(DimensionManager dimensionmanager) {
if (!this.world.isClientSide && !this.dead) {
this.world.methodProfiler.a("changeDimension");
MinecraftServer minecraftserver = this.bK();
// CraftBukkit start - Move logic into new function "teleportTo(Location,boolean)"
- // int j = this.dimension;
- // WorldServer worldserver = minecraftserver.getWorldServer(j);
- // WorldServer worldserver1 = minecraftserver.getWorldServer(i);
+ // DimensionManager dimensionmanager1 = this.dimension;
+ // WorldServer worldserver = minecraftserver.getWorldServer(dimensionmanager1);
+ // WorldServer worldserver1 = minecraftserver.getWorldServer(dimensionmanager);
WorldServer exitWorld = null;
- if (this.dimension < CraftWorld.CUSTOM_DIMENSION_OFFSET) { // Plugins must specify exit from custom Bukkit worlds
- // Only target existing worlds (compensate for allow-nether/allow-end as false)
- for (WorldServer world : minecraftserver.worlds) {
- if (world.dimension == i) {
- exitWorld = world;
- }
- }
+ if (this.dimension.getDimensionID() < CraftWorld.CUSTOM_DIMENSION_OFFSET) { // Plugins must specify exit from custom Bukkit worlds
+ exitWorld = minecraftserver.getWorldServer(dimensionmanager);
}
BlockPosition blockposition = null; // PAIL: CHECK
@@ -2563,13 +2556,13 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
if (blockposition != null) {
exit = new Location(exitWorld.getWorld(), blockposition.getX(), blockposition.getY(), blockposition.getZ());
} else {
- exit = minecraftserver.getPlayerList().calculateTarget(enter, minecraftserver.getWorldServer(i));
+ exit = minecraftserver.getPlayerList().calculateTarget(enter, exitWorld);
}
}
else {
exit = null;
}
- boolean useTravelAgent = exitWorld != null && !(this.dimension == 1 && exitWorld.dimension == 1); // don't use agent for custom worlds or return from THE_END
+ boolean useTravelAgent = exitWorld != null && !(this.dimension == DimensionManager.THE_END && exitWorld.dimension == DimensionManager.THE_END); // don't use agent for custom worlds or return from THE_END
TravelAgent agent = exit != null ? (TravelAgent) ((CraftWorld) exit.getWorld()).getHandle().getTravelAgent() : org.bukkit.craftbukkit.CraftTravelAgent.DEFAULT; // return arbitrary TA to compensate for implementation dependent plugins
boolean oldCanCreate = agent.getCanCreatePortal();
@@ -2589,22 +2582,23 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
Entity entity = this.teleportTo(exit, true);
this.world.methodProfiler.e();
return entity;
+ } else {
+ return null;
}
- return null;
}
public Entity teleportTo(Location exit, boolean portal) {
if (!this.dead) { // Paper
WorldServer worldserver = ((CraftWorld) getBukkitEntity().getLocation().getWorld()).getHandle();
WorldServer worldserver1 = ((CraftWorld) exit.getWorld()).getHandle();
- int i = worldserver1.dimension;
+ DimensionManager dimensionmanager = worldserver1.dimension;
// CraftBukkit end
- this.dimension = i;
+ this.dimension = dimensionmanager;
/* CraftBukkit start - TODO: Check if we need this
- if (j == 1 && i == 1) {
- worldserver1 = minecraftserver.a(DimensionManager.OVERWORLD);
- this.dimension = 0;
+ if (dimensionmanager1 == DimensionManager.THE_END && dimensionmanager == DimensionManager.THE_END) {
+ worldserver1 = minecraftserver.getWorldServer(DimensionManager.OVERWORLD);
+ this.dimension = DimensionManager.OVERWORLD;
}
// CraftBukkit end */
@@ -2614,17 +2608,17 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
/* CraftBukkit start - Handled in calculateTarget
BlockPosition blockposition;
- if (i == 1) {
+ if (dimensionmanager == DimensionManager.THE_END) {
blockposition = worldserver1.getDimensionSpawn();
} else {
double d0 = this.locX;
double d1 = this.locZ;
double d2 = 8.0D;
- if (i == -1) {
+ if (dimensionmanager == DimensionManager.NETHER) {
d0 = MathHelper.a(d0 / 8.0D, worldserver1.getWorldBorder().b() + 16.0D, worldserver1.getWorldBorder().d() - 16.0D);
d1 = MathHelper.a(d1 / 8.0D, worldserver1.getWorldBorder().c() + 16.0D, worldserver1.getWorldBorder().e() - 16.0D);
- } else if (i == 0) {
+ } else if (dimensionmanager == DimensionManager.OVERWORLD) {
d0 = MathHelper.a(d0 * 8.0D, worldserver1.getWorldBorder().b() + 16.0D, worldserver1.getWorldBorder().d() - 16.0D);
d1 = MathHelper.a(d1 * 8.0D, worldserver1.getWorldBorder().c() + 16.0D, worldserver1.getWorldBorder().e() - 16.0D);
}
@@ -2652,7 +2646,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
if (entity != null) {
entity.v(this);
/* CraftBukkit start - We need to do this...
- if (j == 1 && i == 1) {
+ if (dimensionmanager1 == DimensionManager.THE_END && dimensionmanager == DimensionManager.THE_END) {
BlockPosition blockposition1 = worldserver1.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING_NO_LEAVES, worldserver1.getSpawn());
entity.setPositionRotation(blockposition1, entity.yaw, entity.pitch);
@@ -2679,8 +2673,8 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
this.dead = true;
this.world.methodProfiler.e();
- worldserver.q_();
- worldserver1.q_();
+ worldserver.p();
+ worldserver1.p();
// this.world.methodProfiler.e(); // CraftBukkit: Moved up to keep balanced
return entity;
} else {
@@ -2801,7 +2795,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
return EnumDirection.fromAngle((double) this.yaw);
}
- public EnumDirection bB() {
+ public EnumDirection getAdjustedDirection() {
return this.getDirection();
}
@@ -3063,7 +3057,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
@Nullable
public Entity getVehicle() {
- return this.ax;
+ return this.vehicle;
}
public EnumPistonReaction getPushReaction() {
@@ -3086,7 +3080,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
return 0;
}
- public boolean k(int i) {
+ public boolean j(int i) {
return this.y() >= i;
}
diff --git a/sources/src/main/java/net/minecraft/server/EntityPlayer.java b/sources/src/main/java/net/minecraft/server/EntityPlayer.java
index f09710bc7..b422dc793 100644
--- a/sources/src/main/java/net/minecraft/server/EntityPlayer.java
+++ b/sources/src/main/java/net/minecraft/server/EntityPlayer.java
@@ -5,12 +5,16 @@ import com.mojang.authlib.GameProfile;
import io.akarin.api.internal.mixin.IMixinWorldServer;
import io.netty.buffer.Unpooled;
+import io.netty.util.concurrent.Future;
+import io.netty.util.concurrent.GenericFutureListener;
import java.util.ArrayDeque; // Paper
import java.util.ArrayList;
import java.util.Collection;
import java.util.Deque; // Paper
import java.util.Iterator;
+import java.util.List;
import java.util.Random;
+import java.util.function.Consumer;
import javax.annotation.Nullable;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -35,12 +39,11 @@ import org.bukkit.inventory.MainHand;
/**
* Akarin Changes Note
- * 2) Add lock to player track (safety issue)
+ * 1) Add lock to player track (safety issue)
*/
public class EntityPlayer extends EntityHuman implements ICrafting {
private static final Logger cc = LogManager.getLogger();
- private static final IChatBaseComponent cd = (new ChatMessage("multiplayer.message_not_delivered", new Object[0])).a(EnumChatFormat.RED);
public String locale = null; // CraftBukkit - lowercase // Paper - default to null
public long lastSave = MinecraftServer.currentTick; // Paper
public PlayerConnection playerConnection;
@@ -49,30 +52,30 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
public double d;
public double e;
public final Deque removeQueue = new ArrayDeque<>(); // Paper
- private final AdvancementDataPlayer cg;
- private final ServerStatisticManager ch;
- private float ci = Float.MIN_VALUE;
+ private final AdvancementDataPlayer cf;
+ private final ServerStatisticManager cg;
+ private float ch = Float.MIN_VALUE;
+ private int ci = Integer.MIN_VALUE;
private int cj = Integer.MIN_VALUE;
private int ck = Integer.MIN_VALUE;
private int cl = Integer.MIN_VALUE;
private int cm = Integer.MIN_VALUE;
- private int cn = Integer.MIN_VALUE;
private float lastHealthSent = -1.0E8F;
- private int cp = -99999999;
- private boolean cq = true;
+ private int co = -99999999;
+ private boolean cp = true;
public int lastSentExp = -99999999;
public int invulnerableTicks = 60;
- private EntityHuman.EnumChatVisibility ct;
- private boolean cu = true;
- private long cv = SystemUtils.b();
- private Entity cw;
+ private EntityHuman.EnumChatVisibility cs;
+ private boolean ct = true;
+ private long cu = SystemUtils.b();
+ private Entity cv;
public boolean worldChangeInvuln;
- private boolean cy; private void setHasSeenCredits(boolean has) { this.cy = has; } // Paper - OBFHELPER
- private final RecipeBookServer cz;
- private Vec3D cA;
- private int cB;
- private boolean cC;
- private Vec3D cD;
+ private boolean cx; private void setHasSeenCredits(boolean has) { this.cx = has; } // Paper - OBFHELPER
+ private final RecipeBookServer cy;
+ private Vec3D cz;
+ private int cA;
+ private boolean cB;
+ private Vec3D cC;
private int containerCounter;
public boolean f;
public int ping;
@@ -106,9 +109,9 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
playerinteractmanager.player = this;
this.playerInteractManager = playerinteractmanager;
this.server = minecraftserver;
- this.cz = new RecipeBookServer(minecraftserver.getCraftingManager());
- this.ch = minecraftserver.getPlayerList().getStatisticManager(this);
- this.cg = minecraftserver.getPlayerList().h(this);
+ this.cy = new RecipeBookServer(minecraftserver.getCraftingManager());
+ this.cg = minecraftserver.getPlayerList().getStatisticManager(this);
+ this.cf = minecraftserver.getPlayerList().h(this);
this.Q = 1.0F;
this.a(worldserver);
@@ -136,7 +139,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
}
int k = (i * 2 + 1) * (i * 2 + 1);
- int l = this.s(k);
+ int l = this.r(k);
int i1 = (new Random()).nextInt(k);
for (int j1 = 0; j1 < k; ++j1) {
@@ -171,7 +174,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
}
int k = (i * 2 + 1) * (i * 2 + 1);
- int l = this.s(k);
+ int l = this.r(k);
int i1 = (new Random()).nextInt(k);
for (int j1 = 0; j1 < k; ++j1) {
@@ -197,7 +200,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
}
- private int s(int i) {
+ private int r(int i) {
return i <= 16 ? i - 1 : 17;
}
@@ -215,12 +218,12 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
if (nbttagcompound.hasKeyOfType("enteredNetherPosition", 10)) {
NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("enteredNetherPosition");
- this.cD = new Vec3D(nbttagcompound1.getDouble("x"), nbttagcompound1.getDouble("y"), nbttagcompound1.getDouble("z"));
+ this.cC = new Vec3D(nbttagcompound1.getDouble("x"), nbttagcompound1.getDouble("y"), nbttagcompound1.getDouble("z"));
}
- this.cy = nbttagcompound.getBoolean("seenCredits");
+ this.cx = nbttagcompound.getBoolean("seenCredits");
if (nbttagcompound.hasKeyOfType("recipeBook", 10)) {
- this.cz.a(nbttagcompound.getCompound("recipeBook"));
+ this.cy.a(nbttagcompound.getCompound("recipeBook"));
}
this.getBukkitEntity().readExtraData(nbttagcompound); // CraftBukkit
@@ -229,13 +232,13 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
public void b(NBTTagCompound nbttagcompound) {
super.b(nbttagcompound);
nbttagcompound.setInt("playerGameType", this.playerInteractManager.getGameMode().getId());
- nbttagcompound.setBoolean("seenCredits", this.cy);
- if (this.cD != null) {
+ nbttagcompound.setBoolean("seenCredits", this.cx);
+ if (this.cC != null) {
NBTTagCompound nbttagcompound1 = new NBTTagCompound();
- nbttagcompound1.setDouble("x", this.cD.x);
- nbttagcompound1.setDouble("y", this.cD.y);
- nbttagcompound1.setDouble("z", this.cD.z);
+ nbttagcompound1.setDouble("x", this.cC.x);
+ nbttagcompound1.setDouble("y", this.cC.y);
+ nbttagcompound1.setDouble("z", this.cC.z);
nbttagcompound.set("enteredNetherPosition", nbttagcompound1);
}
@@ -265,7 +268,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
nbttagcompound.set("RootVehicle", nbttagcompound2);
}
- nbttagcompound.set("recipeBook", this.cz.e());
+ nbttagcompound.set("recipeBook", this.cy.e());
this.getBukkitEntity().setExtraData(nbttagcompound); // CraftBukkit
}
@@ -365,7 +368,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
while (!this.removeQueue.isEmpty()) {
int i = Math.min(this.removeQueue.size(), Integer.MAX_VALUE);
int[] aint = new int[i];
- Iterator iterator = this.removeQueue.iterator();
+ //Iterator iterator = this.removeQueue.iterator(); // Paper
int j = 0;
// Paper start
@@ -398,11 +401,11 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
}
CriterionTriggers.w.a(this);
- if (this.cA != null) {
- CriterionTriggers.u.a(this, this.cA, this.ticksLived - this.cB);
+ if (this.cz != null) {
+ CriterionTriggers.u.a(this, this.cz, this.ticksLived - this.cA);
}
- this.cg.b(this);
+ this.cf.b(this);
}
public void playerTick() {
@@ -421,36 +424,36 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
}
}
- if (this.getHealth() != this.lastHealthSent || this.cp != this.foodData.getFoodLevel() || this.foodData.getSaturationLevel() == 0.0F != this.cq) {
+ if (this.getHealth() != this.lastHealthSent || this.co != this.foodData.getFoodLevel() || this.foodData.getSaturationLevel() == 0.0F != this.cp) {
this.playerConnection.sendPacket(new PacketPlayOutUpdateHealth(this.getBukkitEntity().getScaledHealth(), this.foodData.getFoodLevel(), this.foodData.getSaturationLevel())); // CraftBukkit
this.lastHealthSent = this.getHealth();
- this.cp = this.foodData.getFoodLevel();
- this.cq = this.foodData.getSaturationLevel() == 0.0F;
+ this.co = this.foodData.getFoodLevel();
+ this.cp = this.foodData.getSaturationLevel() == 0.0F;
}
- if (this.getHealth() + this.getAbsorptionHearts() != this.ci) {
- this.ci = this.getHealth() + this.getAbsorptionHearts();
- this.a(IScoreboardCriteria.g, MathHelper.f(this.ci));
+ if (this.getHealth() + this.getAbsorptionHearts() != this.ch) {
+ this.ch = this.getHealth() + this.getAbsorptionHearts();
+ this.a(IScoreboardCriteria.g, MathHelper.f(this.ch));
}
- if (this.foodData.getFoodLevel() != this.cj) {
- this.cj = this.foodData.getFoodLevel();
- this.a(IScoreboardCriteria.h, MathHelper.f((float) this.cj));
+ if (this.foodData.getFoodLevel() != this.ci) {
+ this.ci = this.foodData.getFoodLevel();
+ this.a(IScoreboardCriteria.h, MathHelper.f((float) this.ci));
}
- if (this.getAirTicks() != this.ck) {
- this.ck = this.getAirTicks();
- this.a(IScoreboardCriteria.i, MathHelper.f((float) this.ck));
+ if (this.getAirTicks() != this.cj) {
+ this.cj = this.getAirTicks();
+ this.a(IScoreboardCriteria.i, MathHelper.f((float) this.cj));
}
- if (this.getArmorStrength() != this.cl) {
- this.cl = this.getArmorStrength();
- this.a(IScoreboardCriteria.j, MathHelper.f((float) this.cl));
+ if (this.getArmorStrength() != this.ck) {
+ this.ck = this.getArmorStrength();
+ this.a(IScoreboardCriteria.j, MathHelper.f((float) this.ck));
}
- if (this.expTotal != this.cn) {
- this.cn = this.expTotal;
- this.a(IScoreboardCriteria.k, MathHelper.f((float) this.cn));
+ if (this.expTotal != this.cm) {
+ this.cm = this.expTotal;
+ this.a(IScoreboardCriteria.k, MathHelper.f((float) this.cm));
}
// CraftBukkit start - Force max health updates
@@ -459,9 +462,9 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
}
// CraftBukkit end
- if (this.expLevel != this.cm) {
- this.cm = this.expLevel;
- this.a(IScoreboardCriteria.l, MathHelper.f((float) this.cm));
+ if (this.expLevel != this.cl) {
+ this.cl = this.expLevel;
+ this.a(IScoreboardCriteria.l, MathHelper.f((float) this.cl));
}
if (this.expTotal != this.lastSentExp) {
@@ -501,8 +504,6 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
public void die(DamageSource damagesource) {
boolean flag = this.world.getGameRules().getBoolean("showDeathMessages");
-
- this.playerConnection.sendPacket(new PacketPlayOutCombatEvent(this.getCombatTracker(), PacketPlayOutCombatEvent.EnumCombatEventType.ENTITY_DIED, flag));
// CraftBukkit start - fire PlayerDeathEvent
if (this.dead) {
return;
@@ -518,29 +519,46 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
}
}
- IChatBaseComponent chatmessage = this.getCombatTracker().getDeathMessage();
+ IChatBaseComponent defaultMessage = this.getCombatTracker().getDeathMessage();
- String deathmessage = chatmessage.getString();
+ String deathmessage = defaultMessage.getString();
org.bukkit.event.entity.PlayerDeathEvent event = CraftEventFactory.callPlayerDeathEvent(this, loot, deathmessage, keepInventory);
String deathMessage = event.getDeathMessage();
if (deathMessage != null && deathMessage.length() > 0 && flag) { // TODO: allow plugins to override?
+ IChatBaseComponent ichatbasecomponent;
if (deathMessage.equals(deathmessage)) {
- ScoreboardTeamBase scoreboardteambase = this.be();
+ ichatbasecomponent = this.getCombatTracker().getDeathMessage();
+ } else {
+ ichatbasecomponent = org.bukkit.craftbukkit.util.CraftChatMessage.fromStringOrNull(deathMessage);
+ }
- if (scoreboardteambase != null && scoreboardteambase.getDeathMessageVisibility() != ScoreboardTeamBase.EnumNameTagVisibility.ALWAYS) {
- if (scoreboardteambase.getDeathMessageVisibility() == ScoreboardTeamBase.EnumNameTagVisibility.HIDE_FOR_OTHER_TEAMS) {
- this.server.getPlayerList().a((EntityHuman) this, chatmessage);
- } else if (scoreboardteambase.getDeathMessageVisibility() == ScoreboardTeamBase.EnumNameTagVisibility.HIDE_FOR_OWN_TEAM) {
- this.server.getPlayerList().b((EntityHuman) this, chatmessage);
- }
- } else {
- this.server.getPlayerList().sendMessage(chatmessage);
+ this.playerConnection.a((Packet) (new PacketPlayOutCombatEvent(this.getCombatTracker(), PacketPlayOutCombatEvent.EnumCombatEventType.ENTITY_DIED, ichatbasecomponent)), (future) -> {
+ if (!future.isSuccess()) {
+ String s = ichatbasecomponent.a(256);
+ ChatMessage chatmessage = new ChatMessage("death.attack.message_too_long", new Object[] { (new ChatComponentText(s)).a(EnumChatFormat.YELLOW)});
+ IChatBaseComponent ichatbasecomponent1 = (new ChatMessage("death.attack.even_more_magic", new Object[] { this.getScoreboardDisplayName()})).a((chatmodifier) -> {
+ chatmodifier.setChatHoverable(new ChatHoverable(ChatHoverable.EnumHoverAction.SHOW_TEXT, chatmessage));
+ });
+
+ this.playerConnection.sendPacket(new PacketPlayOutCombatEvent(this.getCombatTracker(), PacketPlayOutCombatEvent.EnumCombatEventType.ENTITY_DIED, ichatbasecomponent1));
+ }
+
+ });
+ ScoreboardTeamBase scoreboardteambase = this.be();
+
+ if (scoreboardteambase != null && scoreboardteambase.getDeathMessageVisibility() != ScoreboardTeamBase.EnumNameTagVisibility.ALWAYS) {
+ if (scoreboardteambase.getDeathMessageVisibility() == ScoreboardTeamBase.EnumNameTagVisibility.HIDE_FOR_OTHER_TEAMS) {
+ this.server.getPlayerList().a((EntityHuman) this, ichatbasecomponent);
+ } else if (scoreboardteambase.getDeathMessageVisibility() == ScoreboardTeamBase.EnumNameTagVisibility.HIDE_FOR_OWN_TEAM) {
+ this.server.getPlayerList().b((EntityHuman) this, ichatbasecomponent);
}
} else {
- this.server.getPlayerList().sendMessage(org.bukkit.craftbukkit.util.CraftChatMessage.fromString(deathMessage));
+ this.server.getPlayerList().sendMessage(ichatbasecomponent);
}
+ } else {
+ this.playerConnection.sendPacket(new PacketPlayOutCombatEvent(this.getCombatTracker(), PacketPlayOutCombatEvent.EnumCombatEventType.ENTITY_DIED));
}
this.releaseShoulderEntities();
@@ -555,7 +573,6 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
// CraftBukkit - Get our scores instead
this.world.getServer().getScoreboardManager().getScoreboardScores(IScoreboardCriteria.d, this.getName(), ScoreboardScore::incrementScore);
-
EntityLiving entityliving = this.cv();
if (entityliving != null) {
@@ -565,7 +582,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
this.a(StatisticList.DEATHS);
this.a(StatisticList.CUSTOM.b(StatisticList.TIME_SINCE_DEATH));
- this.a(StatisticList.CUSTOM.b(StatisticList.n));
+ this.a(StatisticList.CUSTOM.b(StatisticList.TIME_SINCE_REST));
this.extinguish();
this.setFlag(0, false);
this.getCombatTracker().g();
@@ -612,7 +629,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
if (this.isInvulnerable(damagesource)) {
return false;
} else {
- boolean flag = this.server.S() && this.canPvP() && "fall".equals(damagesource.translationIndex);
+ boolean flag = this.server.Q() && this.canPvP() && "fall".equals(damagesource.translationIndex);
if (!flag && this.invulnerableTicks > 0 && damagesource != DamageSource.OUT_OF_WORLD) {
return false;
@@ -626,8 +643,9 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
if (entity instanceof EntityArrow) {
EntityArrow entityarrow = (EntityArrow) entity;
+ Entity entity1 = entityarrow.getShooter();
- if (entityarrow.shooter instanceof EntityHuman && !this.a((EntityHuman) entityarrow.shooter)) {
+ if (entity1 instanceof EntityHuman && !this.a((EntityHuman) entity1)) {
return false;
}
}
@@ -648,39 +666,39 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
}
@Nullable
- public Entity d(int i) {
+ public Entity a(DimensionManager dimensionmanager) {
if (this.isSleeping()) return this; // CraftBukkit - SPIGOT-3154
// this.worldChangeInvuln = true; // CraftBukkit - Moved down and into PlayerList#changeDimension
- if (this.dimension == 0 && i == -1) {
- this.cD = new Vec3D(this.locX, this.locY, this.locZ);
- } else if (this.dimension != -1 && i != 0) {
- this.cD = null;
+ if (this.dimension == DimensionManager.OVERWORLD && dimensionmanager == DimensionManager.NETHER) {
+ this.cC = new Vec3D(this.locX, this.locY, this.locZ);
+ } else if (this.dimension != DimensionManager.NETHER && dimensionmanager != DimensionManager.OVERWORLD) {
+ this.cC = null;
}
- if (this.dimension == 1 && i == 1) {
+ if (this.dimension == DimensionManager.THE_END && dimensionmanager == DimensionManager.THE_END) {
this.worldChangeInvuln = true; // CraftBukkit - Moved down from above
this.world.kill(this);
if (!this.viewingCredits) {
this.viewingCredits = true;
if (world.paperConfig.disableEndCredits) this.setHasSeenCredits(true); // Paper - Toggle to always disable end credits
- this.playerConnection.sendPacket(new PacketPlayOutGameStateChange(4, this.cy ? 0.0F : 1.0F));
- this.cy = true;
+ this.playerConnection.sendPacket(new PacketPlayOutGameStateChange(4, this.cx ? 0.0F : 1.0F));
+ this.cx = true;
}
return this;
} else {
- if (this.dimension == 0 && i == 1) {
- i = 1;
+ if (this.dimension == DimensionManager.OVERWORLD && dimensionmanager == DimensionManager.THE_END) {
+ dimensionmanager = DimensionManager.THE_END;
}
// CraftBukkit start
- TeleportCause cause = (this.dimension == 1 || i == 1) ? TeleportCause.END_PORTAL : TeleportCause.NETHER_PORTAL;
- this.server.getPlayerList().changeDimension(this, i, cause); // PAIL: check all this
+ TeleportCause cause = (this.dimension == DimensionManager.THE_END || i == DimensionManager.THE_END) ? TeleportCause.END_PORTAL : TeleportCause.NETHER_PORTAL;
+ this.server.getPlayerList().changeDimension(this, dimensionmanager, cause); // PAIL: check all this
// CraftBukkit end
this.playerConnection.sendPacket(new PacketPlayOutWorldEvent(1032, BlockPosition.ZERO, 0, false));
this.lastSentExp = -1;
this.lastHealthSent = -1.0F;
- this.cp = -1;
+ this.co = -1;
return this;
}
}
@@ -766,7 +784,6 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
synchronized (((IMixinWorldServer) worldServer).trackLock()) { // Akarin
worldServer.tracker.track(this);
}
- worldServer.tracker.track(this);
}
// Paper end
@@ -818,10 +835,10 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
public void openTileEntity(ITileEntityContainer itileentitycontainer) {
// CraftBukkit start - Inventory open hook
- if (false && itileentitycontainer instanceof ILootable && ((ILootable) itileentitycontainer).Q_() != null && this.isSpectator()) {
+ if (false && itileentitycontainer instanceof ILootable && ((ILootable) itileentitycontainer).getLootTable() != null && this.isSpectator()) {
this.a((new ChatMessage("container.spectatorCantOpen", new Object[0])).a(EnumChatFormat.RED), true);
} else {
- boolean cancelled = itileentitycontainer instanceof ILootable && ((ILootable) itileentitycontainer).Q_() != null && this.isSpectator();
+ boolean cancelled = itileentitycontainer instanceof ILootable && ((ILootable) itileentitycontainer).getLootTable()!= null && this.isSpectator();
Container container = CraftEventFactory.callInventoryOpenEvent(this, itileentitycontainer.createContainer(this.inventory, this), cancelled);
if (container == null) {
return;
@@ -860,7 +877,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
}
// CraftBukkit end
- if (iinventory instanceof ILootable && ((ILootable) iinventory).Q_() != null && this.isSpectator()) {
+ if (iinventory instanceof ILootable && ((ILootable) iinventory).getLootTable() != null && this.isSpectator()) {
this.a((new ChatMessage("container.spectatorCantOpen", new Object[0])).a(EnumChatFormat.RED), true);
} else {
if (this.activeContainer != this.defaultContainer) {
@@ -1033,19 +1050,19 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
}
public void a(Statistic> statistic, int i) {
- this.ch.b(this, statistic, i);
+ this.cg.b(this, statistic, i);
this.world.getServer().getScoreboardManager().getScoreboardScores(statistic, this.getName(), (scoreboardscore) -> { // CraftBukkit - Get our scores instead
scoreboardscore.addScore(i);
});
}
public void a(Statistic> statistic) {
- this.ch.setStatistic(this, statistic, 0);
+ this.cg.setStatistic(this, statistic, 0);
this.world.getServer().getScoreboardManager().getScoreboardScores(statistic, this.getName(), ScoreboardScore::c); // CraftBukkit - Get our scores instead
}
public int a(Collection collection) {
- return this.cz.a(collection, this);
+ return this.cy.a(collection, this);
}
public void a(MinecraftKey[] aminecraftkey) {
@@ -1066,7 +1083,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
}
public int b(Collection collection) {
- return this.cz.b(collection, this);
+ return this.cy.b(collection, this);
}
public void giveExp(int i) {
@@ -1075,7 +1092,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
}
public void n() {
- this.cC = true;
+ this.cB = true;
this.ejectPassengers();
if (this.sleeping) {
this.a(true, false, false);
@@ -1084,7 +1101,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
}
public boolean o() {
- return this.cC;
+ return this.cB;
}
public void triggerHealthUpdate() {
@@ -1149,15 +1166,18 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
this.getDataWatcher().set(EntityPlayer.bx, entityplayer.getDataWatcher().get(EntityPlayer.bx));
this.lastSentExp = -1;
this.lastHealthSent = -1.0F;
- this.cp = -1;
- // this.cz.a((RecipeBook) entityplayer.cz); // CraftBukkit
- // Paper start - Optimize remove queue
+ this.co = -1;
+ // this.cy.a((RecipeBook) entityplayer.cy); // CraftBukkit
+ // Paper start - Optimize remove queue - vanilla copies player objects, but CB doesn't. This method currently only
+ // Applies to the same player, so we need to not duplicate our removal queue. The rest of this method does "resetting"
+ // type logic so it does need to be called, maybe? This is silly.
//this.removeQueue.addAll(entityplayer.removeQueue);
if (this.removeQueue != entityplayer.removeQueue) {
this.removeQueue.addAll(entityplayer.removeQueue);
}
- this.cy = entityplayer.cy;
- this.cD = entityplayer.cD;
+ // Paper end
+ this.cx = entityplayer.cx;
+ this.cC = entityplayer.cC;
this.setShoulderEntityLeft(entityplayer.getShoulderEntityLeft());
this.setShoulderEntityRight(entityplayer.getShoulderEntityRight());
}
@@ -1166,8 +1186,8 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
super.a(mobeffect);
this.playerConnection.sendPacket(new PacketPlayOutEntityEffect(this.getId(), mobeffect));
if (mobeffect.getMobEffect() == MobEffects.LEVITATION) {
- this.cB = this.ticksLived;
- this.cA = new Vec3D(this.locX, this.locY, this.locZ);
+ this.cA = this.ticksLived;
+ this.cz = new Vec3D(this.locX, this.locY, this.locZ);
}
CriterionTriggers.A.a(this);
@@ -1183,7 +1203,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
super.b(mobeffect);
this.playerConnection.sendPacket(new PacketPlayOutRemoveEntityEffect(this.getId(), mobeffect.getMobEffect()));
if (mobeffect.getMobEffect() == MobEffects.LEVITATION) {
- this.cA = null;
+ this.cz = null;
}
CriterionTriggers.A.a(this);
@@ -1253,7 +1273,11 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
public void a(IChatBaseComponent ichatbasecomponent, ChatMessageType chatmessagetype) {
this.playerConnection.a((Packet) (new PacketPlayOutChat(ichatbasecomponent, chatmessagetype)), (future) -> {
if (!future.isSuccess() && (chatmessagetype == ChatMessageType.GAME_INFO || chatmessagetype == ChatMessageType.SYSTEM)) {
- this.playerConnection.sendPacket(new PacketPlayOutChat(EntityPlayer.cd, ChatMessageType.SYSTEM));
+ boolean flag = true;
+ String s = ichatbasecomponent.a(256);
+ IChatBaseComponent ichatbasecomponent1 = (new ChatComponentText(s)).a(EnumChatFormat.YELLOW);
+
+ this.playerConnection.sendPacket(new PacketPlayOutChat((new ChatMessage("multiplayer.message_not_delivered", new Object[] { ichatbasecomponent1})).a(EnumChatFormat.RED), ChatMessageType.SYSTEM));
}
});
@@ -1273,7 +1297,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
PlayerChangedMainHandEvent event = new PlayerChangedMainHandEvent(getBukkitEntity(), getMainHand() == EnumMainHand.LEFT ? MainHand.LEFT : MainHand.RIGHT);
this.server.server.getPluginManager().callEvent(event);
}
- if (this.locale == null || !this.locale.equals(packetplayinsettings.b())) { // Paper - fix bug and check for null
+ if (this.locale == null || !this.locale.equals(packetplayinsettings.b())) { // Paper - check for null
PlayerLocaleChangeEvent event = new PlayerLocaleChangeEvent(getBukkitEntity(), packetplayinsettings.b());
this.server.server.getPluginManager().callEvent(event);
}
@@ -1286,14 +1310,14 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
new com.destroystokyo.paper.event.player.PlayerLocaleChangeEvent(this.getBukkitEntity(), oldLocale, this.locale).callEvent();
}
// Paper end
- this.ct = packetplayinsettings.d();
- this.cu = packetplayinsettings.e();
+ this.cs = packetplayinsettings.d();
+ this.ct = packetplayinsettings.e();
this.getDataWatcher().set(EntityPlayer.bx, Byte.valueOf((byte) packetplayinsettings.f()));
this.getDataWatcher().set(EntityPlayer.by, Byte.valueOf((byte) (packetplayinsettings.getMainHand() == EnumMainHand.LEFT ? 0 : 1)));
}
public EntityHuman.EnumChatVisibility getChatFlags() {
- return this.ct;
+ return this.cs;
}
public void setResourcePack(String s, String s1) {
@@ -1305,15 +1329,15 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
}
public void resetIdleTimer() {
- this.cv = SystemUtils.b();
+ this.cu = SystemUtils.b();
}
public ServerStatisticManager getStatisticManager() {
- return this.ch;
+ return this.cg;
}
public RecipeBookServer B() {
- return this.cz;
+ return this.cy;
}
public void c(Entity entity) {
@@ -1341,16 +1365,16 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
}
public Entity getSpecatorTarget() {
- return (Entity) (this.cw == null ? this : this.cw);
+ return (Entity) (this.cv == null ? this : this.cv);
}
public void setSpectatorTarget(Entity entity) {
Entity entity1 = this.getSpecatorTarget();
- this.cw = (Entity) (entity == null ? this : entity);
- if (entity1 != this.cw) {
- this.playerConnection.sendPacket(new PacketPlayOutCamera(this.cw));
- this.playerConnection.a(this.cw.locX, this.cw.locY, this.cw.locZ, this.yaw, this.pitch, TeleportCause.SPECTATE); // CraftBukkit
+ this.cv = (Entity) (entity == null ? this : entity);
+ if (entity1 != this.cv) {
+ this.playerConnection.sendPacket(new PacketPlayOutCamera(this.cv));
+ this.playerConnection.a(this.cv.locX, this.cv.locY, this.cv.locZ, this.yaw, this.pitch, TeleportCause.SPECTATE); // CraftBukkit
}
}
@@ -1372,7 +1396,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
}
public long F() {
- return this.cv;
+ return this.cu;
}
@Nullable
@@ -1408,12 +1432,12 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
}
public AdvancementDataPlayer getAdvancementData() {
- return this.cg;
+ return this.cf;
}
@Nullable
public Vec3D M() {
- return this.cD;
+ return this.cC;
}
// CraftBukkit start
@@ -1431,7 +1455,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
} else {
WorldServer worldserver1 = this.getWorldServer();
- this.dimension = worldserver.worldProvider.getDimensionManager().getDimensionID();
+ this.dimension = worldserver.worldProvider.getDimensionManager();
this.playerConnection.sendPacket(new PacketPlayOutRespawn(this.dimension, worldserver1.getDifficulty(), worldserver1.getWorldData().getType(), this.playerInteractManager.getGameMode()));
this.server.getPlayerList().f(this);
worldserver1.removeEntity(this);
diff --git a/sources/src/main/java/net/minecraft/server/ItemEnderEye.java b/sources/src/main/java/net/minecraft/server/ItemEnderEye.java
index 0a382120a..2b5ebd6c1 100644
--- a/sources/src/main/java/net/minecraft/server/ItemEnderEye.java
+++ b/sources/src/main/java/net/minecraft/server/ItemEnderEye.java
@@ -23,15 +23,15 @@ public class ItemEnderEye extends Item {
} else {
IBlockData iblockdata1 = (IBlockData) iblockdata.set(BlockEnderPortalFrame.EYE, Boolean.valueOf(true));
- Block.a(iblockdata, iblockdata1, (GeneratorAccess) world, blockposition);
+ Block.a(iblockdata, iblockdata1, world, blockposition);
world.setTypeAndData(blockposition, iblockdata1, 2);
world.updateAdjacentComparators(blockposition, Blocks.END_PORTAL_FRAME);
itemactioncontext.getItemStack().subtract(1);
for (int i = 0; i < 16; ++i) {
- double d0 = (double) ((float) blockposition.getX() + (5.0F + ItemEnderEye.k.nextFloat() * 6.0F) / 16.0F);
+ double d0 = (double) ((float) blockposition.getX() + (5.0F + ItemEnderEye.i.nextFloat() * 6.0F) / 16.0F);
double d1 = (double) ((float) blockposition.getY() + 0.8125F);
- double d2 = (double) ((float) blockposition.getZ() + (5.0F + ItemEnderEye.k.nextFloat() * 6.0F) / 16.0F);
+ double d2 = (double) ((float) blockposition.getZ() + (5.0F + ItemEnderEye.i.nextFloat() * 6.0F) / 16.0F);
double d3 = 0.0D;
double d4 = 0.0D;
double d5 = 0.0D;
@@ -71,7 +71,7 @@ public class ItemEnderEye extends Item {
} else {
entityhuman.c(enumhand);
if (!world.isClientSide) {
- BlockPosition blockposition = ((WorldServer) world).getChunkProviderServer().a(world, "Stronghold", new BlockPosition(entityhuman), 100);
+ BlockPosition blockposition = ((WorldServer) world).getChunkProviderServer().a(world, "Stronghold", new BlockPosition(entityhuman), 100, false);
if (blockposition != null) {
EntityEnderSignal entityendersignal = new EntityEnderSignal(world, entityhuman.locX, entityhuman.locY + (double) (entityhuman.length / 2.0F), entityhuman.locZ);
@@ -82,7 +82,7 @@ public class ItemEnderEye extends Item {
CriterionTriggers.m.a((EntityPlayer) entityhuman, blockposition);
}
- world.a((EntityHuman) null, entityhuman.locX, entityhuman.locY, entityhuman.locZ, SoundEffects.ENTITY_ENDER_EYE_LAUNCH, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemEnderEye.k.nextFloat() * 0.4F + 0.8F));
+ world.a((EntityHuman) null, entityhuman.locX, entityhuman.locY, entityhuman.locZ, SoundEffects.ENTITY_ENDER_EYE_LAUNCH, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemEnderEye.i.nextFloat() * 0.4F + 0.8F));
world.a((EntityHuman) null, 1003, new BlockPosition(entityhuman), 0);
if (!entityhuman.abilities.canInstantlyBuild) {
itemstack.subtract(1);
diff --git a/sources/src/main/java/net/minecraft/server/NetworkManager.java b/sources/src/main/java/net/minecraft/server/NetworkManager.java
index 30520ad98..57da82f5a 100644
--- a/sources/src/main/java/net/minecraft/server/NetworkManager.java
+++ b/sources/src/main/java/net/minecraft/server/NetworkManager.java
@@ -20,6 +20,8 @@ import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
import java.net.SocketAddress;
import java.util.Queue;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.function.Supplier;
import javax.annotation.Nullable;
import javax.crypto.SecretKey;
import org.apache.commons.lang3.Validate;
@@ -48,7 +50,7 @@ public class NetworkManager extends SimpleChannelInboundHandler> {
return new DefaultEventLoopGroup(0, (new ThreadFactoryBuilder()).setNameFormat("Netty Local Client IO #%d").setDaemon(true).build());
});
private final EnumProtocolDirection h;
- private final Queue i = Queues.newConcurrentLinkedQueue();
+ private final Queue i = Queues.newConcurrentLinkedQueue(); private final Queue getPacketQueue() { return this.i; } // Paper - OBFHELPER
private final ReentrantReadWriteUpdateLock j = new ReentrantReadWriteUpdateLock(); // Akarin - use update lock
public Channel channel;
// Spigot Start // PAIL
@@ -162,8 +164,8 @@ public class NetworkManager extends SimpleChannelInboundHandler> {
}
public void sendPacket(Packet> packet, @Nullable GenericFutureListener extends Future super Void>> genericfuturelistener) {
- if (this.isConnected()) {
- this.o();
+ if (this.isConnected() && this.sendPacketQueue() && !(packet instanceof PacketPlayOutMapChunk && !((PacketPlayOutMapChunk) packet).isReady())) { // Paper - Async-Anti-Xray - Add chunk packets which are not ready or all packets if the packet queue contains chunk packets which are not ready to the packet queue and send the packets later in the right order
+ //this.o(); // Paper - Async-Anti-Xray - Move to if statement (this.sendPacketQueue())
this.b(packet, genericfuturelistener);
} else {
this.j.writeLock().lock();
@@ -177,6 +179,7 @@ public class NetworkManager extends SimpleChannelInboundHandler> {
}
+ private void dispatchPacket(Packet> packet, @Nullable GenericFutureListener extends Future super Void>> genericFutureListener) { this.b(packet, genericFutureListener); } // Paper - OBFHELPER
private void b(Packet> packet, @Nullable GenericFutureListener extends Future super Void>> genericfuturelistener) {
EnumProtocol enumprotocol = EnumProtocol.a(packet);
EnumProtocol enumprotocol1 = (EnumProtocol) this.channel.attr(NetworkManager.c).get();
@@ -217,22 +220,38 @@ public class NetworkManager extends SimpleChannelInboundHandler> {
}
- private void o() {
+ // Paper start - Async-Anti-Xray - Stop dispatching further packets and return false if the peeked packet is a chunk packet which is not ready
+ private boolean sendPacketQueue() { return this.o(); } // OBFHELPER // void -> boolean
+ private boolean o() { // void -> boolean
if (this.channel != null && this.channel.isOpen()) {
- this.j.updateLock().lock(); // Akarin
+ if (this.i.isEmpty()) { // return if the packet queue is empty so that the write lock by Anti-Xray doesn't affect the vanilla performance at all
+ return true;
+ }
+
+ this.j.writeLock().lock(); // readLock -> writeLock (because of race condition between peek and poll)
try {
while (!this.i.isEmpty()) {
- NetworkManager.QueuedPacket networkmanager_queuedpacket = (NetworkManager.QueuedPacket) this.i.poll();
+ NetworkManager.QueuedPacket networkmanager_queuedpacket = (NetworkManager.QueuedPacket) this.getPacketQueue().peek(); // poll -> peek
- this.b(networkmanager_queuedpacket.a, networkmanager_queuedpacket.b);
+ if (networkmanager_queuedpacket != null) { // Fix NPE (Spigot bug caused by handleDisconnection())
+ if (networkmanager_queuedpacket.getPacket() instanceof PacketPlayOutMapChunk && !((PacketPlayOutMapChunk) networkmanager_queuedpacket.getPacket()).isReady()) { // Check if the peeked packet is a chunk packet which is not ready
+ return false; // Return false if the peeked packet is a chunk packet which is not ready
+ } else {
+ this.getPacketQueue().poll(); // poll here
+ this.dispatchPacket(networkmanager_queuedpacket.getPacket(), networkmanager_queuedpacket.getGenericFutureListener()); // dispatch the packet
+ }
+ }
}
} finally {
- this.j.updateLock().unlock(); // Akarin
+ this.j.writeLock().unlock(); // readLock -> writeLock (because of race condition between peek and poll)
}
}
+
+ return true; // Return true if all packets were dispatched
}
+ // Paper end
public void a() {
this.o();
@@ -345,11 +364,11 @@ public class NetworkManager extends SimpleChannelInboundHandler> {
this.a(channelhandlercontext, (Packet) object);
}
- static class QueuedPacket {
+ public static class QueuedPacket { // Akarin
- private final Packet> a;
+ private final Packet> a; public final Packet> getPacket() { return this.a; } // Paper - OBFHELPER // Akarin
@Nullable
- private final GenericFutureListener extends Future super Void>> b;
+ private final GenericFutureListener extends Future super Void>> b; public final GenericFutureListener extends Future super Void>> getGenericFutureListener() { return this.b; } // Paper - OBFHELPER // Akarin
public QueuedPacket(Packet> packet, @Nullable GenericFutureListener extends Future super Void>> genericfuturelistener) {
this.a = packet;
diff --git a/sources/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java b/sources/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java
index 30fdc2f22..63cdcdac0 100644
--- a/sources/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java
+++ b/sources/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java
@@ -1,9 +1,11 @@
package net.minecraft.server;
+import com.destroystokyo.paper.antixray.ChunkPacketInfo; // Paper - Anti-Xray
import com.google.common.collect.Lists;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import java.io.IOException;
+import java.security.KeyStore.PrivateKeyEntry;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
@@ -17,20 +19,33 @@ public class PacketPlayOutMapChunk implements Packet {
private int a;
private int b;
private int c;
- private ByteBuf d; // Akarin - byte[] -> ByteBuf
+ private ByteBuf d; private ByteBuf getData() { return this.d; } // Paper - OBFHELPER // Akarin - byte[] -> ByteBuf
private List e;
private boolean f;
+ private volatile boolean ready = false; // Paper - Async-Anti-Xray - Ready flag for the network manager
- public PacketPlayOutMapChunk() {}
+ // Paper start - Async-Anti-Xray - Set the ready flag to true
+ public PacketPlayOutMapChunk() {
+ this.ready = true;
+ }
+ // Paper end
public PacketPlayOutMapChunk(Chunk chunk, int i) {
+ ChunkPacketInfo chunkPacketInfo = chunk.world.chunkPacketBlockController.getChunkPacketInfo(this, chunk, i); // Paper - Anti-Xray - Add chunk packet info
this.a = chunk.locX;
this.b = chunk.locZ;
this.f = i == '\uffff';
boolean flag = chunk.getWorld().worldProvider.g();
this.d = allocateBuffer(this.a(chunk, flag, i)); // Akarin
- this.c = this.a(new PacketDataSerializer(this.d), chunk, flag, i); // Akarin
+
+ // Paper start - Anti-Xray - Add chunk packet info
+ if (chunkPacketInfo != null) {
+ chunkPacketInfo.setData(this.getData());
+ }
+ // Paper end
+
+ this.c = this.writeChunk(new PacketDataSerializer(this.getData()), chunk, flag, i, chunkPacketInfo); // Paper - Anti-Xray - Add chunk packet info // Akarin
this.e = Lists.newArrayList();
Iterator iterator = chunk.getTileEntities().entrySet().iterator();
@@ -48,8 +63,19 @@ public class PacketPlayOutMapChunk implements Packet {
}
}
+ chunk.world.chunkPacketBlockController.modifyBlocks(this, chunkPacketInfo); // Paper - Anti-Xray - Modify blocks
}
+ // Paper start - Async-Anti-Xray - Getter and Setter for the ready flag
+ public boolean isReady() {
+ return this.ready;
+ }
+
+ public void setReady(boolean ready) {
+ this.ready = ready;
+ }
+ // Paper end
+
public void a(PacketDataSerializer packetdataserializer) throws IOException {
this.a = packetdataserializer.readInt();
this.b = packetdataserializer.readInt();
@@ -78,8 +104,8 @@ public class PacketPlayOutMapChunk implements Packet {
packetdataserializer.writeInt(this.b);
packetdataserializer.writeBoolean(this.f);
packetdataserializer.d(this.c);
- packetdataserializer.d(this.d.array().length); // Akarin
- packetdataserializer.writeBytes(this.d.array()); // Akarin
+ packetdataserializer.d(this.getData().capacity()); // Akarin
+ packetdataserializer.writeBytes(this.getData().array()); // Akarin
packetdataserializer.d(this.e.size());
Iterator iterator = this.e.iterator();
@@ -95,15 +121,23 @@ public class PacketPlayOutMapChunk implements Packet {
packetlistenerplayout.a(this);
}
- private ByteBuf allocateBuffer(int expectedCapacity) { return h(expectedCapacity); } // Akarin - OBFHELPER
- private ByteBuf h(int expectedCapacity) { // Akarin - added argument
- ByteBuf bytebuf = Unpooled.buffer(expectedCapacity); // Akarin
+ private ByteBuf h() { return allocateBuffer(-1); } // Akarin
+ private ByteBuf allocateBuffer(int expectedCapacity) { // Akarin - added argument
+ ByteBuf bytebuf = expectedCapacity == -1 ? Unpooled.buffer() : Unpooled.buffer(expectedCapacity); // Akarin
bytebuf.writerIndex(0);
return bytebuf;
}
+ // Paper start - Anti-Xray - Support default methods
+ public int writeChunk(PacketDataSerializer packetDataSerializer, Chunk chunk, boolean writeSkyLightArray, int chunkSectionSelector) { return this.a(packetDataSerializer, chunk, writeSkyLightArray, chunkSectionSelector); }
public int a(PacketDataSerializer packetdataserializer, Chunk chunk, boolean flag, int i) {
+ return this.a(packetdataserializer, chunk, flag, i, null);
+ }
+ // Paper end
+
+ public int writeChunk(PacketDataSerializer packetDataSerializer, Chunk chunk, boolean writeSkyLightArray, int chunkSectionSelector, ChunkPacketInfo chunkPacketInfo) { return this.a(packetDataSerializer, chunk, writeSkyLightArray, chunkSectionSelector, chunkPacketInfo); } // Paper - OBFHELPER // Paper - Anti-Xray - Add chunk packet info
+ public int a(PacketDataSerializer packetdataserializer, Chunk chunk, boolean flag, int i, ChunkPacketInfo chunkPacketInfo) { // Paper - Anti-Xray - Add chunk packet info
int j = 0;
ChunkSection[] achunksection = chunk.getSections();
int k = 0;
@@ -115,7 +149,7 @@ public class PacketPlayOutMapChunk implements Packet {
if (chunksection != Chunk.a && (!this.f() || !chunksection.a()) && (i & 1 << k) != 0) {
j |= 1 << k;
- chunksection.getBlocks().b(packetdataserializer);
+ chunksection.getBlocks().writeDataPaletteBlock(packetdataserializer, chunkPacketInfo, k); // Paper - Anti-Xray - Add chunk packet info
packetdataserializer.writeBytes(chunksection.getEmittedLightArray().asBytes());
if (flag) {
packetdataserializer.writeBytes(chunksection.getSkyLightArray().asBytes());
@@ -127,7 +161,7 @@ public class PacketPlayOutMapChunk implements Packet {
BiomeBase[] abiomebase = chunk.getBiomeIndex();
for (l = 0; l < abiomebase.length; ++l) {
- packetdataserializer.writeInt(BiomeBase.REGISTRY_ID.a((BiomeBase) abiomebase[l]));
+ packetdataserializer.writeInt(IRegistry.BIOME.a(abiomebase[l])); // Paper - decompile fix
}
}
@@ -161,4 +195,4 @@ public class PacketPlayOutMapChunk implements Packet {
public boolean f() {
return this.f;
}
-}
\ No newline at end of file
+}
diff --git a/sources/src/main/java/net/minecraft/server/PlayerConnection.java b/sources/src/main/java/net/minecraft/server/PlayerConnection.java
index ae78daf0b..70cc49d82 100644
--- a/sources/src/main/java/net/minecraft/server/PlayerConnection.java
+++ b/sources/src/main/java/net/minecraft/server/PlayerConnection.java
@@ -2,7 +2,9 @@ package net.minecraft.server;
import com.google.common.primitives.Doubles;
import com.google.common.primitives.Floats;
+import com.google.common.util.concurrent.Futures;
import com.mojang.brigadier.ParseResults;
+import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.suggestion.Suggestions;
import io.akarin.api.internal.Akari;
@@ -10,16 +12,18 @@ import io.akarin.server.core.AkarinGlobalConfig;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
import java.util.Collections;
+import java.util.Iterator;
import java.util.Set;
+import java.util.function.Consumer;
import javax.annotation.Nullable;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+// CraftBukkit start
+import java.util.HashSet;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
-
-import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.craftbukkit.entity.CraftPlayer;
import org.bukkit.craftbukkit.event.CraftEventFactory;
@@ -58,6 +62,7 @@ import org.bukkit.inventory.CraftingInventory;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.InventoryView;
import org.bukkit.util.NumberConversions;
+import com.destroystokyo.paper.event.player.IllegalPacketEvent; // Paper
import com.destroystokyo.paper.event.player.PlayerJumpEvent; // Paper
import co.aikar.timings.MinecraftTimings; // Paper
// CraftBukkit end
@@ -109,7 +114,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable {
private int E;
private int receivedMovePackets;
private int processedMovePackets;
- private static final long KEEPALIVE_LIMIT = /*Long.getLong("paper.playerconnection.keepalive", 30)*/ AkarinGlobalConfig.keepAliveTimeout * 1000; // Paper - provide property to set keepalive limit // Akarin - more accessible - keep changes
+ private static final long KEEPALIVE_LIMIT = /*Long.getLong("paper.playerconnection.keepalive", 30)*/ AkarinGlobalConfig.keepAliveTimeout * 1000; // Paper - provide property to set keepalive limit // Akarin - more accessible
public PlayerConnection(MinecraftServer minecraftserver, NetworkManager networkmanager, EntityPlayer entityplayer) {
this.minecraftServer = minecraftserver;
@@ -351,7 +356,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable {
}
speed *= 2f; // TODO: Get the speed of the vehicle instead of the player
- if (d10 - d9 > Math.max(100.0D, Math.pow((double) (org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed), 2)) && (!this.minecraftServer.J() || !this.minecraftServer.I().equals(entity.getDisplayName().getString()))) {
+ if (d10 - d9 > Math.max(100.0D, Math.pow((double) (org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed), 2)) && (!this.minecraftServer.H() || !this.minecraftServer.G().equals(entity.getDisplayName().getString()))) {
// CraftBukkit end
PlayerConnection.LOGGER.warn("{} (vehicle of {}) moved too quickly! {},{},{}", entity.getDisplayName().getString(), this.player.getDisplayName().getString(), Double.valueOf(d6), Double.valueOf(d7), Double.valueOf(d8));
this.networkManager.sendPacket(new PacketPlayOutVehicleMove(entity));
@@ -473,10 +478,10 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable {
PlayerConnectionUtils.ensureMainThread(packetplayinteleportaccept, this, this.player.getWorldServer());
if (packetplayinteleportaccept.b() == this.teleportAwait && this.teleportPos != null) { // CraftBukkit
this.player.setLocation(this.teleportPos.x, this.teleportPos.y, this.teleportPos.z, this.player.yaw, this.player.pitch);
+ this.o = this.teleportPos.x;
+ this.p = this.teleportPos.y;
+ this.q = this.teleportPos.z;
if (this.player.H()) {
- this.o = this.teleportPos.x;
- this.p = this.teleportPos.y;
- this.q = this.teleportPos.z;
this.player.I();
}
@@ -523,6 +528,13 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable {
minecraftServer.postToMainThread(() -> this.disconnect(new ChatMessage("disconnect.spam", new Object[0]))); // Paper
return;
}
+ // CraftBukkit end
+ StringReader stringreader = new StringReader(packetplayintabcomplete.c());
+
+ if (stringreader.canRead() && stringreader.peek() == 47) {
+ stringreader.skip();
+ }
+
// Paper start
com.destroystokyo.paper.event.server.AsyncTabCompleteEvent event;
java.util.List completions = new java.util.ArrayList<>();
@@ -770,12 +782,13 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable {
return;
}
this.lastBookTick = MinecraftServer.currentTick;
+ EnumItemSlot enumitemslot = packetplayinbedit.d() == EnumHand.MAIN_HAND ? EnumItemSlot.MAINHAND : EnumItemSlot.OFFHAND;
// CraftBukkit end
ItemStack itemstack = packetplayinbedit.b();
if (!itemstack.isEmpty()) {
if (ItemBookAndQuill.b(itemstack.getTag())) {
- ItemStack itemstack1 = this.player.getItemInMainHand();
+ ItemStack itemstack1 = this.player.b(packetplayinbedit.d());
if (!itemstack1.isEmpty()) {
if (itemstack.getItem() == Items.WRITABLE_BOOK && itemstack1.getItem() == Items.WRITABLE_BOOK) {
@@ -795,10 +808,13 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable {
}
itemstack2.a("pages", (NBTBase) nbttaglist);
- CraftEventFactory.handleEditBookEvent(player, itemstack2); // CraftBukkit
+ // EnumItemSlot enumitemslot = packetplayinbedit.d() == EnumHand.MAIN_HAND ? EnumItemSlot.MAINHAND : EnumItemSlot.OFFHAND; // CraftBukkit - Moved up
+
+ this.player.setSlot(enumitemslot, CraftEventFactory.handleEditBookEvent(player, enumitemslot, itemstack1, itemstack2)); // CraftBukkit
} else {
+ ItemStack old = itemstack1.cloneItemStack(); // CraftBukkit
itemstack1.a("pages", (NBTBase) itemstack.getTag().getList("pages", 8));
- CraftEventFactory.handleEditBookEvent(player, itemstack1); // CraftBukkit
+ CraftEventFactory.handleEditBookEvent(player, enumitemslot, old, itemstack1); // CraftBukkit
}
}
@@ -809,7 +825,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable {
public void a(PacketPlayInEntityNBTQuery packetplayinentitynbtquery) {
PlayerConnectionUtils.ensureMainThread(packetplayinentitynbtquery, this, this.player.getWorldServer());
- if (this.player.k(2)) {
+ if (this.player.j(2)) {
Entity entity = this.player.getWorldServer().getEntity(packetplayinentitynbtquery.c());
if (entity != null) {
@@ -823,7 +839,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable {
public void a(PacketPlayInTileNBTQuery packetplayintilenbtquery) {
PlayerConnectionUtils.ensureMainThread(packetplayintilenbtquery, this, this.player.getWorldServer());
- if (this.player.k(2)) {
+ if (this.player.j(2)) {
TileEntity tileentity = this.player.getWorldServer().getTileEntity(packetplayintilenbtquery.c());
NBTTagCompound nbttagcompound = tileentity != null ? tileentity.save(new NBTTagCompound()) : null;
@@ -912,7 +928,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable {
if (!this.player.H() && (!this.player.getWorldServer().getGameRules().getBoolean("disableElytraMovementCheck") || !this.player.dc())) {
float f2 = this.player.dc() ? 300.0F : 100.0F;
- if (d11 - d10 > Math.max(f2, Math.pow((double) (org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed), 2)) && (!this.minecraftServer.J() || !this.minecraftServer.I().equals(this.player.getProfile().getName()))) {
+ if (d11 - d10 > Math.max(f2, Math.pow((double) (org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed), 2)) && (!this.minecraftServer.H() || !this.minecraftServer.G().equals(this.player.getProfile().getName()))) {
// CraftBukkit end
PlayerConnection.LOGGER.warn("{} moved too quickly! {},{},{}", this.player.getDisplayName().getString(), Double.valueOf(d7), Double.valueOf(d8), Double.valueOf(d9));
this.a(this.player.locX, this.player.locY, this.player.locZ, this.player.yaw, this.player.pitch);
@@ -1158,6 +1174,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable {
this.A = this.e;
this.player.setLocation(d0, d1, d2, f, f1);
this.player.playerConnection.sendPacket(new PacketPlayOutPosition(d0 - d3, d1 - d4, d2 - d5, f - f2, f1 - f3, set, this.teleportAwait));
+ this.minecraftServer.getPlayerList().d(this.player); // CraftBukkit
}
public void a(PacketPlayInBlockDig packetplayinblockdig) {
@@ -1384,17 +1401,14 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable {
PlayerConnectionUtils.ensureMainThread(packetplayinspectate, this, this.player.getWorldServer());
if (this.player.isSpectator()) {
Entity entity = null;
- WorldServer[] aworldserver = this.minecraftServer.worldServer;
- int i = aworldserver.length;
+ Iterator iterator = this.minecraftServer.getWorlds().iterator();
- // CraftBukkit - use the worlds array list
- for (WorldServer worldserver : minecraftServer.worlds) {
+ while (iterator.hasNext()) {
+ WorldServer worldserver = (WorldServer) iterator.next();
- if (worldserver != null) {
- entity = packetplayinspectate.a(worldserver);
- if (entity != null) {
- break;
- }
+ entity = packetplayinspectate.a(worldserver);
+ if (entity != null) {
+ break;
}
}
@@ -1433,7 +1447,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable {
PlayerConnection.LOGGER.info("{} lost connection: {}", this.player.getDisplayName().getString(), ichatbasecomponent.getString());
// CraftBukkit start - Replace vanilla quit message handling with our own.
/*
- this.minecraftServer.av();
+ this.minecraftServer.at();
this.minecraftServer.getPlayerList().sendMessage((new ChatMessage("multiplayer.player.left", new Object[] { this.player.getScoreboardDisplayName()})).a(EnumChatFormat.YELLOW));
*/
@@ -1443,7 +1457,7 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable {
this.minecraftServer.getPlayerList().sendMessage(CraftChatMessage.fromString(quitMessage));
}
// CraftBukkit end
- if (this.minecraftServer.J() && this.player.getDisplayName().getString().equals(this.minecraftServer.I())) {
+ if (this.minecraftServer.H() && this.player.getDisplayName().getString().equals(this.minecraftServer.G())) {
PlayerConnection.LOGGER.info("Stopping singleplayer server as player logged out");
this.minecraftServer.safeShutdown();
}
@@ -2030,15 +2044,15 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable {
case PERFORM_RESPAWN:
if (this.player.viewingCredits) {
this.player.viewingCredits = false;
- // this.player = this.minecraftServer.getPlayerList().moveToWorld(this.player, 0, true);
- this.minecraftServer.getPlayerList().changeDimension(this.player, 0, PlayerTeleportEvent.TeleportCause.END_PORTAL); // CraftBukkit - reroute logic through custom portal management
+ // this.player = this.minecraftServer.getPlayerList().moveToWorld(this.player, DimensionManager.OVERWORLD, true);
+ this.minecraftServer.getPlayerList().changeDimension(this.player, DimensionManager.OVERWORLD, PlayerTeleportEvent.TeleportCause.END_PORTAL); // CraftBukkit - reroute logic through custom portal management
CriterionTriggers.v.a(this.player, DimensionManager.THE_END, DimensionManager.OVERWORLD);
} else {
if (this.player.getHealth() > 0.0F) {
return;
}
- this.player = this.minecraftServer.getPlayerList().moveToWorld(this.player, 0, false);
+ this.player = this.minecraftServer.getPlayerList().moveToWorld(this.player, DimensionManager.OVERWORLD, false);
if (this.minecraftServer.isHardcore()) {
this.player.a(EnumGamemode.SPECTATOR);
this.player.getWorldServer().getGameRules().set("spectatorsGenerateChunks", "false", this.minecraftServer);
@@ -2544,10 +2558,10 @@ public class PlayerConnection implements PacketListenerPlayIn, ITickable {
this.player.ping = (this.player.ping * 3 + i) / 4;
this.g = false;
- } else if (!this.player.getDisplayName().getString().equals(this.minecraftServer.I())) {
+ } else if (!this.player.getDisplayName().getString().equals(this.minecraftServer.G())) {
// Paper start - This needs to be handled on the main thread for plugins
minecraftServer.postToMainThread(() -> {
- this.disconnect(new ChatMessage("disconnect.timeout", new Object[0]));
+ this.disconnect(new ChatMessage("disconnect.timeout", new Object[0]));
});
// Paper end
}
diff --git a/sources/src/main/java/net/minecraft/server/TileEntitySkull.java b/sources/src/main/java/net/minecraft/server/TileEntitySkull.java
index faa5471b0..372b0d540 100644
--- a/sources/src/main/java/net/minecraft/server/TileEntitySkull.java
+++ b/sources/src/main/java/net/minecraft/server/TileEntitySkull.java
@@ -87,7 +87,7 @@ public class TileEntitySkull extends TileEntity /*implements ITickable*/ { // Pa
// Spigot end
public TileEntitySkull() {
- super(TileEntityTypes.p);
+ super(TileEntityTypes.SKULL);
}
public static void a(UserCache usercache) {
@@ -113,12 +113,12 @@ public class TileEntitySkull extends TileEntity /*implements ITickable*/ { // Pa
public void load(NBTTagCompound nbttagcompound) {
super.load(nbttagcompound);
if (nbttagcompound.hasKeyOfType("Owner", 10)) {
- this.a = GameProfileSerializer.deserialize(nbttagcompound.getCompound("Owner"));
+ this.setGameProfile(GameProfileSerializer.deserialize(nbttagcompound.getCompound("Owner")));
} else if (nbttagcompound.hasKeyOfType("ExtraType", 8)) {
String s = nbttagcompound.getString("ExtraType");
if (!UtilColor.b(s)) {
- this.a = new GameProfile((UUID) null, s);
+ this.setGameProfile(new GameProfile((UUID) null, s));
this.f();
}
}
@@ -143,7 +143,7 @@ public class TileEntitySkull extends TileEntity /*implements ITickable*/ { // Pa
public GameProfile getGameProfile() {
return this.a;
}
-
+
// Paper start
static NBTTagCompound sanitizeTileEntityUUID(NBTTagCompound cmp) {
NBTTagCompound owner = cmp.getCompound("Owner");
diff --git a/sources/src/main/java/net/minecraft/server/WorldServer.java b/sources/src/main/java/net/minecraft/server/WorldServer.java
index ded33901b..59abde338 100644
--- a/sources/src/main/java/net/minecraft/server/WorldServer.java
+++ b/sources/src/main/java/net/minecraft/server/WorldServer.java
@@ -1,19 +1,22 @@
package net.minecraft.server;
+import co.aikar.timings.Timings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.util.concurrent.ListenableFuture;
import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.UUID;
+import java.util.function.BooleanSupplier;
+import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.apache.logging.log4j.LogManager;
@@ -23,6 +26,10 @@ import org.apache.logging.log4j.Logger;
import java.util.logging.Level;
import org.bukkit.WeatherType;
+import org.bukkit.block.BlockState;
+import org.bukkit.craftbukkit.util.HashTreeSet;
+
+import org.bukkit.event.block.BlockFormEvent;
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
import org.bukkit.event.weather.LightningStrikeEvent;
// CraftBukkit end
@@ -41,7 +48,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
public final PlayerChunkMap manager; // Akarin - private -> public
public final Map entitiesByUUID = Maps.newHashMap(); // Paper
public boolean savingDisabled;
- private boolean K;
+ private boolean J;
private int emptyTime;
private final PortalTravelAgent portalTravelAgent;
private final SpawnerCreature spawnerCreature = new SpawnerCreature();
@@ -49,74 +56,73 @@ public class WorldServer extends World implements IAsyncTaskHandler {
private final TickListServer nextTickListFluid;
protected final VillageSiege siegeManager;
ObjectLinkedOpenHashSet d;
- private boolean Q;
+ private boolean P;
// CraftBukkit start
+ public final DimensionManager dimension;
private static final boolean DEBUG_ENTITIES = Boolean.getBoolean("debug.entities"); // Paper
private static Throwable getAddToWorldStackTrace(Entity entity) {
return new Throwable(entity + " Added to world at " + new java.util.Date());
}
- public final int dimension;
// Add env and gen to constructor
- public WorldServer(MinecraftServer minecraftserver, IDataManager idatamanager, WorldData worlddata, int i, MethodProfiler methodprofiler, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) {
- super(idatamanager, worlddata, DimensionManager.a(env.getId()).d(), methodprofiler, false, gen, env);
- this.dimension = i;
+ public WorldServer(MinecraftServer minecraftserver, IDataManager idatamanager, PersistentCollection persistentcollection, WorldData worlddata, DimensionManager dimensionmanager, MethodProfiler methodprofiler, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) {
+ super(idatamanager, persistentcollection, worlddata, DimensionManager.a(env.getId()).e(), methodprofiler, false, gen, env);
+ this.dimension = dimensionmanager;
this.pvpMode = minecraftserver.getPVP();
worlddata.world = this;
// CraftBukkit end
Predicate predicate = (block) -> { // CraftBukkit - decompile error
return block == null || block.getBlockData().isAir();
};
- RegistryBlocks registryblocks = Block.REGISTRY;
+ IRegistry iregistry = IRegistry.BLOCK;
- Block.REGISTRY.getClass();
- Function function = registryblocks::b;
- RegistryBlocks registryblocks1 = Block.REGISTRY; // CraftBukkit - decompile error
+ IRegistry.BLOCK.getClass();
+ Function function = iregistry::getKey;
+ IRegistry iregistry1 = IRegistry.BLOCK; // CraftBukkit - decompile error
- Block.REGISTRY.getClass();
- this.nextTickListBlock = new TickListServer<>(this, predicate, function, key -> registryblocks1.get((MinecraftKey) key), e -> b((NextTickListEntry) e), "Blocks"); // CraftBukkit - decompile error // Paper - Timings v2 // Akarin - decompile error
- Predicate predicate2 = (fluidtype) -> {
+ IRegistry.BLOCK.getClass();
+ this.nextTickListBlock = new TickListServer<>(this, predicate, function, iregistry1::getOrDefault, this::b, "Blocks"); // CraftBukkit - decompile error // Paper - Timings v2
+ Predicate predicate2 = (fluidtype) -> { // CraftBukkit - decompile error
return fluidtype == null || fluidtype == FluidTypes.a;
};
- registryblocks = FluidType.c;
- FluidType.c.getClass();
- function = registryblocks::b;
- RegistryBlocks registryblocks2 = FluidType.c; // CraftBukkit - decompile error
- FluidType.c.getClass();
- this.nextTickListFluid = new TickListServer<>(this, predicate2, function, registryblocks2::get, e -> a((NextTickListEntry) e), "Fluids"); // CraftBukkit - decompile error // Paper - Timings v2 // Akarin - decompile error
+ iregistry = IRegistry.FLUID;
+ IRegistry.FLUID.getClass();
+ function = iregistry::getKey;
+ IRegistry iregistry2 = IRegistry.FLUID; // CraftBukkit - decompile error
+ IRegistry.FLUID.getClass();
+ this.nextTickListFluid = new TickListServer<>(this, predicate2, function, iregistry2::getOrDefault, this::a, "Fluids"); // CraftBukkit - decompile error // Paper - Timings v2
this.siegeManager = new VillageSiege(this);
this.d = new ObjectLinkedOpenHashSet();
this.server = minecraftserver;
this.tracker = new EntityTracker(this);
this.manager = new PlayerChunkMap(this);
this.worldProvider.a((World) this);
- this.chunkProvider = this.q();
+ this.chunkProvider = this.r();
this.portalTravelAgent = new org.bukkit.craftbukkit.CraftTravelAgent(this); // CraftBukkit
- this.O();
this.P();
- this.getWorldBorder().a(minecraftserver.aw());
+ this.Q();
+ this.getWorldBorder().a(minecraftserver.au());
}
- public GeneratorAccess b() {
- this.worldMaps = new PersistentCollection(this.dataManager);
+ public WorldServer i_() {
String s = PersistentVillage.a(this.worldProvider);
- PersistentVillage persistentvillage = (PersistentVillage) this.worldMaps.get(PersistentVillage::new, s);
+ PersistentVillage persistentvillage = (PersistentVillage) this.a(DimensionManager.OVERWORLD, PersistentVillage::new, s);
if (persistentvillage == null) {
this.villages = new PersistentVillage(this);
- this.worldMaps.a(s, this.villages);
+ this.a(DimensionManager.OVERWORLD, s, (PersistentBase) this.villages);
} else {
this.villages = persistentvillage;
this.villages.a((World) this);
}
if (getServer().getScoreboardManager() == null) { // CraftBukkit
- PersistentScoreboard persistentscoreboard = (PersistentScoreboard) this.worldMaps.get(PersistentScoreboard::new, "scoreboard");
+ PersistentScoreboard persistentscoreboard = (PersistentScoreboard) this.a(DimensionManager.OVERWORLD, PersistentScoreboard::new, "scoreboard");
if (persistentscoreboard == null) {
persistentscoreboard = new PersistentScoreboard();
- this.worldMaps.a("scoreboard", persistentscoreboard);
+ this.a(DimensionManager.OVERWORLD, "scoreboard", (PersistentBase) persistentscoreboard);
}
persistentscoreboard.a((Scoreboard) this.server.getScoreboard());
@@ -264,9 +270,9 @@ public class WorldServer extends World implements IAsyncTaskHandler {
}
// CraftBukkit end
- public void doTick() {
- this.Q = true;
- super.doTick();
+ public void doTick(BooleanSupplier booleansupplier) {
+ this.P = true;
+ super.doTick(booleansupplier);
// Akarin start - goes to slack service
/*
if (this.getWorldData().isHardcore() && this.getDifficulty() != EnumDifficulty.HARD) {
@@ -283,7 +289,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
this.worldData.setDayTime(i - i % 24000L);
}
- this.h();
+ this.i();
}
this.methodProfiler.a("spawner");
@@ -299,7 +305,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
timings.doChunkUnload.startTiming(); // Spigot
this.methodProfiler.c("chunkSource");
- this.chunkProvider.unloadChunks();
+ this.chunkProvider.unloadChunks(booleansupplier);
int j = this.a(1.0F);
if (j != this.c()) {
@@ -314,11 +320,11 @@ public class WorldServer extends World implements IAsyncTaskHandler {
timings.doChunkUnload.stopTiming(); // Spigot
this.methodProfiler.c("tickPending");
timings.scheduledBlocks.startTiming(); // Paper
- this.p();
+ this.q();
timings.scheduledBlocks.stopTiming(); // Paper
this.methodProfiler.c("tickBlocks");
timings.chunkTicks.startTiming(); // Paper
- this.l();
+ this.n_();
timings.chunkTicks.stopTiming(); // Paper
this.methodProfiler.c("chunkMap");
timings.doChunkMap.startTiming(); // Spigot
@@ -335,9 +341,9 @@ public class WorldServer extends World implements IAsyncTaskHandler {
timings.doPortalForcer.stopTiming(); // Spigot
this.methodProfiler.e();
timings.doSounds.startTiming(); // Spigot
- this.am();
+ this.an();
timings.doSounds.stopTiming(); // Spigot
- this.Q = false;
+ this.P = false;
timings.doChunkGC.startTiming();// Spigot
this.getWorld().processChunkGC(); // CraftBukkit
@@ -345,7 +351,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
}
public boolean j_() {
- return this.Q;
+ return this.P;
}
@Nullable
@@ -362,7 +368,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
}
public void everyoneSleeping() {
- this.K = false;
+ this.J = false;
if (!this.players.isEmpty()) {
int i = 0;
int j = 0;
@@ -378,7 +384,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
}
}
- this.K = j > 0 && j >= this.players.size() - i;
+ this.J = j > 0 && j >= this.players.size() - i;
}
}
@@ -387,8 +393,8 @@ public class WorldServer extends World implements IAsyncTaskHandler {
return this.server.getScoreboard();
}
- protected void h() {
- this.K = false;
+ protected void i() {
+ this.J = false;
List list = (List) this.players.stream().filter(EntityHuman::isSleeping).collect(Collectors.toList());
Iterator iterator = list.iterator();
@@ -399,12 +405,12 @@ public class WorldServer extends World implements IAsyncTaskHandler {
}
if (this.getGameRules().getBoolean("doWeatherCycle")) {
- this.ai();
+ this.b();
}
}
- private void ai() {
+ private void b() {
// CraftBukkit start
this.worldData.setStorm(false);
// If we stop due to everyone sleeping we should reset the weather duration to some other random value.
@@ -424,7 +430,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
}
public boolean everyoneDeeplySleeping() {
- if (this.K && !this.isClientSide) {
+ if (this.J && !this.isClientSide) {
Iterator iterator = this.players.iterator();
// CraftBukkit - This allows us to assume that some people are in bed but not really, allowing time to pass in spite of AFKers
@@ -460,7 +466,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
return this.getChunkProviderServer().isLoaded(i, j);
}
- protected void n_() {
+ protected void l() {
this.methodProfiler.a("playerCheckLight");
if (spigotConfig.randomLightUpdates && !this.players.isEmpty()) { // Spigot
int i = this.random.nextInt(this.players.size());
@@ -475,8 +481,8 @@ public class WorldServer extends World implements IAsyncTaskHandler {
this.methodProfiler.e();
}
- protected void l() {
- this.n_();
+ protected void n_() {
+ this.l();
if (this.worldData.getType() == WorldType.DEBUG_ALL_BLOCK_STATES) {
Iterator iterator = this.manager.b();
@@ -487,7 +493,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
} else {
int i = this.getGameRules().c("randomTickSpeed");
boolean flag = this.isRaining();
- boolean flag1 = this.X();
+ boolean flag1 = this.Y();
this.methodProfiler.a("pollingChunks");
@@ -512,18 +518,18 @@ public class WorldServer extends World implements IAsyncTaskHandler {
blockposition = this.a(new BlockPosition(j + (l & 15), 0, k + (l >> 8 & 15)));
if (this.isRainingAt(blockposition)) {
DifficultyDamageScaler difficultydamagescaler = this.getDamageScaler(blockposition);
+ boolean flag2 = this.getGameRules().getBoolean("doMobSpawning") && this.random.nextDouble() < (double) difficultydamagescaler.b() * paperConfig.skeleHorseSpawnChance; // Paper
- if (this.getGameRules().getBoolean("doMobSpawning") && this.random.nextDouble() < (double) difficultydamagescaler.b() * paperConfig.skeleHorseSpawnChance) {
+ if (flag2) {
EntityHorseSkeleton entityhorseskeleton = new EntityHorseSkeleton(this);
entityhorseskeleton.s(true);
entityhorseskeleton.setAgeRaw(0);
entityhorseskeleton.setPosition((double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ());
this.addEntity(entityhorseskeleton, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.LIGHTNING); // CraftBukkit
- this.strikeLightning(new EntityLightning(this, (double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ(), true));
- } else {
- this.strikeLightning(new EntityLightning(this, (double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ(), false));
}
+
+ this.strikeLightning(new EntityLightning(this, (double) blockposition.getX() + 0.5D, (double) blockposition.getY(), (double) blockposition.getZ() + 0.5D, flag2));
}
}
@@ -611,7 +617,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
return;
}
} else {
- this.q_();
+ this.p();
}
this.worldProvider.l();
@@ -667,11 +673,11 @@ public class WorldServer extends World implements IAsyncTaskHandler {
}
- public void q_() {
+ public void p() {
this.emptyTime = 0;
}
- public void p() {
+ public void q() {
if (this.worldData.getType() != WorldType.DEBUG_ALL_BLOCK_STATES) {
this.nextTickListBlock.a();
this.nextTickListFluid.a();
@@ -719,7 +725,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
return this.server.getSpawnAnimals();
}
- protected IChunkProvider q() {
+ protected IChunkProvider r() {
IChunkLoader ichunkloader = this.dataManager.createChunkLoader(this.worldProvider);
// CraftBukkit start
@@ -735,7 +741,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
gen = new org.bukkit.craftbukkit.generator.NormalChunkGenerator(this, this.getSeed());
}
- return new ChunkProviderServer(this, ichunkloader, new co.aikar.timings.TimedChunkGenerator(this, gen), this.server); // Paper
+ return new ChunkProviderServer(this, ichunkloader, gen, this.server);
// CraftBukkit end
}
@@ -748,7 +754,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
try {
this.b(worldsettings);
if (this.worldData.getType() == WorldType.DEBUG_ALL_BLOCK_STATES) {
- this.al();
+ this.am();
}
super.a(worldsettings);
@@ -769,7 +775,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
}
- private void al() {
+ private void am() {
this.worldData.f(false);
this.worldData.c(true);
this.worldData.setStorm(false);
@@ -816,7 +822,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
}
boolean flag = false;
- Iterator iterator = TagsBlock.I.a().iterator();
+ Iterator iterator = TagsBlock.VALID_SPAWN.a().iterator();
while (iterator.hasNext()) {
Block block = (Block) iterator.next();
@@ -856,13 +862,13 @@ public class WorldServer extends World implements IAsyncTaskHandler {
}
if (worldsettings.c()) {
- this.r();
+ this.s();
}
}
}
- protected void r() {
+ protected void s() {
WorldGenBonusChest worldgenbonuschest = new WorldGenBonusChest();
for (int i = 0; i < 10; ++i) {
@@ -885,7 +891,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
public void save(boolean flag, @Nullable IProgressUpdate iprogressupdate) throws ExceptionWorldConflict {
ChunkProviderServer chunkproviderserver = this.getChunkProviderServer();
- if (chunkproviderserver.e()) {
+ if (chunkproviderserver.d()) {
if (flag) org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(getWorld())); // CraftBukkit // Paper - Incremental Auto Saving - Only fire event on full save
timings.worldSave.startTiming(); // Paper
if (flag || server.serverAutoSave) { // Paper
@@ -903,7 +909,8 @@ public class WorldServer extends World implements IAsyncTaskHandler {
chunkproviderserver.a(flag);
timings.worldSaveChunks.stopTiming(); // Paper
// CraftBukkit - ArrayList -> Collection
- /* //Paper start Collection arraylist = chunkproviderserver.a();
+ /* //Paper start - disable vanilla chunk GC
+ java.util.Collection arraylist = chunkproviderserver.a();
Iterator iterator = arraylist.iterator();
while (iterator.hasNext()) {
@@ -921,7 +928,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
public void flushSave() {
ChunkProviderServer chunkproviderserver = this.getChunkProviderServer();
- if (chunkproviderserver.e()) {
+ if (chunkproviderserver.d()) {
chunkproviderserver.c();
}
}
@@ -929,11 +936,10 @@ public class WorldServer extends World implements IAsyncTaskHandler {
protected void a() throws ExceptionWorldConflict {
timings.worldSaveLevel.startTiming(); // Paper
this.checkSession();
- WorldServer[] aworldserver = this.server.worldServer;
- int i = aworldserver.length;
+ Iterator iterator = this.server.getWorlds().iterator();
- for (int j = 0; j < i; ++j) {
- WorldServer worldserver = aworldserver[j];
+ while (iterator.hasNext()) {
+ WorldServer worldserver = (WorldServer) iterator.next();
if (worldserver instanceof SecondaryWorldServer) {
((SecondaryWorldServer) worldserver).t_();
@@ -955,9 +961,9 @@ public class WorldServer extends World implements IAsyncTaskHandler {
this.worldData.i(this.getWorldBorder().getWarningTime());
this.worldData.b(this.getWorldBorder().j());
this.worldData.c(this.getWorldBorder().i());
- this.worldData.c(this.server.aR().c());
+ this.worldData.c(this.server.aP().c());
this.dataManager.saveWorldData(this.worldData, this.server.getPlayerList().t());
- this.worldMaps.a();
+ this.h().a();
timings.worldSaveLevel.stopTiming(); // Paper
}
@@ -969,19 +975,14 @@ public class WorldServer extends World implements IAsyncTaskHandler {
}
// CraftBukkit end
- public void a(Collection collection) {
- ArrayList arraylist = Lists.newArrayList(collection);
- Iterator iterator = arraylist.iterator();
-
- while (iterator.hasNext()) {
- Entity entity = (Entity) iterator.next();
-
+ public void a(Stream stream) {
+ stream.forEach((entity) -> {
if (this.j(entity)) {
this.entityList.add(entity);
this.b(entity);
}
- }
+ });
}
private boolean j(Entity entity) {
@@ -1145,7 +1146,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
this.d.add(new BlockActionData(blockposition, block, i, j));
}
- private void am() {
+ private void an() {
while (!this.d.isEmpty()) {
BlockActionData blockactiondata = (BlockActionData) this.d.removeFirst();
@@ -1168,17 +1169,17 @@ public class WorldServer extends World implements IAsyncTaskHandler {
super.close();
}
- protected void v() {
+ protected void w() {
boolean flag = this.isRaining();
- super.v();
+ super.w();
/* CraftBukkit start
if (this.o != this.p) {
- this.server.getPlayerList().a((Packet) (new PacketPlayOutGameStateChange(7, this.p)), this.worldProvider.getDimensionManager().getDimensionID());
+ this.server.getPlayerList().a((Packet) (new PacketPlayOutGameStateChange(7, this.p)), this.worldProvider.getDimensionManager());
}
if (this.q != this.r) {
- this.server.getPlayerList().a((Packet) (new PacketPlayOutGameStateChange(8, this.r)), this.worldProvider.getDimensionManager().getDimensionID());
+ this.server.getPlayerList().a((Packet) (new PacketPlayOutGameStateChange(8, this.r)), this.worldProvider.getDimensionManager());
}
if (flag != this.isRaining()) {
@@ -1209,11 +1210,11 @@ public class WorldServer extends World implements IAsyncTaskHandler {
}
- public TickListServer w() {
+ public TickListServer x() {
return this.nextTickListBlock;
}
- public TickListServer x() {
+ public TickListServer y() {
return this.nextTickListFluid;
}
@@ -1234,30 +1235,30 @@ public class WorldServer extends World implements IAsyncTaskHandler {
return this.portalTravelAgent;
}
- public DefinedStructureManager C() {
+ public DefinedStructureManager D() {
return this.dataManager.h();
}
public int a(T t0, double d0, double d1, double d2, int i, double d3, double d4, double d5, double d6) {
// CraftBukkit - visibility api support
- return sendParticles(null, t0, d0, d1, d2, i, d3, d4, d5, d6);
- }
- // Paper start - Particle API Expansion
- public int sendParticles(EntityPlayer sender, T t0, double d0, double d1, double d2, int i, double d3, double d4, double d5, double d6) {
- return sendParticles(this.players, sender, t0, false, d0, d1, d2, i, d3, d5, d5, d6);
+ return sendParticles(null, t0, d0, d1, d2, i, d3, d4, d5, d6, false);
}
- public int sendParticles(List receivers, EntityPlayer sender, T t0, boolean force, double d0, double d1, double d2, int i, double d3, double d4, double d5, double d6) {
- // CraftBukkit end
- PacketPlayOutWorldParticles packetplayoutworldparticles = new PacketPlayOutWorldParticles(t0, force, (float) d0, (float) d1, (float) d2, (float) d3, (float) d4, (float) d5, (float) d6, i);
+ public int sendParticles(EntityPlayer sender, T t0, double d0, double d1, double d2, int i, double d3, double d4, double d5, double d6, boolean force) {
+ // Paper start - Particle API Expansion
+ return sendParticles(players, sender, t0, d0, d1, d2, i, d3, d4, d5, d6, force);
+ }
+ public int sendParticles(List receivers, EntityPlayer sender, T t0, double d0, double d1, double d2, int i, double d3, double d4, double d5, double d6, boolean force) {
// Paper end
+ PacketPlayOutWorldParticles packetplayoutworldparticles = new PacketPlayOutWorldParticles(t0, force, (float) d0, (float) d1, (float) d2, (float) d3, (float) d4, (float) d5, (float) d6, i);
+ // CraftBukkit end
int j = 0;
for (EntityHuman entityhuman : receivers) { // Paper - Particle API Expansion
EntityPlayer entityplayer = (EntityPlayer) entityhuman; // Paper - Particle API Expansion
if (sender != null && !entityplayer.getBukkitEntity().canSee(sender.getBukkitEntity())) continue; // CraftBukkit
- if (this.a(entityplayer, false, d0, d1, d2, packetplayoutworldparticles)) {
+ if (this.a(entityplayer, force, d0, d1, d2, packetplayoutworldparticles)) { // CraftBukkit
++j;
}
}
@@ -1301,15 +1302,15 @@ public class WorldServer extends World implements IAsyncTaskHandler {
}
@Nullable
- public BlockPosition a(String s, BlockPosition blockposition, int i) {
- return this.getChunkProviderServer().a(this, s, blockposition, i);
+ public BlockPosition a(String s, BlockPosition blockposition, int i, boolean flag) {
+ return this.getChunkProviderServer().a(this, s, blockposition, i, flag);
}
- public CraftingManager D() {
+ public CraftingManager E() {
return this.server.getCraftingManager();
}
- public TagRegistry E() {
+ public TagRegistry F() {
return this.server.getTagRegistry();
}
@@ -1321,11 +1322,11 @@ public class WorldServer extends World implements IAsyncTaskHandler {
return this.getChunkProviderServer();
}
- public TickList H() {
- return this.x();
+ public TickList I() {
+ return this.y();
}
- public TickList I() {
- return this.w();
+ public TickList J() {
+ return this.x();
}
}
diff --git a/sources/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/sources/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 3304cb586..8ed9c1338 100644
--- a/sources/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/sources/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -8,6 +8,7 @@ import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
@@ -20,6 +21,8 @@ import java.util.UUID;
import java.util.function.Consumer;
import java.util.logging.Level;
import java.util.logging.Logger;
+import java.util.regex.Pattern;
+
import javax.imageio.ImageIO;
import net.minecraft.server.*;
@@ -55,6 +58,7 @@ import org.bukkit.craftbukkit.entity.CraftPlayer;
import org.bukkit.craftbukkit.generator.CraftChunkData;
import org.bukkit.craftbukkit.help.SimpleHelpMap;
import org.bukkit.craftbukkit.inventory.CraftFurnaceRecipe;
+import org.bukkit.craftbukkit.inventory.CraftInventoryCustom;
import org.bukkit.craftbukkit.inventory.CraftItemFactory;
import org.bukkit.craftbukkit.inventory.CraftMerchantCustom;
import org.bukkit.craftbukkit.inventory.CraftRecipe;
@@ -120,18 +124,22 @@ import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
+import com.google.common.collect.MapMaker;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.mojang.authlib.GameProfile;
+import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.CommandNode;
import com.mojang.brigadier.tree.LiteralCommandNode;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufOutputStream;
import io.netty.buffer.Unpooled;
+import it.unimi.dsi.fastutil.longs.LongIterator;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
+import java.util.HashMap;
import org.bukkit.Keyed;
import org.apache.commons.lang.StringUtils;
import org.bukkit.NamespacedKey;
@@ -746,8 +754,8 @@ public final class CraftServer implements Server {
((DedicatedServer) console).propertyManager = config;
boolean animals = config.getBoolean("spawn-animals", console.getSpawnAnimals());
- boolean monsters = config.getBoolean("spawn-monsters", console.worlds.get(0).getDifficulty() != EnumDifficulty.PEACEFUL);
- EnumDifficulty difficulty = EnumDifficulty.getById(config.getInt("difficulty", console.worlds.get(0).getDifficulty().ordinal()));
+ boolean monsters = config.getBoolean("spawn-monsters", console.getWorldServer(DimensionManager.OVERWORLD).getDifficulty() != EnumDifficulty.PEACEFUL);
+ EnumDifficulty difficulty = EnumDifficulty.getById(config.getInt("difficulty", console.getWorldServer(DimensionManager.OVERWORLD).getDifficulty().ordinal()));
online.value = config.getBoolean("online-mode", console.getOnlineMode());
console.setSpawnAnimals(config.getBoolean("spawn-animals", console.getSpawnAnimals()));
@@ -778,7 +786,7 @@ public final class CraftServer implements Server {
org.spigotmc.SpigotConfig.init((File) console.options.valueOf("spigot-settings")); // Spigot
com.destroystokyo.paper.PaperConfig.init((File) console.options.valueOf("paper-settings")); // Paper
- for (WorldServer world : console.worlds) {
+ for (WorldServer world : console.getWorlds()) {
world.worldData.setDifficulty(difficulty);
world.setSpawnFlags(monsters, animals);
if (this.getTicksPerAnimalSpawns() < 0) {
@@ -954,11 +962,11 @@ public final class CraftServer implements Server {
console.convertWorld(name);
- int dimension = CraftWorld.CUSTOM_DIMENSION_OFFSET + console.worlds.size();
+ int dimension = CraftWorld.CUSTOM_DIMENSION_OFFSET + console.worldServer.size();
boolean used = false;
do {
- for (WorldServer server : console.worlds) {
- used = server.dimension == dimension;
+ for (WorldServer server : console.getWorlds()) {
+ used = server.dimension.getDimensionID() == dimension;
if (used) {
dimension++;
break;
@@ -968,6 +976,7 @@ public final class CraftServer implements Server {
boolean hardcore = false;
IDataManager sdm = new ServerNBTManager(getWorldContainer(), name, getServer(), getHandle().getServer().dataConverterManager);
+ PersistentCollection persistentcollection = new PersistentCollection(sdm);
WorldData worlddata = sdm.getWorldData();
WorldSettings worldSettings = null;
if (worlddata == null) {
@@ -979,7 +988,9 @@ public final class CraftServer implements Server {
worlddata = new WorldData(worldSettings, name);
}
worlddata.checkName(name); // CraftBukkit - Migration did not rewrite the level.dat; This forces 1.8 to take the last loaded world as respawn (in this case the end)
- WorldServer internal = (WorldServer) new WorldServer(console, sdm, worlddata, dimension, console.methodProfiler, creator.environment(), generator).b();
+
+ DimensionManager internalDimension = new DimensionManager(dimension, name, name, () -> DimensionManager.a(creator.environment().getId()).e());
+ WorldServer internal = (WorldServer) new WorldServer(console, sdm, persistentcollection, worlddata, internalDimension, console.methodProfiler, creator.environment(), generator).i_();
if (!(worlds.containsKey(name.toLowerCase(java.util.Locale.ENGLISH)))) {
return null;
@@ -993,10 +1004,10 @@ public final class CraftServer implements Server {
internal.addIWorldAccess(new WorldManager(console, internal));
internal.worldData.setDifficulty(EnumDifficulty.EASY);
internal.setSpawnFlags(true, true);
- console.worlds.add(internal);
+ console.worldServer.put(internal.dimension, internal);
pluginManager.callEvent(new WorldInitEvent(internal.getWorld()));
- System.out.println("Preparing start region for level " + (console.worlds.size() - 1) + " (Seed: " + internal.getSeed() + ")");
+ System.out.println("Preparing start region for level " + (console.worldServer.size() - 1) + " (Seed: " + internal.getSeed() + ")");
if (internal.getWorld().getKeepSpawnInMemory()) {
short short1 = internal.paperConfig.keepLoadedRange; // Paper
@@ -1018,10 +1029,26 @@ public final class CraftServer implements Server {
}
BlockPosition chunkcoordinates = internal.getSpawn();
- internal.getChunkProviderServer().getChunkAt(chunkcoordinates.getX() + j >> 4, chunkcoordinates.getZ() + k >> 4);
+ internal.getChunkProviderServer().getChunkAt(chunkcoordinates.getX() + j >> 4, chunkcoordinates.getZ() + k >> 4, true, true);
}
}
}
+
+ DimensionManager dimensionmanager = internalDimension.e().getDimensionManager();
+ ForcedChunk forcedchunk = (ForcedChunk) persistentcollection.get(dimensionmanager, ForcedChunk::new, "chunks");
+
+ if (forcedchunk != null) {
+ LongIterator longiterator = forcedchunk.a().iterator();
+
+ while (longiterator.hasNext()) {
+ System.out.println("Loading forced chunks for dimension " + dimension + ", " + forcedchunk.a().size() * 100 / 625 + "%");
+ long k = longiterator.nextLong();
+ ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(k);
+
+ internal.getChunkProviderServer().getChunkAt(chunkcoordintpair.x, chunkcoordintpair.z, true, true);
+ }
+ }
+
pluginManager.callEvent(new WorldLoadEvent(internal.getWorld()));
return internal.getWorld();
}
@@ -1039,11 +1066,11 @@ public final class CraftServer implements Server {
WorldServer handle = ((CraftWorld) world).getHandle();
- if (!(console.worlds.contains(handle))) {
+ if (!(console.worldServer.containsKey(handle.dimension))) {
return false;
}
- if (handle.dimension == 0) {
+ if (handle.dimension == DimensionManager.OVERWORLD) {
return false;
}
@@ -1068,7 +1095,7 @@ public final class CraftServer implements Server {
}
worlds.remove(world.getName().toLowerCase(java.util.Locale.ENGLISH));
- console.worlds.remove(console.worlds.indexOf(handle));
+ console.worldServer.remove(handle.dimension);
File parentFolder = world.getWorldFolder().getAbsoluteFile();
@@ -1312,8 +1339,8 @@ public final class CraftServer implements Server {
@Override
@Deprecated
public CraftMapView getMap(short id) {
- PersistentCollection collection = console.worlds.get(0).worldMaps;
- WorldMap worldmap = (WorldMap) collection.get(WorldMap::new, "map_" + id);
+ PersistentCollection collection = console.getWorldServer(DimensionManager.OVERWORLD).worldMaps;
+ WorldMap worldmap = (WorldMap) collection.get(DimensionManager.OVERWORLD, WorldMap::new, "map_" + id);
if (worldmap == null) {
return null;
}
@@ -1513,7 +1540,7 @@ public final class CraftServer implements Server {
@Override
public GameMode getDefaultGameMode() {
- return GameMode.getByValue(console.worlds.get(0).getWorldData().getGameType().getId());
+ return GameMode.getByValue(console.getWorldServer(DimensionManager.OVERWORLD).getWorldData().getGameType().getId());
}
@Override
@@ -1557,7 +1584,7 @@ public final class CraftServer implements Server {
@Override
public OfflinePlayer[] getOfflinePlayers() {
- WorldNBTStorage storage = (WorldNBTStorage) console.worlds.get(0).getDataManager();
+ WorldNBTStorage storage = (WorldNBTStorage) console.getWorldServer(DimensionManager.OVERWORLD).getDataManager();
String[] files = storage.getPlayerDir().list(new DatFileFilter());
Set players = new HashSet();
@@ -1820,7 +1847,7 @@ public final class CraftServer implements Server {
public Entity getEntity(UUID uuid) {
Validate.notNull(uuid, "UUID cannot be null");
- for (WorldServer world : getServer().worlds) {
+ for (WorldServer world : getServer().getWorlds()) {
net.minecraft.server.Entity entity = world.getEntity(uuid);
if (entity != null) {
return entity.getBukkitEntity();
@@ -1902,8 +1929,8 @@ public final class CraftServer implements Server {
public LootTable getLootTable(NamespacedKey key) {
Validate.notNull(key, "NamespacedKey cannot be null");
- LootTableRegistry registry = getServer().aP(); // PAIL getLootTableRegistry
- return new CraftLootTable(key, registry.a(CraftNamespacedKey.toMinecraft(key))); // PAIL rename getLootTable
+ LootTableRegistry registry = getServer().getLootTableRegistry();
+ return new CraftLootTable(key, registry.getLootTable(CraftNamespacedKey.toMinecraft(key)));
}
@Deprecated
diff --git a/sources/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/sources/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 748bed397..033ca3679 100644
--- a/sources/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/sources/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -247,10 +247,8 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
@Override
public void setPlayerListHeaderFooter(BaseComponent[] header, BaseComponent[] footer) {
- PacketPlayOutPlayerListHeaderFooter packet = new PacketPlayOutPlayerListHeaderFooter();
- packet.header = header;
- packet.footer = footer;
- getHandle().playerConnection.sendPacket(packet);
+ setPlayerListHeader(header == null ? null : net.md_5.bungee.chat.ComponentSerializer.toString(header));
+ setPlayerListFooter(footer == null ? null : net.md_5.bungee.chat.ComponentSerializer.toString(footer));
}
@Override
@@ -387,8 +385,8 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
if (getHandle().playerConnection == null) return;
PacketPlayOutPlayerListHeaderFooter packet = new PacketPlayOutPlayerListHeaderFooter();
- packet.a = (this.playerListHeader == null) ? new ChatComponentText("") : this.playerListHeader;
- packet.b = (this.playerListFooter == null) ? new ChatComponentText("") : this.playerListFooter;
+ packet.header = (this.playerListHeader == null) ? new ChatComponentText("") : this.playerListHeader;
+ packet.footer = (this.playerListFooter == null) ? new ChatComponentText("") : this.playerListFooter;
getHandle().playerConnection.sendPacket(packet);
}
@@ -1937,7 +1935,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
{
if ( getHealth() <= 0 && isOnline() )
{
- server.getServer().getPlayerList().moveToWorld( getHandle(), 0, false );
+ server.getServer().getPlayerList().moveToWorld( getHandle(), net.minecraft.server.DimensionManager.OVERWORLD, false );
}
}
diff --git a/sources/src/main/java/org/bukkit/plugin/EventExecutor.java b/sources/src/main/java/org/bukkit/plugin/EventExecutor.java
deleted file mode 100644
index 97affdf49..000000000
--- a/sources/src/main/java/org/bukkit/plugin/EventExecutor.java
+++ /dev/null
@@ -1,105 +0,0 @@
-package org.bukkit.plugin;
-
-import org.bukkit.event.Event;
-import org.bukkit.event.EventException;
-import org.bukkit.event.Listener;
-// Paper start
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.function.Function;
-
-import com.destroystokyo.paper.event.executor.MethodHandleEventExecutor;
-import com.destroystokyo.paper.event.executor.StaticMethodHandleEventExecutor;
-import com.destroystokyo.paper.event.executor.asm.ASMEventExecutorGenerator;
-import com.destroystokyo.paper.event.executor.asm.ClassDefiner;
-import com.google.common.base.Preconditions;
-
-import io.akarin.api.internal.Akari;
-// Paper end
-import io.akarin.server.core.AkarinGlobalConfig;
-
-/**
- * Akarin Changes Note
- * 1) Suspend for event (safety issue)
- */
-/**
- * Interface which defines the class for event call backs to plugins
- */
-public interface EventExecutor {
- public void execute(Listener listener, Event event) throws EventException;
-
- // Paper start
- ConcurrentMap> eventExecutorMap = new ConcurrentHashMap>() {
- @Override
- public Class extends EventExecutor> computeIfAbsent(Method key, Function super Method, ? extends Class extends EventExecutor>> mappingFunction) {
- Class extends EventExecutor> executorClass = get(key);
- if (executorClass != null)
- return executorClass;
-
- //noinspection SynchronizationOnLocalVariableOrMethodParameter
- synchronized (key) {
- executorClass = get(key);
- if (executorClass != null)
- return executorClass;
-
- return super.computeIfAbsent(key, mappingFunction);
- }
- }
- };
-
- public static EventExecutor create(Method m, Class extends Event> eventClass) {
- Preconditions.checkNotNull(m, "Null method");
- Preconditions.checkArgument(m.getParameterCount() != 0, "Incorrect number of arguments %s", m.getParameterCount());
- Preconditions.checkArgument(m.getParameterTypes()[0] == eventClass, "First parameter %s doesn't match event class %s", m.getParameterTypes()[0], eventClass);
- ClassDefiner definer = ClassDefiner.getInstance();
- if (Modifier.isStatic(m.getModifiers())) {
- return new StaticMethodHandleEventExecutor(eventClass, m);
- } else if (definer.isBypassAccessChecks() || Modifier.isPublic(m.getDeclaringClass().getModifiers()) && Modifier.isPublic(m.getModifiers())) {
- // get the existing generated EventExecutor class for the Method or generate one
- Class extends EventExecutor> executorClass = eventExecutorMap.computeIfAbsent(m, (__) -> {
- String name = ASMEventExecutorGenerator.generateName();
- byte[] classData = ASMEventExecutorGenerator.generateEventExecutor(m, name);
- return definer.defineClass(m.getDeclaringClass().getClassLoader(), name, classData).asSubclass(EventExecutor.class);
- });
-
- try {
- EventExecutor asmExecutor = executorClass.newInstance();
- // Define a wrapper to conform to bukkit stupidity (passing in events that don't match and wrapper exception)
- return new EventExecutor() {
- @Override
- public void execute(Listener listener, Event event) throws EventException {
- if (!eventClass.isInstance(event)) return;
- try {
- // Akarin start
- if (false && AkarinGlobalConfig.parallelMode != -1) {
- Akari.eventSuspendTiming.startTiming();
- Akari.timingsLock.lock();
- Akari.STAGE_TICK.suspend();
- Akari.eventSuspendTiming.stopTiming();
- }
- // Akarin end
- asmExecutor.execute(listener, event);
- // Akarin start
- if (false && AkarinGlobalConfig.parallelMode != -1) {
- Akari.eventResumeTiming.startTiming();
- Akari.STAGE_TICK.resume();
- Akari.timingsLock.unlock();
- Akari.eventResumeTiming.stopTiming();
- }
- // Akarin end
- } catch (Exception e) {
- throw new EventException(e);
- }
- }
- };
- } catch (InstantiationException | IllegalAccessException e) {
- throw new AssertionError("Unable to initialize generated event executor", e);
- }
- } else {
- return new MethodHandleEventExecutor(eventClass, m);
- }
- }
- // Paper end
-}
diff --git a/sources/src/main/resources/mixins.akarin.core.json b/sources/src/main/resources/mixins.akarin.core.json
index 74a5e81d2..40a75b0aa 100644
--- a/sources/src/main/resources/mixins.akarin.core.json
+++ b/sources/src/main/resources/mixins.akarin.core.json
@@ -25,6 +25,7 @@
"core.MixinChunkIOExecutor",
"core.MixinPlayerConnectionUtils",
+ "nsc.OptimisticNetworkManager",
"nsc.NonblockingServerConnection",
"optimization.MixinEntity",
diff --git a/sources/src/main/resources/mixins.akarin.optimization.chunk.json b/sources/src/main/resources/mixins.akarin.optimization.chunk.json
deleted file mode 100644
index 3e0eb4f29..000000000
--- a/sources/src/main/resources/mixins.akarin.optimization.chunk.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "required": true,
- "minVersion": "0.7.10",
- "package": "io.akarin.server.mixin",
- "target": "@env(DEFAULT)",
- "compatibilityLevel": "JAVA_8",
- "server": [
- "cps.MixinCraftWorld",
- "cps.MixinChunkProviderServer",
- ]
-}
\ No newline at end of file
diff --git a/work/Paper b/work/Paper
index 83ba855ba..e84839f56 160000
--- a/work/Paper
+++ b/work/Paper
@@ -1 +1 @@
-Subproject commit 83ba855ba6c1e3838c7eea8aa56f54490578c1c6
+Subproject commit e84839f56de2deeee7689ca6fafc2ef628f1d7b6