From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Gegy Date: Tue, 9 Feb 2021 13:23:12 -0500 Subject: [PATCH] tic-tacs: unblocking Code originally licenced under LGPLv3 for the tic-tacs project: https://github.com/Gegy/tic-tacs diff --git a/src/main/java/net/gegy1000/tictacs/NonBlockingWorldAccess.java b/src/main/java/net/gegy1000/tictacs/NonBlockingWorldAccess.java new file mode 100644 index 0000000000000000000000000000000000000000..0d99f3b4930045632d88fa4acb3b8159ee9cf9f3 --- /dev/null +++ b/src/main/java/net/gegy1000/tictacs/NonBlockingWorldAccess.java @@ -0,0 +1,29 @@ +package net.gegy1000.tictacs; + +import net.minecraft.world.level.block.state.IBlockData; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.material.Fluid; +import net.minecraft.world.level.material.FluidTypes; +import net.minecraft.core.BlockPosition; +import net.minecraft.world.level.IWorldReader; +import net.minecraft.world.level.material.FluidTypes; + +public interface NonBlockingWorldAccess extends IWorldReader { + + public static final IBlockData DEFAULT_BLOCK_STATE = Blocks.AIR.getBlockData(); + public static final Fluid DEFAULT_FLUID_STATE = FluidTypes.EMPTY.getFluidData(); + + default IBlockData getBlockStateIfLoaded(BlockPosition pos) { + if (this.isLoaded(pos)) { + return this.getType(pos); + } + return DEFAULT_BLOCK_STATE; + } + + default Fluid getFluidStateIfLoaded(BlockPosition pos) { + if (this.isLoaded(pos)) { + return this.getFluid(pos); + } + return DEFAULT_FLUID_STATE; + } +} \ No newline at end of file diff --git a/src/main/java/net/minecraft/server/level/EntityPlayer.java b/src/main/java/net/minecraft/server/level/EntityPlayer.java index a33cbd6504fd0d5c5e50aa63009d70533c01f686..e4f8bb15201e89d0832e3bcdfcbc12667f51165b 100644 --- a/src/main/java/net/minecraft/server/level/EntityPlayer.java +++ b/src/main/java/net/minecraft/server/level/EntityPlayer.java @@ -657,6 +657,8 @@ public class EntityPlayer extends EntityHuman implements ICrafting { } public void playerTick() { + if (!this.world.isLoaded(this.getChunkCoordinates())) return; // Yatopia - tic-tac unblocking + try { if (valid && !this.isSpectator() || this.world.isLoaded(this.getChunkCoordinates())) { // Paper - don't tick dead players that are not in the world currently (pending respawn) super.tick(); diff --git a/src/main/java/net/minecraft/server/level/WorldServer.java b/src/main/java/net/minecraft/server/level/WorldServer.java index 7cedb4aaf4a002945866a0ca56eb9b0e7ae28de6..e054e98e413ed02b76e63b29c52bd70a559ad15d 100644 --- a/src/main/java/net/minecraft/server/level/WorldServer.java +++ b/src/main/java/net/minecraft/server/level/WorldServer.java @@ -176,8 +176,9 @@ import org.bukkit.event.weather.LightningStrikeEvent; import org.bukkit.event.world.TimeSkipEvent; // CraftBukkit end import it.unimi.dsi.fastutil.ints.IntArrayList; // Tuinity +import net.gegy1000.tictacs.NonBlockingWorldAccess; // Yatopia -public class WorldServer extends World implements GeneratorAccessSeed { +public class WorldServer extends World implements GeneratorAccessSeed, NonBlockingWorldAccess { // Yatopia public static final BlockPosition a = new BlockPosition(100, 50, 0); private static final Logger LOGGER = LogManager.getLogger(); diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java index 4492f2579da79bd58def922894f40422fbeaf54c..cd1f94e5c1c923ee9d8dd451406ac2bee360e9c3 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -142,9 +142,12 @@ import org.bukkit.event.entity.EntityPoseChangeEvent; import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.plugin.PluginManager; // CraftBukkit end +import net.gegy1000.tictacs.NonBlockingWorldAccess; // Yatopia public abstract class Entity implements INamableTileEntity, ICommandListener, net.minecraft.server.KeyedObject { // Paper + public boolean updateNeeded; // Yatopia + private boolean chunkPosUpdateRequested; // Yatopia // CraftBukkit start private static final int CURRENT_LEVEL = 2; boolean preserveMotion = true; // Paper - keep initial motion on first setPositionRotation @@ -772,6 +775,12 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne } // Tuinity end - detailed watchdog information public void move(EnumMoveType enummovetype, Vec3D vec3d) { + // Yatopia start - tic-tacs unblocking + BlockPosition pos = this.getChunkCoordinates(); + if (!this.world.isLoaded(pos)) { + return; + } + // Yatopia end // Tuinity start - detailed watchdog information com.tuinity.tuinity.util.TickThread.ensureTickThread("Cannot move an entity off-main"); synchronized (this.posLock) { @@ -822,7 +831,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne this.v = vec3d.y != vec3d1.y; this.onGround = this.v && vec3d.y < 0.0D; BlockPosition blockposition = this.ap(); - IBlockData iblockdata = this.world.getType(blockposition); + IBlockData iblockdata = this.world.getBlockStateIfLoaded(blockposition); // Yatopia this.a(vec3d1.y, this.onGround, iblockdata, blockposition); Vec3D vec3d2 = this.getMot(); @@ -936,9 +945,9 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne int k = MathHelper.floor(this.loc.z); BlockPosition blockposition = new BlockPosition(i, j, k); - if (this.world.getType(blockposition).isAir()) { + if (this.world.getBlockStateIfLoaded(blockposition).isAir()) { // Yatopia BlockPosition blockposition1 = blockposition.down(); - IBlockData iblockdata = this.world.getType(blockposition1); + IBlockData iblockdata = this.world.getBlockStateIfLoaded(blockposition1); // Yatopia Block block = iblockdata.getBlock(); if (block.a((Tag) TagsBlock.FENCES) || block.a((Tag) TagsBlock.WALLS) || block instanceof BlockFenceGate) { @@ -950,17 +959,21 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne } protected float getBlockJumpFactor() { - float f = this.world.getType(this.getChunkCoordinates()).getBlock().getJumpFactor(); - float f1 = this.world.getType(this.as()).getBlock().getJumpFactor(); + // Yatopia start - tic-tacs unblocking + float f = this.world.getBlockStateIfLoaded(this.getChunkCoordinates()).getBlock().getJumpFactor(); + float f1 = this.world.getBlockStateIfLoaded(this.as()).getBlock().getJumpFactor(); + // Yatopia end return (double) f == 1.0D ? f1 : f; } protected float getBlockSpeedFactor() { - Block block = this.world.getType(this.getChunkCoordinates()).getBlock(); + // Yatopia start - tic-tacs unblocking + Block block = this.world.getBlockStateIfLoaded(this.getChunkCoordinates()).getBlock(); float f = block.getSpeedFactor(); - return block != Blocks.WATER && block != Blocks.BUBBLE_COLUMN ? ((double) f == 1.0D ? this.world.getType(this.as()).getBlock().getSpeedFactor() : f) : f; + return block != Blocks.WATER && block != Blocks.BUBBLE_COLUMN ? ((double) f == 1.0D ? this.world.getBlockStateIfLoaded(this.as()).getBlock().getSpeedFactor() : f) : f; + // Yatopia end } protected BlockPosition as() { @@ -1305,7 +1318,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne for (int i = blockposition.getX(); i <= blockposition1.getX(); ++i) { // Tuinity end - reorder iteration to more cache aware blockposition_mutableblockposition.d(i, j, k); - IBlockData iblockdata = this.world.getType(blockposition_mutableblockposition); + IBlockData iblockdata = this.world.getBlockStateIfLoaded(blockposition_mutableblockposition); // Tuinity start - move fire checking in here - reuse getType from this method if (checkFire) { @@ -1341,7 +1354,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne protected void b(BlockPosition blockposition, IBlockData iblockdata) { if (!iblockdata.getMaterial().isLiquid()) { - IBlockData iblockdata1 = this.world.getType(blockposition.up()); + IBlockData iblockdata1 = this.world.getBlockStateIfLoaded(blockposition.up()); // Yatopia SoundEffectType soundeffecttype = iblockdata1.a(Blocks.SNOW) ? iblockdata1.getStepSound() : iblockdata.getStepSound(); this.playSound(soundeffecttype.getStepSound(), soundeffecttype.getVolume() * 0.15F, soundeffecttype.getPitch()); @@ -1432,7 +1445,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne public final boolean isInBubbleColumn() { return k(); } // Paper - OBFHELPER private boolean k() { - return this.world.getType(this.getChunkCoordinates()).a(Blocks.BUBBLE_COLUMN); + return this.world.getBlockStateIfLoaded(this.getChunkCoordinates()).a(Blocks.BUBBLE_COLUMN); // Yatopia } public boolean isInWaterOrRain() { @@ -1503,7 +1516,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne } BlockPosition blockposition = new BlockPosition(this.locX(), d0, this.locZ()); - Fluid fluid = this.world.getFluid(blockposition); + Fluid fluid = this.world.getFluidStateIfLoaded(blockposition); // Yatopia Iterator iterator = TagsFluid.b().iterator(); Tag tag; @@ -1561,7 +1574,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne } protected IBlockData aN() { - return this.world.getType(this.ap()); + return this.world.getBlockStateIfLoaded(this.ap()); // Yatopia } public boolean aO() { @@ -1573,7 +1586,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne int j = MathHelper.floor(this.locY() - 0.20000000298023224D); int k = MathHelper.floor(this.locZ()); BlockPosition blockposition = new BlockPosition(i, j, k); - IBlockData iblockdata = this.world.getType(blockposition); + IBlockData iblockdata = this.world.getBlockStateIfLoaded(blockposition); // Yatopia if (iblockdata.h() != EnumRenderType.INVISIBLE) { Vec3D vec3d = this.getMot(); @@ -2827,7 +2840,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne EnumDirection enumdirection1 = aenumdirection[j]; blockposition_mutableblockposition.a((BaseBlockPosition) blockposition, enumdirection1); - if (!this.world.getType(blockposition_mutableblockposition).r(this.world, blockposition_mutableblockposition)) { + if (!this.world.getBlockStateIfLoaded(blockposition_mutableblockposition).r(this.world, blockposition_mutableblockposition)) { // Yatopia double d4 = vec3d.a(enumdirection1.n()); double d5 = enumdirection1.e() == EnumDirection.EnumAxisDirection.POSITIVE ? 1.0D - d4 : d4; @@ -3043,14 +3056,14 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne return (ShapeDetectorShape) this.findOrCreatePortal(worldserver, blockposition, flag2, event.getSearchRadius(), event.getCanCreatePortal(), event.getCreationRadius()).map((blockutil_rectangle) -> { // CraftBukkit end - IBlockData iblockdata = this.world.getType(this.ac); + IBlockData iblockdata = this.world.getBlockStateIfLoaded(this.ac); // Yatopia EnumDirection.EnumAxis enumdirection_enumaxis; Vec3D vec3d; if (iblockdata.b(BlockProperties.E)) { enumdirection_enumaxis = (EnumDirection.EnumAxis) iblockdata.get(BlockProperties.E); BlockUtil.Rectangle blockutil_rectangle1 = BlockUtil.a(this.ac, enumdirection_enumaxis, 21, EnumDirection.EnumAxis.Y, 21, (blockposition1) -> { - return this.world.getType(blockposition1) == iblockdata; + return this.world.getBlockStateIfLoaded(blockposition1) == iblockdata; // Yatopia }); vec3d = this.a(enumdirection_enumaxis, blockutil_rectangle1); @@ -3417,6 +3430,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne } public boolean cl() { + if (!this.updateNeeded) this.chunkPosUpdateRequested = true; // Yatopia boolean flag = this.au; this.au = false; @@ -3620,7 +3634,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne for (int i2 = k; i2 < l; ++i2) { for (int j2 = i1; j2 < j1; ++j2) { blockposition_mutableblockposition.d(l1, i2, j2); - Fluid fluid = this.world.getFluid(blockposition_mutableblockposition); + Fluid fluid = this.world.getFluidStateIfLoaded(blockposition_mutableblockposition); // Yatopia if (fluid.a(tag)) { double d2 = (double) ((float) i2 + fluid.getHeight(this.world, blockposition_mutableblockposition)); diff --git a/src/main/java/net/minecraft/world/entity/EntityLiving.java b/src/main/java/net/minecraft/world/entity/EntityLiving.java index fb62d5bfe188a7ae82a038454cbf0db10de23dda..2f5960a85b3599f369ad334f3b3a0bae8fad8ecf 100644 --- a/src/main/java/net/minecraft/world/entity/EntityLiving.java +++ b/src/main/java/net/minecraft/world/entity/EntityLiving.java @@ -140,6 +140,7 @@ import org.bukkit.event.entity.EntityTeleportEvent; import org.bukkit.event.player.PlayerItemConsumeEvent; // CraftBukkit end +import net.gegy1000.tictacs.NonBlockingWorldAccess; // Yatopia public abstract class EntityLiving extends Entity { @@ -393,7 +394,7 @@ public abstract class EntityLiving extends Entity { boolean flag1 = flag && ((EntityHuman) this).abilities.isInvulnerable; if (this.isAlive()) { - if (this.a((Tag) TagsFluid.WATER) && !this.world.getType(new BlockPosition(this.locX(), this.getHeadY(), this.locZ())).a(Blocks.BUBBLE_COLUMN)) { + if (this.a((Tag) TagsFluid.WATER) && !this.world.getBlockStateIfLoaded(new BlockPosition(this.locX(), this.getHeadY(), this.locZ())).a(Blocks.BUBBLE_COLUMN)) { // Yatopia if (!this.canBreatheUnderwater() && !MobEffectUtil.c(this) && !flag1) { // Paper - use OBFHELPER so it can be overridden this.setAirTicks(this.l(this.getAirTicks())); if (this.getAirTicks() == -this.world.purpurConfig.drowningDamageInterval) { // Purpur @@ -486,7 +487,7 @@ public abstract class EntityLiving extends Entity { } protected boolean cP() { - return this.world.getType(this.as()).a((Tag) TagsBlock.SOUL_SPEED_BLOCKS); + return this.world.getBlockStateIfLoaded(this.as()).a((Tag) TagsBlock.SOUL_SPEED_BLOCKS); // Yatopia } @Override @@ -534,6 +535,8 @@ public abstract class EntityLiving extends Entity { } protected void c(BlockPosition blockposition) { + if (!this.world.isLoaded(blockposition)) return; // Yatopia + int i = EnchantmentManager.a(Enchantments.FROST_WALKER, this); if (i > 0) { @@ -1580,7 +1583,7 @@ public abstract class EntityLiving extends Entity { BlockPosition blockposition = this.getChunkCoordinates(); IBlockData iblockdata = Blocks.WITHER_ROSE.getBlockData(); - if (this.world.getType(blockposition).isAir() && iblockdata.canPlace(this.world, blockposition)) { + if (this.world.getBlockStateIfLoaded(blockposition).isAir() && iblockdata.canPlace(this.world, blockposition)) { // Yatopia this.world.setTypeAndData(blockposition, iblockdata, 3); flag = true; } @@ -1772,12 +1775,12 @@ public abstract class EntityLiving extends Entity { } public IBlockData ds() { - return this.world.getType(this.getChunkCoordinates()); + return this.world.getBlockStateIfLoaded(this.getChunkCoordinates()); // Yatopia } private boolean c(BlockPosition blockposition, IBlockData iblockdata) { if ((Boolean) iblockdata.get(BlockTrapdoor.OPEN)) { - IBlockData iblockdata1 = this.world.getType(blockposition.down()); + IBlockData iblockdata1 = this.world.getBlockStateIfLoaded(blockposition.down()); // Yatopia if (iblockdata1.a(Blocks.LADDER) && iblockdata1.get(BlockLadder.FACING) == iblockdata.get(BlockTrapdoor.FACING)) { return true; @@ -1824,7 +1827,7 @@ public abstract class EntityLiving extends Entity { int i = MathHelper.floor(this.locX()); int j = MathHelper.floor(this.locY() - 0.20000000298023224D); int k = MathHelper.floor(this.locZ()); - IBlockData iblockdata = this.world.getType(new BlockPosition(i, j, k)); + IBlockData iblockdata = this.world.getBlockStateIfLoaded(new BlockPosition(i, j, k)); // Yatopia if (!iblockdata.isAir()) { SoundEffectType soundeffecttype = iblockdata.getStepSound(); @@ -2315,7 +2318,7 @@ public abstract class EntityLiving extends Entity { private void a(Entity entity) { Vec3D vec3d; - if (!entity.dead && !this.world.getType(entity.getChunkCoordinates()).getBlock().a((Tag) TagsBlock.PORTALS)) { + if (!entity.dead && !this.world.getBlockStateIfLoaded(entity.getChunkCoordinates()).getBlock().a((Tag) TagsBlock.PORTALS)) { // Yatopia vec3d = entity.b(this); } else { vec3d = new Vec3D(entity.locX(), entity.locY() + (double) entity.getHeight(), entity.locZ()); @@ -2369,7 +2372,7 @@ public abstract class EntityLiving extends Entity { this.fallDistance = 0.0F; } - Fluid fluid = this.world.getFluid(this.getChunkCoordinates()); + Fluid fluid = this.world.getFluidStateIfLoaded(this.getChunkCoordinates()); // Yatopia double d1; float f; @@ -2485,7 +2488,7 @@ public abstract class EntityLiving extends Entity { } } else { BlockPosition blockposition = this.as(); - float f5 = this.world.getType(blockposition).getBlock().getFrictionFactor(); + float f5 = this.world.getBlockStateIfLoaded(blockposition).getBlock().getFrictionFactor(); // Yatopia f = this.onGround ? f5 * 0.91F : 0.91F; Vec3D vec3d6 = this.a(vec3d, f5); @@ -3546,7 +3549,7 @@ public abstract class EntityLiving extends Entity { while (!flag2 && blockposition.getY() > 0) { BlockPosition blockposition1 = blockposition.down(); - IBlockData iblockdata = world.getType(blockposition1); + IBlockData iblockdata = this.world.getBlockStateIfLoaded(blockposition1); // Yatopia if (iblockdata.getMaterial().isSolid()) { flag2 = true; @@ -3641,7 +3644,7 @@ public abstract class EntityLiving extends Entity { this.stopRiding(); } - IBlockData iblockdata = this.world.getType(blockposition); + IBlockData iblockdata = this.world.getBlockStateIfLoaded(blockposition); // Yatopia if (iblockdata.getBlock() instanceof BlockBed) { this.world.setTypeAndData(blockposition, (IBlockData) iblockdata.set(BlockBed.OCCUPIED, true), 3); @@ -3660,7 +3663,7 @@ public abstract class EntityLiving extends Entity { private boolean x() { return (Boolean) this.getBedPosition().map((blockposition) -> { - return this.world.getType(blockposition).getBlock() instanceof BlockBed; + return this.world.getBlockStateIfLoaded(blockposition).getBlock() instanceof BlockBed; // Yatopia }).orElse(false); } @@ -3670,7 +3673,7 @@ public abstract class EntityLiving extends Entity { this.world.getClass(); optional.filter(world::isLoaded).ifPresent((blockposition) -> { - IBlockData iblockdata = this.world.getType(blockposition); + IBlockData iblockdata = this.world.getBlockStateIfLoaded(blockposition); // Yatopia if (iblockdata.getBlock() instanceof BlockBed) { this.world.setTypeAndData(blockposition, (IBlockData) iblockdata.set(BlockBed.OCCUPIED, false), 3); diff --git a/src/main/java/net/minecraft/world/level/World.java b/src/main/java/net/minecraft/world/level/World.java index aed97af643b8ec9b6fd5a5f06ff4f364daf39742..f5badbe0dee5c40cf83a5d2993d27ed70ddd2c85 100644 --- a/src/main/java/net/minecraft/world/level/World.java +++ b/src/main/java/net/minecraft/world/level/World.java @@ -96,7 +96,9 @@ import org.bukkit.craftbukkit.block.data.CraftBlockData; import org.bukkit.event.block.BlockPhysicsEvent; // CraftBukkit end -public abstract class World implements GeneratorAccess, AutoCloseable { +import net.gegy1000.tictacs.NonBlockingWorldAccess; // Yatopia + +public abstract class World implements GeneratorAccess, AutoCloseable, NonBlockingWorldAccess { // Yatopia protected static final Logger LOGGER = LogManager.getLogger(); public static final Codec> f = MinecraftKey.a.xmap(ResourceKey.b(IRegistry.L), ResourceKey::a); diff --git a/src/main/java/net/minecraft/world/level/material/FluidType.java b/src/main/java/net/minecraft/world/level/material/FluidType.java index 6a60f53407db840150b84f4d2a709cc2e92362a4..bf3300607f9142486dc790a600d4c2ffa998d376 100644 --- a/src/main/java/net/minecraft/world/level/material/FluidType.java +++ b/src/main/java/net/minecraft/world/level/material/FluidType.java @@ -38,6 +38,7 @@ public abstract class FluidType { this.a = fluid; } + public final Fluid getFluidData() { return this.h(); } // Yatopia - OBFHELPER public final Fluid h() { return this.a; }