From 23bf7ede3aac2e0054dcdc6301da047f0918a09b Mon Sep 17 00:00:00 2001 From: Aikar Date: Mon, 28 Mar 2016 20:55:47 -0400 Subject: [PATCH] MC Utils diff --git a/src/main/java/net/minecraft/server/BlockAccessAir.java b/src/main/java/net/minecraft/server/BlockAccessAir.java index eff6ebcd3..30cbfc8ea 100644 --- a/src/main/java/net/minecraft/server/BlockAccessAir.java +++ b/src/main/java/net/minecraft/server/BlockAccessAir.java @@ -14,6 +14,18 @@ public enum BlockAccessAir implements IBlockAccess { return null; } + // Paper start - If loaded util + @Override + public Fluid getFluidIfLoaded(BlockPosition blockposition) { + return this.getFluid(blockposition); + } + + @Override + public IBlockData getTypeIfLoaded(BlockPosition blockposition) { + return this.getType(blockposition); + } + // Paper end + @Override public IBlockData getType(BlockPosition blockposition) { return Blocks.AIR.getBlockData(); diff --git a/src/main/java/net/minecraft/server/BlockDataAbstract.java b/src/main/java/net/minecraft/server/BlockDataAbstract.java index 1cf97cefc..2040f1834 100644 --- a/src/main/java/net/minecraft/server/BlockDataAbstract.java +++ b/src/main/java/net/minecraft/server/BlockDataAbstract.java @@ -78,6 +78,7 @@ public abstract class BlockDataAbstract implements IBlockDataHolder { return Collections.unmodifiableCollection(this.d.keySet()); } + public final > boolean hasProperty(IBlockState iblockstate) { return this.b(iblockstate); } // Paper - OBFHELPER public > boolean b(IBlockState iblockstate) { return this.d.containsKey(iblockstate); } diff --git a/src/main/java/net/minecraft/server/BlockPosition.java b/src/main/java/net/minecraft/server/BlockPosition.java index c88a62f6b..1cdf0346f 100644 --- a/src/main/java/net/minecraft/server/BlockPosition.java +++ b/src/main/java/net/minecraft/server/BlockPosition.java @@ -120,6 +120,7 @@ public class BlockPosition extends BaseBlockPosition implements MinecraftSeriali return d0 == 0.0D && d1 == 0.0D && d2 == 0.0D ? this : new BlockPosition((double) this.getX() + d0, (double) this.getY() + d1, (double) this.getZ() + d2); } + public BlockPosition add(int i, int j, int k) {return b(i, j, k);} // Paper - OBFHELPER public BlockPosition b(int i, int j, int k) { return i == 0 && j == 0 && k == 0 ? this : new BlockPosition(this.getX() + i, this.getY() + j, this.getZ() + k); } @@ -210,6 +211,8 @@ public class BlockPosition extends BaseBlockPosition implements MinecraftSeriali return new BlockPosition(this.getY() * baseblockposition.getZ() - this.getZ() * baseblockposition.getY(), this.getZ() * baseblockposition.getX() - this.getX() * baseblockposition.getZ(), this.getX() * baseblockposition.getY() - this.getY() * baseblockposition.getX()); } + @Deprecated // We'll replace this... + public BlockPosition asImmutable() { return immutableCopy(); } // Paper - OBFHELPER public BlockPosition immutableCopy() { return this; } @@ -402,6 +405,7 @@ public class BlockPosition extends BaseBlockPosition implements MinecraftSeriali return this.d; } + public BlockPosition.MutableBlockPosition setValues(int i, int j, int k) { return d(i, j, k);} // Paper - OBFHELPER public BlockPosition.MutableBlockPosition d(int i, int j, int k) { this.b = i; this.c = j; @@ -413,6 +417,7 @@ public class BlockPosition extends BaseBlockPosition implements MinecraftSeriali return this.c(entity.locX(), entity.locY(), entity.locZ()); } + public BlockPosition.MutableBlockPosition setValues(double d0, double d1, double d2) { return c(d0, d1, d2);} // Paper - OBFHELPER public BlockPosition.MutableBlockPosition c(double d0, double d1, double d2) { return this.d(MathHelper.floor(d0), MathHelper.floor(d1), MathHelper.floor(d2)); } diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java index 55373cae0..cfffbd031 100644 --- a/src/main/java/net/minecraft/server/Chunk.java +++ b/src/main/java/net/minecraft/server/Chunk.java @@ -25,7 +25,7 @@ import org.apache.logging.log4j.Logger; public class Chunk implements IChunkAccess { private static final Logger LOGGER = LogManager.getLogger(); - public static final ChunkSection a = null; + public static final ChunkSection a = null; public static final ChunkSection EMPTY_CHUNK_SECTION = Chunk.a; // Paper - OBFHELPER private final ChunkSection[] sections; private BiomeStorage d; private final Map e; @@ -213,6 +213,18 @@ public class Chunk implements IChunkAccess { } } + // Paper start - If loaded util + @Override + public Fluid getFluidIfLoaded(BlockPosition blockposition) { + return this.getFluid(blockposition); + } + + @Override + public IBlockData getTypeIfLoaded(BlockPosition blockposition) { + return this.getType(blockposition); + } + // Paper end + @Override public Fluid getFluid(BlockPosition blockposition) { return this.a(blockposition.getX(), blockposition.getY(), blockposition.getZ()); @@ -395,6 +407,7 @@ public class Chunk implements IChunkAccess { return this.a(blockposition, Chunk.EnumTileEntityState.CHECK); } + @Nullable public final TileEntity getTileEntityImmediately(BlockPosition pos) { return this.a(pos, EnumTileEntityState.IMMEDIATE); } // Paper - OBFHELPER @Nullable public TileEntity a(BlockPosition blockposition, Chunk.EnumTileEntityState chunk_enumtileentitystate) { // CraftBukkit start diff --git a/src/main/java/net/minecraft/server/ChunkCache.java b/src/main/java/net/minecraft/server/ChunkCache.java index 11c4d23ba..53c15c1c0 100644 --- a/src/main/java/net/minecraft/server/ChunkCache.java +++ b/src/main/java/net/minecraft/server/ChunkCache.java @@ -8,7 +8,7 @@ public class ChunkCache implements IBlockAccess, ICollisionAccess { protected final int b; protected final IChunkAccess[][] c; protected boolean d; - protected final World e; + protected final World e; protected final World getWorld() { return e; } // Paper - OBFHELPER public ChunkCache(World world, BlockPosition blockposition, BlockPosition blockposition1) { this.e = world; @@ -71,6 +71,20 @@ public class ChunkCache implements IBlockAccess, ICollisionAccess { return this.a(i, j); } + // Paper start - if loaded util + @Override + public Fluid getFluidIfLoaded(BlockPosition blockposition) { + IChunkAccess chunk = getWorld().getChunkIfLoadedImmediately(blockposition.getX() >> 4, blockposition.getZ() >> 4); + return chunk == null ? null : chunk.getFluid(blockposition); + } + + @Override + public IBlockData getTypeIfLoaded(BlockPosition blockposition) { + IChunkAccess chunk = getWorld().getChunkIfLoadedImmediately(blockposition.getX() >> 4, blockposition.getZ() >> 4); + return chunk == null ? null : chunk.getType(blockposition); + } + // Paper end + @Nullable @Override public TileEntity getTileEntity(BlockPosition blockposition) { diff --git a/src/main/java/net/minecraft/server/ChunkCoordIntPair.java b/src/main/java/net/minecraft/server/ChunkCoordIntPair.java index 260644bf0..f2a19acd8 100644 --- a/src/main/java/net/minecraft/server/ChunkCoordIntPair.java +++ b/src/main/java/net/minecraft/server/ChunkCoordIntPair.java @@ -31,7 +31,9 @@ public class ChunkCoordIntPair { return pair(this.x, this.z); } - public static long pair(int i, int j) { + public static long asLong(final BlockPosition pos) { return pair(pos.getX() >> 4, pos.getZ() >> 4); } // Paper - OBFHELPER + public static long asLong(int x, int z) { return pair(x, z); } // Paper - OBFHELPER + public static long pair(int i, int j) { return (long) i & 4294967295L | ((long) j & 4294967295L) << 32; } diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java index e8b7cc06c..9cd21b1ff 100644 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java @@ -77,6 +77,37 @@ public class ChunkProviderServer extends IChunkProvider { this.cacheChunk[0] = ichunkaccess; } + // Paper start - "real" get chunk if loaded + // Note: Partially copied from the getChunkAt method below + @Nullable + public Chunk getChunkAtIfCachedImmediately(int x, int z) { + long k = ChunkCoordIntPair.pair(x, z); + + // Note: Bypass cache to make this MT-Safe + + PlayerChunk playerChunk = this.getChunk(k); + if (playerChunk == null) { + return null; + } + + return playerChunk.getFullChunkIfCached(); + } + + @Nullable + public Chunk getChunkAtIfLoadedImmediately(int x, int z) { + long k = ChunkCoordIntPair.pair(x, z); + + // Note: Bypass cache since we need to check ticket level, and to make this MT-Safe + + PlayerChunk playerChunk = this.getChunk(k); + if (playerChunk == null) { + return null; + } + + return playerChunk.getFullChunk(); + } + // Paper end + @Nullable @Override public IChunkAccess getChunkAt(int i, int j, ChunkStatus chunkstatus, boolean flag) { diff --git a/src/main/java/net/minecraft/server/DataBits.java b/src/main/java/net/minecraft/server/DataBits.java index 7ca3a1d0c..2edd9b871 100644 --- a/src/main/java/net/minecraft/server/DataBits.java +++ b/src/main/java/net/minecraft/server/DataBits.java @@ -83,6 +83,7 @@ public class DataBits { } } + public long[] getDataBits() { return this.a(); } // Paper - OBFHELPER public long[] a() { return this.a; } diff --git a/src/main/java/net/minecraft/server/DataPalette.java b/src/main/java/net/minecraft/server/DataPalette.java index 75ba69886..45403fbe3 100644 --- a/src/main/java/net/minecraft/server/DataPalette.java +++ b/src/main/java/net/minecraft/server/DataPalette.java @@ -4,10 +4,12 @@ import javax.annotation.Nullable; public interface DataPalette { + default int getOrCreateIdFor(T object) { return this.a(object); } // Paper - OBFHELPER int a(T t0); boolean b(T t0); + @Nullable default T getObject(int dataBits) { return this.a(dataBits); } // Paper - OBFHELPER @Nullable T a(int i); diff --git a/src/main/java/net/minecraft/server/DataPaletteBlock.java b/src/main/java/net/minecraft/server/DataPaletteBlock.java index 774a8f543..d5f5a5187 100644 --- a/src/main/java/net/minecraft/server/DataPaletteBlock.java +++ b/src/main/java/net/minecraft/server/DataPaletteBlock.java @@ -11,7 +11,7 @@ import java.util.stream.Collectors; public class DataPaletteBlock implements DataPaletteExpandable { - private final DataPalette b; + private final DataPalette b; private final DataPalette getDataPaletteGlobal() { return this.b; } // Paper - OBFHELPER private final DataPaletteExpandable c = (i, object) -> { return 0; }; @@ -19,9 +19,9 @@ public class DataPaletteBlock implements DataPaletteExpandable { private final Function e; private final Function f; private final T g; - protected DataBits a; - private DataPalette h; - private int i; + protected DataBits a; protected DataBits getDataBits() { return this.a; } // Paper - OBFHELPER + private DataPalette h; private DataPalette getDataPalette() { return this.h; } // Paper - OBFHELPER + private int i; private int getBitsPerObject() { return this.i; } // Paper - OBFHELPER private final ReentrantLock j = new ReentrantLock(); public void a() { @@ -56,6 +56,7 @@ public class DataPaletteBlock implements DataPaletteExpandable { return j << 8 | k << 4 | i; } + private void initialize(int bitsPerObject) { this.b(bitsPerObject); } // Paper - OBFHELPER private void b(int i) { if (i != this.i) { this.i = i; @@ -133,6 +134,7 @@ public class DataPaletteBlock implements DataPaletteExpandable { return t0 == null ? this.g : t0; } + public void writeDataPaletteBlock(PacketDataSerializer packetDataSerializer) { this.b(packetDataSerializer); } // Paper - OBFHELPER public void b(PacketDataSerializer packetdataserializer) { this.a(); packetdataserializer.writeByte(this.i); diff --git a/src/main/java/net/minecraft/server/EntityCreature.java b/src/main/java/net/minecraft/server/EntityCreature.java index fe69161e5..b40c8d2f8 100644 --- a/src/main/java/net/minecraft/server/EntityCreature.java +++ b/src/main/java/net/minecraft/server/EntityCreature.java @@ -6,6 +6,8 @@ import org.bukkit.event.entity.EntityUnleashEvent; public abstract class EntityCreature extends EntityInsentient { + public org.bukkit.craftbukkit.entity.CraftCreature getBukkitCreature() { return (org.bukkit.craftbukkit.entity.CraftCreature) super.getBukkitEntity(); } // Paper + protected EntityCreature(EntityTypes entitytypes, World world) { super(entitytypes, world); } diff --git a/src/main/java/net/minecraft/server/EntityInsentient.java b/src/main/java/net/minecraft/server/EntityInsentient.java index e1398652a..7ee5eb987 100644 --- a/src/main/java/net/minecraft/server/EntityInsentient.java +++ b/src/main/java/net/minecraft/server/EntityInsentient.java @@ -144,6 +144,7 @@ public abstract class EntityInsentient extends EntityLiving { return this.goalTarget; } + public org.bukkit.craftbukkit.entity.CraftMob getBukkitMob() { return (org.bukkit.craftbukkit.entity.CraftMob) super.getBukkitEntity(); } // Paper public void setGoalTarget(@Nullable EntityLiving entityliving) { // CraftBukkit start - fire event setGoalTarget(entityliving, EntityTargetEvent.TargetReason.UNKNOWN, true); diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java index 3b1bcf349..1f350e335 100644 --- a/src/main/java/net/minecraft/server/EntityLiving.java +++ b/src/main/java/net/minecraft/server/EntityLiving.java @@ -129,6 +129,7 @@ public abstract class EntityLiving extends Entity { public org.bukkit.craftbukkit.attribute.CraftAttributeMap craftAttributes; public boolean collides = true; public boolean canPickUpLoot; + public org.bukkit.craftbukkit.entity.CraftLivingEntity getBukkitLivingEntity() { return (org.bukkit.craftbukkit.entity.CraftLivingEntity) super.getBukkitEntity(); } // Paper @Override public float getBukkitYaw() { diff --git a/src/main/java/net/minecraft/server/EntityMonster.java b/src/main/java/net/minecraft/server/EntityMonster.java index 00c3b666d..e5322fbae 100644 --- a/src/main/java/net/minecraft/server/EntityMonster.java +++ b/src/main/java/net/minecraft/server/EntityMonster.java @@ -5,6 +5,7 @@ import java.util.function.Predicate; public abstract class EntityMonster extends EntityCreature implements IMonster { + public org.bukkit.craftbukkit.entity.CraftMonster getBukkitMonster() { return (org.bukkit.craftbukkit.entity.CraftMonster) super.getBukkitEntity(); } // Paper protected EntityMonster(EntityTypes entitytypes, World world) { super(entitytypes, world); this.f = 5; diff --git a/src/main/java/net/minecraft/server/EntityTypes.java b/src/main/java/net/minecraft/server/EntityTypes.java index f937b7294..cbf0c2f25 100644 --- a/src/main/java/net/minecraft/server/EntityTypes.java +++ b/src/main/java/net/minecraft/server/EntityTypes.java @@ -4,6 +4,7 @@ import com.mojang.datafixers.DataFixUtils; import java.util.Collections; import java.util.Optional; import java.util.Set; // Paper +import java.util.Map; // Paper import java.util.UUID; import java.util.function.Function; import java.util.stream.Stream; @@ -290,8 +291,8 @@ public class EntityTypes { return this.bj.height; } - @Nullable - public T a(World world) { + public T create(World world) { return this.a(world); } // Paper - OBFHELPER + @Nullable public T a(World world) { // Paper - OBFHELPER return this.ba.create(this, world); } diff --git a/src/main/java/net/minecraft/server/IAsyncTaskHandler.java b/src/main/java/net/minecraft/server/IAsyncTaskHandler.java index 1890c760f..7e5ece9d5 100644 --- a/src/main/java/net/minecraft/server/IAsyncTaskHandler.java +++ b/src/main/java/net/minecraft/server/IAsyncTaskHandler.java @@ -68,6 +68,15 @@ public abstract class IAsyncTaskHandler implements Mailbox d = Queues.newConcurrentLinkedQueue(); - private final RegionFileCache e; + private final RegionFileCache e; public RegionFileCache getRegionFileCache() { return e; } // Paper - OBFHELPER private final Map f = Maps.newLinkedHashMap(); private boolean g = true; private CompletableFuture h = new CompletableFuture(); diff --git a/src/main/java/net/minecraft/server/IWorldReader.java b/src/main/java/net/minecraft/server/IWorldReader.java index ba315131e..cbe2aa4c0 100644 --- a/src/main/java/net/minecraft/server/IWorldReader.java +++ b/src/main/java/net/minecraft/server/IWorldReader.java @@ -4,6 +4,7 @@ import javax.annotation.Nullable; public interface IWorldReader extends IBlockLightAccess, ICollisionAccess, BiomeManager.Provider { + @Nullable IChunkAccess getChunkIfLoadedImmediately(int x, int z); // Paper - ifLoaded api (we need this since current impl blocks if the chunk is loading) @Nullable IChunkAccess getChunkAt(int i, int j, ChunkStatus chunkstatus, boolean flag); diff --git a/src/main/java/net/minecraft/server/ItemStack.java b/src/main/java/net/minecraft/server/ItemStack.java index b5d45b43c..766b1fe13 100644 --- a/src/main/java/net/minecraft/server/ItemStack.java +++ b/src/main/java/net/minecraft/server/ItemStack.java @@ -37,10 +37,19 @@ import org.bukkit.event.world.StructureGrowEvent; public final class ItemStack { private static final Logger LOGGER = LogManager.getLogger(); - public static final ItemStack a = new ItemStack((Item) null); + public static final ItemStack a = new ItemStack((Item) null);public static final ItemStack NULL_ITEM = a; // Paper - OBFHELPER public static final DecimalFormat b = H(); private int count; private int e; + // Paper start + private org.bukkit.craftbukkit.inventory.CraftItemStack bukkitStack; + public org.bukkit.inventory.ItemStack getBukkitStack() { + if (bukkitStack == null || bukkitStack.getHandle() != this) { + bukkitStack = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(this); + } + return bukkitStack; + } + // Paper end @Deprecated private Item item; private NBTTagCompound tag; @@ -593,6 +602,17 @@ public final class ItemStack { return this.tag != null ? this.tag.getList("Enchantments", 10) : new NBTTagList(); } + // Paper start - (this is just a good no conflict location) + public org.bukkit.inventory.ItemStack asBukkitMirror() { + return CraftItemStack.asCraftMirror(this); + } + public org.bukkit.inventory.ItemStack asBukkitCopy() { + return CraftItemStack.asCraftMirror(this.cloneItemStack()); + } + public static ItemStack fromBukkitCopy(org.bukkit.inventory.ItemStack itemstack) { + return CraftItemStack.asNMSCopy(itemstack); + } + // Paper end public void setTag(@Nullable NBTTagCompound nbttagcompound) { this.tag = nbttagcompound; if (this.getItem().usesDurability()) { @@ -685,6 +705,7 @@ public final class ItemStack { return this.tag != null && this.tag.hasKeyOfType("Enchantments", 9) ? !this.tag.getList("Enchantments", 10).isEmpty() : false; } + public void getOrCreateTagAndSet(String s, NBTBase nbtbase) { a(s, nbtbase);} // Paper - OBFHELPER public void a(String s, NBTBase nbtbase) { this.getOrCreateTag().set(s, nbtbase); } @@ -761,6 +782,7 @@ public final class ItemStack { // CraftBukkit start @Deprecated public void setItem(Item item) { + this.bukkitStack = null; // Paper this.item = item; } // CraftBukkit end diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java new file mode 100644 index 000000000..628b73a12 --- /dev/null +++ b/src/main/java/net/minecraft/server/MCUtil.java @@ -0,0 +1,316 @@ +package net.minecraft.server; + +import com.destroystokyo.paper.block.TargetBlockInfo; +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import org.bukkit.Location; +import org.bukkit.block.BlockFace; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.util.Waitable; +import org.spigotmc.AsyncCatcher; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.Queue; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.function.Supplier; + +public final class MCUtil { + private static final Executor asyncExecutor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat("Paper Async Task Handler Thread - %1$d").build()); + + private MCUtil() {} + + + public static boolean isMainThread() { + return MinecraftServer.getServer().isMainThread(); + } + + private static class DelayedRunnable implements Runnable { + + private final int ticks; + private final Runnable run; + + private DelayedRunnable(int ticks, Runnable run) { + this.ticks = ticks; + this.run = run; + } + + @Override + public void run() { + if (ticks <= 0) { + run.run(); + } else { + scheduleTask(ticks-1, run); + } + } + } + + public static void scheduleTask(int ticks, Runnable runnable) { + // We use post to main instead of process queue as we don't want to process these mid tick if + // Someone uses processQueueWhileWaiting + MinecraftServer.getServer().scheduleOnMain(new DelayedRunnable(ticks, runnable)); + } + + public static void processQueue() { + Runnable runnable; + Queue processQueue = getProcessQueue(); + while ((runnable = processQueue.poll()) != null) { + try { + runnable.run(); + } catch (Exception e) { + MinecraftServer.LOGGER.error("Error executing task", e); + } + } + } + public static T processQueueWhileWaiting(CompletableFuture future) { + try { + if (isMainThread()) { + while (!future.isDone()) { + try { + return future.get(1, TimeUnit.MILLISECONDS); + } catch (TimeoutException ignored) { + processQueue(); + } + } + } + return future.get(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public static void ensureMain(Runnable run) { + ensureMain(null, run); + } + /** + * Ensures the target code is running on the main thread + * @param reason + * @param run + * @return + */ + public static void ensureMain(String reason, Runnable run) { + if (AsyncCatcher.enabled && Thread.currentThread() != MinecraftServer.getServer().serverThread) { + if (reason != null) { + new IllegalStateException("Asynchronous " + reason + "!").printStackTrace(); + } + getProcessQueue().add(run); + return; + } + run.run(); + } + + private static Queue getProcessQueue() { + return MinecraftServer.getServer().processQueue; + } + + public static T ensureMain(Supplier run) { + return ensureMain(null, run); + } + /** + * Ensures the target code is running on the main thread + * @param reason + * @param run + * @param + * @return + */ + public static T ensureMain(String reason, Supplier run) { + if (AsyncCatcher.enabled && Thread.currentThread() != MinecraftServer.getServer().serverThread) { + if (reason != null) { + new IllegalStateException("Asynchronous " + reason + "! Blocking thread until it returns ").printStackTrace(); + } + Waitable wait = new Waitable() { + @Override + protected T evaluate() { + return run.get(); + } + }; + getProcessQueue().add(wait); + try { + return wait.get(); + } catch (InterruptedException | ExecutionException e) { + e.printStackTrace(); + } + return null; + } + return run.get(); + } + + /** + * Calculates distance between 2 entities + * @param e1 + * @param e2 + * @return + */ + public static double distance(Entity e1, Entity e2) { + return Math.sqrt(distanceSq(e1, e2)); + } + + + /** + * Calculates distance between 2 block positions + * @param e1 + * @param e2 + * @return + */ + public static double distance(BlockPosition e1, BlockPosition e2) { + return Math.sqrt(distanceSq(e1, e2)); + } + + /** + * Gets the distance between 2 positions + * @param x1 + * @param y1 + * @param z1 + * @param x2 + * @param y2 + * @param z2 + * @return + */ + public static double distance(double x1, double y1, double z1, double x2, double y2, double z2) { + return Math.sqrt(distanceSq(x1, y1, z1, x2, y2, z2)); + } + + /** + * Get's the distance squared between 2 entities + * @param e1 + * @param e2 + * @return + */ + public static double distanceSq(Entity e1, Entity e2) { + return distanceSq(e1.locX(),e1.locY(),e1.locZ(), e2.locX(),e2.locY(),e2.locZ()); + } + + /** + * Gets the distance sqaured between 2 block positions + * @param pos1 + * @param pos2 + * @return + */ + public static double distanceSq(BlockPosition pos1, BlockPosition pos2) { + return distanceSq(pos1.getX(), pos1.getY(), pos1.getZ(), pos2.getX(), pos2.getY(), pos2.getZ()); + } + + /** + * Gets the distance squared between 2 positions + * @param x1 + * @param y1 + * @param z1 + * @param x2 + * @param y2 + * @param z2 + * @return + */ + public static double distanceSq(double x1, double y1, double z1, double x2, double y2, double z2) { + return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) + (z1 - z2) * (z1 - z2); + } + + /** + * Converts a NMS World/BlockPosition to Bukkit Location + * @param world + * @param x + * @param y + * @param z + * @return + */ + public static Location toLocation(World world, double x, double y, double z) { + return new Location(world.getWorld(), x, y, z); + } + + /** + * Converts a NMS World/BlockPosition to Bukkit Location + * @param world + * @param pos + * @return + */ + public static Location toLocation(World world, BlockPosition pos) { + return new Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ()); + } + + /** + * Converts an NMS entity's current location to a Bukkit Location + * @param entity + * @return + */ + public static Location toLocation(Entity entity) { + return new Location(entity.getWorld().getWorld(), entity.locX(), entity.locY(), entity.locZ()); + } + + public static org.bukkit.block.Block toBukkitBlock(World world, BlockPosition pos) { + return world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()); + } + + public static BlockPosition toBlockPosition(Location loc) { + return new BlockPosition(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); + } + + public static boolean isEdgeOfChunk(BlockPosition pos) { + final int modX = pos.getX() & 15; + final int modZ = pos.getZ() & 15; + return (modX == 0 || modX == 15 || modZ == 0 || modZ == 15); + } + + /** + * Posts a task to be executed asynchronously + * @param run + */ + public static void scheduleAsyncTask(Runnable run) { + asyncExecutor.execute(run); + } + + @Nullable + public static TileEntityHopper getHopper(World world, BlockPosition pos) { + Chunk chunk = world.getChunkIfLoaded(pos.getX() >> 4, pos.getZ() >> 4); + if (chunk != null && chunk.getType(new BlockPosition(pos.getX(), pos.getY(), pos.getZ())).getBlock() == Blocks.HOPPER) { + TileEntity tileEntity = chunk.getTileEntityImmediately(pos); + if (tileEntity instanceof TileEntityHopper) { + return (TileEntityHopper) tileEntity; + } + } + return null; + } + + @Nonnull + public static World getNMSWorld(@Nonnull org.bukkit.World world) { + return ((CraftWorld) world).getHandle(); + } + + public static World getNMSWorld(@Nonnull org.bukkit.entity.Entity entity) { + return getNMSWorld(entity.getWorld()); + } + + public static RayTrace.FluidCollisionOption getNMSFluidCollisionOption(TargetBlockInfo.FluidMode fluidMode) { + if (fluidMode == TargetBlockInfo.FluidMode.NEVER) { + return RayTrace.FluidCollisionOption.NONE; + } + if (fluidMode == TargetBlockInfo.FluidMode.SOURCE_ONLY) { + return RayTrace.FluidCollisionOption.SOURCE_ONLY; + } + if (fluidMode == TargetBlockInfo.FluidMode.ALWAYS) { + return RayTrace.FluidCollisionOption.ANY; + } + return null; + } + + public static BlockFace toBukkitBlockFace(EnumDirection enumDirection) { + switch (enumDirection) { + case DOWN: + return BlockFace.DOWN; + case UP: + return BlockFace.UP; + case NORTH: + return BlockFace.NORTH; + case SOUTH: + return BlockFace.SOUTH; + case WEST: + return BlockFace.WEST; + case EAST: + return BlockFace.EAST; + default: + return null; + } + } +} diff --git a/src/main/java/net/minecraft/server/NBTTagCompound.java b/src/main/java/net/minecraft/server/NBTTagCompound.java index e85b24a32..75604dbc6 100644 --- a/src/main/java/net/minecraft/server/NBTTagCompound.java +++ b/src/main/java/net/minecraft/server/NBTTagCompound.java @@ -60,7 +60,7 @@ public class NBTTagCompound implements NBTBase { return "TAG_Compound"; } }; - private final Map map; + public final Map map; // Paper private NBTTagCompound(Map map) { this.map = map; @@ -123,11 +123,15 @@ public class NBTTagCompound implements NBTBase { this.map.put(s, NBTTagLong.a(i)); } + public void setUUID(String prefix, UUID uuid) { a(prefix, uuid); } // Paper - OBFHELPER public void a(String s, UUID uuid) { this.setLong(s + "Most", uuid.getMostSignificantBits()); this.setLong(s + "Least", uuid.getLeastSignificantBits()); } + + @Nullable public UUID getUUID(String prefix) { return a(prefix); } // Paper - OBFHELPER + @Nullable public UUID a(String s) { return new UUID(this.getLong(s + "Most"), this.getLong(s + "Least")); } diff --git a/src/main/java/net/minecraft/server/NetworkManager.java b/src/main/java/net/minecraft/server/NetworkManager.java index 6700582e3..3ccf16636 100644 --- a/src/main/java/net/minecraft/server/NetworkManager.java +++ b/src/main/java/net/minecraft/server/NetworkManager.java @@ -159,6 +159,7 @@ public class NetworkManager extends SimpleChannelInboundHandler> { } + private void dispatchPacket(Packet packet, @Nullable GenericFutureListener> genericFutureListener) { this.b(packet, genericFutureListener); } // Paper - OBFHELPER private void b(Packet packet, @Nullable GenericFutureListener> genericfuturelistener) { EnumProtocol enumprotocol = EnumProtocol.a(packet); EnumProtocol enumprotocol1 = (EnumProtocol) this.channel.attr(NetworkManager.c).get(); @@ -199,6 +200,7 @@ public class NetworkManager extends SimpleChannelInboundHandler> { } + private void sendPacketQueue() { this.o(); } // Paper - OBFHELPER private void o() { if (this.channel != null && this.channel.isOpen()) { Queue queue = this.packetQueue; @@ -327,9 +329,9 @@ public class NetworkManager extends SimpleChannelInboundHandler> { static class QueuedPacket { - private final Packet a; + private final Packet a; private final Packet getPacket() { return this.a; } // Paper - OBFHELPER @Nullable - private final GenericFutureListener> b; + private final GenericFutureListener> b; private final GenericFutureListener> getGenericFutureListener() { return this.b; } // Paper - OBFHELPER public QueuedPacket(Packet packet, @Nullable GenericFutureListener> genericfuturelistener) { this.a = packet; diff --git a/src/main/java/net/minecraft/server/PacketDataSerializer.java b/src/main/java/net/minecraft/server/PacketDataSerializer.java index 81b6f4581..d9574a9ac 100644 --- a/src/main/java/net/minecraft/server/PacketDataSerializer.java +++ b/src/main/java/net/minecraft/server/PacketDataSerializer.java @@ -33,6 +33,7 @@ public class PacketDataSerializer extends ByteBuf { this.a = bytebuf; } + public static int countBytes(int i) { return PacketDataSerializer.a(i); } // Paper - OBFHELPER public static int a(int i) { for (int j = 1; j < 5; ++j) { if ((i & -1 << j * 7) == 0) { diff --git a/src/main/java/net/minecraft/server/PacketEncoder.java b/src/main/java/net/minecraft/server/PacketEncoder.java index 90223deae..63c4dbd32 100644 --- a/src/main/java/net/minecraft/server/PacketEncoder.java +++ b/src/main/java/net/minecraft/server/PacketEncoder.java @@ -42,6 +42,7 @@ public class PacketEncoder extends MessageToByteEncoder> { packet.b(packetdataserializer); } catch (Throwable throwable) { PacketEncoder.LOGGER.error(throwable); + throwable.printStackTrace(); // Paper - WHAT WAS IT? WHO DID THIS TO YOU? WHAT DID YOU SEE? if (packet.a()) { throw new SkipEncodeException(throwable); } else { diff --git a/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java b/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java index 677e3e5f6..3a1d0deb0 100644 --- a/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java +++ b/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java @@ -17,7 +17,7 @@ public class PacketPlayOutMapChunk implements Packet { private NBTTagCompound d; @Nullable private BiomeStorage e; - private byte[] f; + private byte[] f; private byte[] getData() { return this.f; } // Paper - OBFHELPER private List g; private boolean h; @@ -129,6 +129,7 @@ public class PacketPlayOutMapChunk implements Packet { return bytebuf; } + public int writeChunk(PacketDataSerializer packetDataSerializer, Chunk chunk, int chunkSectionSelector) { return this.a(packetDataSerializer, chunk, chunkSectionSelector); } // Paper - OBFHELPER public int a(PacketDataSerializer packetdataserializer, Chunk chunk, int i) { int j = 0; ChunkSection[] achunksection = chunk.getSections(); diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java index 775359146..3c6fe0596 100644 --- a/src/main/java/net/minecraft/server/PlayerChunk.java +++ b/src/main/java/net/minecraft/server/PlayerChunk.java @@ -63,6 +63,14 @@ public class PlayerChunk { return either == null ? null : (Chunk) either.left().orElse(null); } // CraftBukkit end + // Paper start - "real" get full chunk immediately + public Chunk getFullChunkIfCached() { + // Note: Copied from above without ticket level check + CompletableFuture> statusFuture = this.getStatusFutureUnchecked(ChunkStatus.FULL); + Either either = (Either) statusFuture.getNow(null); + return either == null ? null : (Chunk) either.left().orElse(null); + } + // Paper end public CompletableFuture> getStatusFutureUnchecked(ChunkStatus chunkstatus) { CompletableFuture> completablefuture = (CompletableFuture) this.statusFutures.get(chunkstatus.c()); diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java index ba0293512..b257e1c4e 100644 --- a/src/main/java/net/minecraft/server/PlayerConnection.java +++ b/src/main/java/net/minecraft/server/PlayerConnection.java @@ -67,9 +67,9 @@ public class PlayerConnection implements PacketListenerPlayIn { private final MinecraftServer minecraftServer; public EntityPlayer player; private int e; - private long lastKeepAlive; - private boolean awaitingKeepAlive; - private long h; + private long lastKeepAlive; private void setLastPing(long lastPing) { this.lastKeepAlive = lastPing;}; private long getLastPing() { return this.lastKeepAlive;}; // Paper - OBFHELPER + private boolean awaitingKeepAlive; private void setPendingPing(boolean isPending) { this.awaitingKeepAlive = isPending;}; private boolean isPendingPing() { return this.awaitingKeepAlive;}; // Paper - OBFHELPER + private long h; private void setKeepAliveID(long keepAliveID) { this.h = keepAliveID;}; private long getKeepAliveID() {return this.h; }; // Paper - OBFHELPER // CraftBukkit start - multithreaded fields private volatile int chatThrottle; private static final AtomicIntegerFieldUpdater chatSpamField = AtomicIntegerFieldUpdater.newUpdater(PlayerConnection.class, "chatThrottle"); diff --git a/src/main/java/net/minecraft/server/PlayerInventory.java b/src/main/java/net/minecraft/server/PlayerInventory.java index 08768a3c8..d103cfaac 100644 --- a/src/main/java/net/minecraft/server/PlayerInventory.java +++ b/src/main/java/net/minecraft/server/PlayerInventory.java @@ -17,7 +17,7 @@ public class PlayerInventory implements IInventory, INamableTileEntity { public final NonNullList items; public final NonNullList armor; public final NonNullList extraSlots; - private final List> f; + private final List> f;List> getComponents() { return f; } // Paper - OBFHELPER public int itemInHandIndex; public final EntityHuman player; private ItemStack carried; diff --git a/src/main/java/net/minecraft/server/PotionUtil.java b/src/main/java/net/minecraft/server/PotionUtil.java index b3824898d..bf4172be5 100644 --- a/src/main/java/net/minecraft/server/PotionUtil.java +++ b/src/main/java/net/minecraft/server/PotionUtil.java @@ -110,6 +110,7 @@ public class PotionUtil { return nbttagcompound == null ? Potions.EMPTY : PotionRegistry.a(nbttagcompound.getString("Potion")); } + public static ItemStack addPotionToItemStack(ItemStack itemstack, PotionRegistry potionregistry) { return a(itemstack, potionregistry); } // Paper - OBFHELPER public static ItemStack a(ItemStack itemstack, PotionRegistry potionregistry) { MinecraftKey minecraftkey = IRegistry.POTION.getKey(potionregistry); diff --git a/src/main/java/net/minecraft/server/ProtoChunk.java b/src/main/java/net/minecraft/server/ProtoChunk.java index 6e65306a2..39339fa27 100644 --- a/src/main/java/net/minecraft/server/ProtoChunk.java +++ b/src/main/java/net/minecraft/server/ProtoChunk.java @@ -80,6 +80,18 @@ public class ProtoChunk implements IChunkAccess { } + // Paper start - If loaded util + @Override + public Fluid getFluidIfLoaded(BlockPosition blockposition) { + return this.getFluid(blockposition); + } + + @Override + public IBlockData getTypeIfLoaded(BlockPosition blockposition) { + return this.getType(blockposition); + } + // Paper end + @Override public IBlockData getType(BlockPosition blockposition) { int i = blockposition.getY(); diff --git a/src/main/java/net/minecraft/server/RegionFile.java b/src/main/java/net/minecraft/server/RegionFile.java index 7b6e0e86b..187c4e0f5 100644 --- a/src/main/java/net/minecraft/server/RegionFile.java +++ b/src/main/java/net/minecraft/server/RegionFile.java @@ -88,6 +88,7 @@ public class RegionFile implements AutoCloseable { return this.d.resolve(s); } + @Nullable public synchronized DataInputStream getReadStream(ChunkCoordIntPair chunkCoordIntPair) throws IOException { return a(chunkCoordIntPair);} // Paper - OBFHELPER @Nullable public synchronized DataInputStream a(ChunkCoordIntPair chunkcoordintpair) throws IOException { int i = this.getOffset(chunkcoordintpair); diff --git a/src/main/java/net/minecraft/server/RegionLimitedWorldAccess.java b/src/main/java/net/minecraft/server/RegionLimitedWorldAccess.java index 8c123f265..9d0e8c2d4 100644 --- a/src/main/java/net/minecraft/server/RegionLimitedWorldAccess.java +++ b/src/main/java/net/minecraft/server/RegionLimitedWorldAccess.java @@ -108,6 +108,26 @@ public class RegionLimitedWorldAccess implements GeneratorAccess { return i >= ichunkaccess.getPos().x && i <= ichunkaccess1.getPos().x && j >= ichunkaccess.getPos().z && j <= ichunkaccess1.getPos().z; } + // Paper start - if loaded util + @Nullable + @Override + public IChunkAccess getChunkIfLoadedImmediately(int x, int z) { + return this.getChunkAt(x, z, ChunkStatus.FULL, false); + } + + @Override + public IBlockData getTypeIfLoaded(BlockPosition blockposition) { + IChunkAccess chunk = this.getChunkIfLoadedImmediately(blockposition.getX() >> 4, blockposition.getZ() >> 4); + return chunk == null ? null : chunk.getType(blockposition); + } + + @Override + public Fluid getFluidIfLoaded(BlockPosition blockposition) { + IChunkAccess chunk = this.getChunkIfLoadedImmediately(blockposition.getX() >> 4, blockposition.getZ() >> 4); + return chunk == null ? null : chunk.getFluid(blockposition); + } + // Paper end + @Override public IBlockData getType(BlockPosition blockposition) { return this.getChunkAt(blockposition.getX() >> 4, blockposition.getZ() >> 4).getType(blockposition); diff --git a/src/main/java/net/minecraft/server/RegistryBlockID.java b/src/main/java/net/minecraft/server/RegistryBlockID.java index 4efcb8b59..60948afa4 100644 --- a/src/main/java/net/minecraft/server/RegistryBlockID.java +++ b/src/main/java/net/minecraft/server/RegistryBlockID.java @@ -57,6 +57,7 @@ public class RegistryBlockID implements Registry { return Iterators.filter(this.c.iterator(), Predicates.notNull()); } + public int size() { return this.a(); } // Paper - OBFHELPER public int a() { return this.b.size(); } diff --git a/src/main/java/net/minecraft/server/SystemUtils.java b/src/main/java/net/minecraft/server/SystemUtils.java index 7b92ecfff..7e224ebef 100644 --- a/src/main/java/net/minecraft/server/SystemUtils.java +++ b/src/main/java/net/minecraft/server/SystemUtils.java @@ -58,7 +58,7 @@ public class SystemUtils { } public static long getMonotonicNanos() { - return SystemUtils.a.getAsLong(); + return System.nanoTime(); // Paper } public static long getTimeMillis() { diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java index 692f8e4b7..8fc88f162 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java @@ -196,6 +196,40 @@ public abstract class World implements GeneratorAccess, AutoCloseable { return (Chunk) this.getChunkAt(i, j, ChunkStatus.FULL); } + // Paper start - if loaded + @Nullable + @Override + public IChunkAccess getChunkIfLoadedImmediately(int x, int z) { + return ((ChunkProviderServer)this.chunkProvider).getChunkAtIfLoadedImmediately(x, z); + } + + @Override + public IBlockData getTypeIfLoaded(BlockPosition blockposition) { + // CraftBukkit start - tree generation + if (captureTreeGeneration) { + for (CraftBlockState previous : capturedBlockStates) { + if (previous.getX() == blockposition.getX() && previous.getY() == blockposition.getY() && previous.getZ() == blockposition.getZ()) { + return previous.getHandle(); + } + } + } + // CraftBukkit end + if (!isValidLocation(blockposition)) { + return Blocks.AIR.getBlockData(); + } + IChunkAccess chunk = this.getChunkIfLoadedImmediately(blockposition.getX() >> 4, blockposition.getZ() >> 4); + + return chunk == null ? null : chunk.getType(blockposition); + } + + @Override + public Fluid getFluidIfLoaded(BlockPosition blockposition) { + IChunkAccess chunk = this.getChunkIfLoadedImmediately(blockposition.getX() >> 4, blockposition.getZ() >> 4); + + return chunk == null ? null : chunk.getFluid(blockposition); + } + // Paper end + @Override public IChunkAccess getChunkAt(int i, int j, ChunkStatus chunkstatus, boolean flag) { IChunkAccess ichunkaccess = this.chunkProvider.getChunkAt(i, j, chunkstatus, flag); @@ -357,8 +391,9 @@ public abstract class World implements GeneratorAccess, AutoCloseable { public void a(BlockPosition blockposition, IBlockData iblockdata, IBlockData iblockdata1) {} - @Override - public boolean a(BlockPosition blockposition, boolean flag) { + public boolean setAir(BlockPosition blockposition) { return this.a(blockposition, false); } // Paper - OBFHELPER + public boolean setAir(BlockPosition blockposition, boolean moved) { return this.a(blockposition, moved); } // Paper - OBFHELPER + @Override public boolean a(BlockPosition blockposition, boolean flag) { // Paper - OBFHELPER Fluid fluid = this.getFluid(blockposition); return this.setTypeAndData(blockposition, fluid.getBlockData(), 3 | (flag ? 64 : 0)); diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java index e181df6f4..4a9132c70 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java @@ -85,6 +85,7 @@ public final class CraftItemStack extends ItemStack { } net.minecraft.server.ItemStack handle; + public net.minecraft.server.ItemStack getHandle() { return handle; } // Paper /** * Mirror diff --git a/src/main/java/org/bukkit/craftbukkit/util/DummyGeneratorAccess.java b/src/main/java/org/bukkit/craftbukkit/util/DummyGeneratorAccess.java index d8358a0f0..d0b813008 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/DummyGeneratorAccess.java +++ b/src/main/java/org/bukkit/craftbukkit/util/DummyGeneratorAccess.java @@ -196,4 +196,22 @@ public class DummyGeneratorAccess implements GeneratorAccess { public boolean a(BlockPosition blockposition, boolean flag, Entity entity) { throw new UnsupportedOperationException("Not supported yet."); } + + // Paper start - if loaded util + @javax.annotation.Nullable + @Override + public IChunkAccess getChunkIfLoadedImmediately(int x, int z) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public IBlockData getTypeIfLoaded(BlockPosition blockposition) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override + public Fluid getFluidIfLoaded(BlockPosition blockposition) { + throw new UnsupportedOperationException("Not supported yet."); + } + // Paper end } -- 2.25.0.windows.1