From 8c102f1eebbad58860b0b1317b87ce030f462e52 Mon Sep 17 00:00:00 2001 From: IzzelAliz Date: Fri, 22 Oct 2021 11:58:54 +0800 Subject: [PATCH] Extra logic worlds (#378) --- .../mixin/bukkit/CraftEventFactoryMixin.java | 175 +++++++++++++++++- .../mixin/core/fluid/FlowingFluidMixin.java | 4 + .../mixin/core/fluid/LavaFluidMixin.java | 6 +- .../core/server/level/ServerLevelMixin.java | 37 ++-- .../core/world/item/ArmorStandItemMixin.java | 3 +- .../mixin/core/world/item/BlockItemMixin.java | 5 +- .../mixin/core/world/item/BoatItemMixin.java | 11 +- .../core/world/item/BucketItemMixin.java | 5 +- .../core/world/item/ChorusFruitItemMixin.java | 3 +- .../core/world/item/CrossbowItemMixin.java | 5 + .../world/item/EnderCrystalItemMixin.java | 3 +- .../core/world/item/FireChargeItemMixin.java | 3 +- .../core/world/item/FishingRodItemMixin.java | 13 +- .../world/item/FlintAndSteelItemMixin.java | 2 + .../world/item/HangingEntityItemMixin.java | 2 + .../core/world/item/MinecartItemMixin.java | 3 +- .../core/world/item/TridentItemMixin.java | 2 + .../block/BasePressurePlateBlockMixin.java | 3 +- .../core/world/level/block/BlockMixin.java | 4 +- .../event/BlockBreakEventDispatcher.java | 4 +- .../event/BlockPlaceEventDispatcher.java | 5 +- .../common/mod/util/DistValidate.java | 31 ++++ .../izzel/arclight/i18n/conf/CompatSpec.java | 8 + .../src/main/resources/META-INF/arclight.conf | 1 + 24 files changed, 300 insertions(+), 38 deletions(-) create mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mod/util/DistValidate.java diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/CraftEventFactoryMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/CraftEventFactoryMixin.java index c29f7bc1..7ba6e3ce 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/CraftEventFactoryMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/CraftEventFactoryMixin.java @@ -2,24 +2,43 @@ package io.izzel.arclight.common.mixin.bukkit; import com.google.common.base.Function; import io.izzel.arclight.common.bridge.core.entity.EntityBridge; +import io.izzel.arclight.common.bridge.core.world.WorldBridge; import io.izzel.arclight.common.mod.ArclightMod; import io.izzel.arclight.common.mod.util.ArclightCaptures; +import io.izzel.arclight.common.mod.util.DistValidate; +import net.minecraft.core.BlockPos; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.state.properties.NoteBlockInstrument; import org.bukkit.Bukkit; import org.bukkit.block.Block; import org.bukkit.craftbukkit.v.block.CraftBlock; +import org.bukkit.craftbukkit.v.block.CraftBlockState; +import org.bukkit.craftbukkit.v.block.data.CraftBlockData; import org.bukkit.craftbukkit.v.event.CraftEventFactory; +import org.bukkit.craftbukkit.v.util.CraftMagicNumbers; +import org.bukkit.event.block.BlockFadeEvent; +import org.bukkit.event.block.BlockFormEvent; +import org.bukkit.event.block.BlockGrowEvent; +import org.bukkit.event.block.BlockPhysicsEvent; +import org.bukkit.event.block.BlockRedstoneEvent; +import org.bukkit.event.block.BlockSpreadEvent; +import org.bukkit.event.block.EntityBlockFormEvent; +import org.bukkit.event.block.NotePlayEvent; +import org.bukkit.event.entity.EntityChangeBlockEvent; import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityDamageEvent; 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.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import javax.annotation.Nullable; import java.util.Map; -import net.minecraft.core.BlockPos; -import net.minecraft.world.damagesource.DamageSource; -import net.minecraft.world.entity.Entity; @Mixin(value = CraftEventFactory.class, remap = false) public class CraftEventFactoryMixin { @@ -63,4 +82,154 @@ public class CraftEventFactoryMixin { } cir.setReturnValue(event); } + + /** + * @author IzzelAliz + * @reason + */ + @Overwrite + public static boolean handleBlockSpreadEvent(LevelAccessor world, BlockPos source, BlockPos target, net.minecraft.world.level.block.state.BlockState block, int flag) { + // Suppress during worldgen + if (!(world instanceof Level) || !DistValidate.isValid(world)) { + world.setBlock(target, block, flag); + return true; + } + + CraftBlockState state = CraftBlockState.getBlockState(world, target, flag); + state.setData(block); + + BlockSpreadEvent event = new BlockSpreadEvent(state.getBlock(), CraftBlock.at(world, source), state); + Bukkit.getPluginManager().callEvent(event); + + if (!event.isCancelled()) { + state.update(true); + } + return !event.isCancelled(); + } + + /** + * @author IzzelAliz + * @reason + */ + @Overwrite + public static boolean handleBlockGrowEvent(Level world, BlockPos pos, net.minecraft.world.level.block.state.BlockState newData, int flag) { + // Suppress during worldgen + if (!DistValidate.isValid(world)) { + world.setBlock(pos, newData, flag); + return true; + } + Block block = ((WorldBridge) world).bridge$getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()); + CraftBlockState state = (CraftBlockState) block.getState(); + state.setData(newData); + + BlockGrowEvent event = new BlockGrowEvent(block, state); + Bukkit.getPluginManager().callEvent(event); + + if (!event.isCancelled()) { + state.update(true); + } + + return !event.isCancelled(); + } + + /** + * @author IzzelAliz + * @reason + */ + @Overwrite + public static boolean handleBlockFormEvent(Level world, BlockPos pos, net.minecraft.world.level.block.state.BlockState block, int flag, @Nullable Entity entity) { + // Suppress during worldgen + if (!DistValidate.isValid(world)) { + world.setBlock(pos, block, flag); + return true; + } + CraftBlockState blockState = CraftBlockState.getBlockState(world, pos, flag); + blockState.setData(block); + + BlockFormEvent event = (entity == null) ? new BlockFormEvent(blockState.getBlock(), blockState) : new EntityBlockFormEvent(((EntityBridge) entity).bridge$getBukkitEntity(), blockState.getBlock(), blockState); + Bukkit.getPluginManager().callEvent(event); + + if (!event.isCancelled()) { + blockState.update(true); + } + + return !event.isCancelled(); + } + + /** + * @author IzzelAliz + * @reason + */ + @Overwrite + public static BlockFadeEvent callBlockFadeEvent(LevelAccessor world, BlockPos pos, net.minecraft.world.level.block.state.BlockState newBlock) { + // Suppress during worldgen + if (!(world instanceof Level) || !DistValidate.isValid(world)) { + return new BlockFadeEvent(CraftBlock.at(world, pos), new CraftBlockState(CraftMagicNumbers.getMaterial(newBlock.getBlock()))); + } + CraftBlockState state = CraftBlockState.getBlockState(world, pos); + state.setData(newBlock); + + BlockFadeEvent event = new BlockFadeEvent(state.getBlock(), state); + Bukkit.getPluginManager().callEvent(event); + return event; + } + + /** + * @author IzzelAliz + * @reason + */ + @Overwrite + public static BlockPhysicsEvent callBlockPhysicsEvent(LevelAccessor world, BlockPos blockposition) { + org.bukkit.block.Block block = CraftBlock.at(world, blockposition); + BlockPhysicsEvent event = new BlockPhysicsEvent(block, block.getBlockData()); + // Suppress during worldgen + if (world instanceof Level && DistValidate.isValid(world)) { + Bukkit.getPluginManager().callEvent(event); + } + return event; + } + + /** + * @author IzzelAliz + * @reason + */ + @Overwrite + public static EntityChangeBlockEvent callEntityChangeBlockEvent(Entity entity, BlockPos position, net.minecraft.world.level.block.state.BlockState newBlock, boolean cancelled) { + Block block = CraftBlock.at(entity.level, position); + EntityChangeBlockEvent event = new EntityChangeBlockEvent(((EntityBridge) entity).bridge$getBukkitEntity(), block, CraftBlockData.fromData(newBlock)); + event.setCancelled(cancelled); + // Suppress during worldgen + if (DistValidate.isValid(entity.level)) { + Bukkit.getPluginManager().callEvent(event); + } + return event; + } + + /** + * @author IzzelAliz + * @reason + */ + @Overwrite + public static BlockRedstoneEvent callRedstoneChange(Level world, BlockPos pos, int oldCurrent, int newCurrent) { + BlockRedstoneEvent event = new BlockRedstoneEvent(CraftBlock.at(world, pos), oldCurrent, newCurrent); + // Suppress during worldgen + if (DistValidate.isValid(world)) { + Bukkit.getPluginManager().callEvent(event); + } + return event; + } + + /** + * @author IzzelAliz + * @reason + */ + @Overwrite + public static NotePlayEvent callNotePlayEvent(Level world, BlockPos pos, NoteBlockInstrument instrument, int note) { + NotePlayEvent event = new NotePlayEvent(CraftBlock.at(world, pos), org.bukkit.Instrument.getByType((byte) instrument.ordinal()), new org.bukkit.Note(note)); + // Suppress during worldgen + if (DistValidate.isValid(world)) { + Bukkit.getPluginManager().callEvent(event); + } + return event; + } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/fluid/FlowingFluidMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/fluid/FlowingFluidMixin.java index 19d4dbf8..04cd4345 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/fluid/FlowingFluidMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/fluid/FlowingFluidMixin.java @@ -1,5 +1,6 @@ package io.izzel.arclight.common.mixin.core.fluid; +import io.izzel.arclight.common.mod.util.DistValidate; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.world.level.BlockGetter; @@ -33,6 +34,7 @@ public abstract class FlowingFluidMixin { @Inject(method = "spread", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/material/FlowingFluid;spreadTo(Lnet/minecraft/world/level/LevelAccessor;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/Direction;Lnet/minecraft/world/level/material/FluidState;)V")) public void arclight$flowInto(LevelAccessor worldIn, BlockPos pos, FluidState stateIn, CallbackInfo ci) { + if (!DistValidate.isValid(worldIn)) return; Block source = CraftBlock.at(worldIn, pos); BlockFromToEvent event = new BlockFromToEvent(source, BlockFace.DOWN); Bukkit.getPluginManager().callEvent(event); @@ -44,6 +46,7 @@ public abstract class FlowingFluidMixin { @Redirect(method = "spreadToSides", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/material/FlowingFluid;canSpreadTo(Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/Direction;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/material/FluidState;Lnet/minecraft/world/level/material/Fluid;)Z")) public boolean arclight$flowInto(FlowingFluid flowingFluid, BlockGetter worldIn, BlockPos fromPos, BlockState fromBlockState, Direction direction, BlockPos toPos, BlockState toBlockState, FluidState toFluidState, Fluid fluidIn) { if (this.canSpreadTo(worldIn, fromPos, fromBlockState, direction, toPos, toBlockState, toFluidState, fluidIn)) { + if (!DistValidate.isValid(worldIn)) return true; Block source = CraftBlock.at(((Level) worldIn), fromPos); BlockFromToEvent event = new BlockFromToEvent(source, CraftBlock.notchToBlockFace(direction)); Bukkit.getPluginManager().callEvent(event); @@ -55,6 +58,7 @@ public abstract class FlowingFluidMixin { @Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;setBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;I)Z")) private boolean arclight$fluidLevelChange(Level world, BlockPos pos, BlockState newState, int flags) { + if (!DistValidate.isValid(world)) return world.setBlock(pos, newState, flags); FluidLevelChangeEvent event = CraftEventFactory.callFluidLevelChangeEvent(world, pos, newState); if (event.isCancelled()) { return false; diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/fluid/LavaFluidMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/fluid/LavaFluidMixin.java index 239eb54f..409c5400 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/fluid/LavaFluidMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/fluid/LavaFluidMixin.java @@ -1,6 +1,7 @@ package io.izzel.arclight.common.mixin.core.fluid; import io.izzel.arclight.common.bridge.core.world.IWorldBridge; +import io.izzel.arclight.common.mod.util.DistValidate; import io.izzel.arclight.mixin.Eject; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -51,7 +52,7 @@ public abstract class LavaFluidMixin { if (blockstate.isAir()) { if (this.hasFlammableNeighbours(world, blockpos)) { if (world.getBlockState(blockpos).getBlock() != Blocks.FIRE) { - if (CraftEventFactory.callBlockIgniteEvent(world, blockpos, pos).isCancelled()) { + if (DistValidate.isValid(world) && CraftEventFactory.callBlockIgniteEvent(world, blockpos, pos).isCancelled()) { continue; } } @@ -72,7 +73,7 @@ public abstract class LavaFluidMixin { if (world.isEmptyBlock(blockpos1.above()) && this.isFlammable(world, blockpos1, Direction.UP)) { BlockPos up = blockpos1.above(); if (world.getBlockState(up).getBlock() != Blocks.FIRE) { - if (CraftEventFactory.callBlockIgniteEvent(world, up, pos).isCancelled()) { + if (DistValidate.isValid(world) && CraftEventFactory.callBlockIgniteEvent(world, up, pos).isCancelled()) { continue; } } @@ -86,6 +87,7 @@ public abstract class LavaFluidMixin { @Eject(method = "spreadTo", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/LevelAccessor;setBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;I)Z")) private boolean arclight$blockFromTo(LevelAccessor world, BlockPos pos, BlockState newState, int flags, CallbackInfo ci) { + if (!DistValidate.isValid(world)) return world.setBlock(pos, newState, flags); if (!CraftEventFactory.handleBlockFormEvent(((IWorldBridge) world).bridge$getMinecraftWorld(), pos, newState, flags)) { ci.cancel(); return false; diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/level/ServerLevelMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/level/ServerLevelMixin.java index 73a3d4b8..6cf75843 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/level/ServerLevelMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/level/ServerLevelMixin.java @@ -15,6 +15,7 @@ import io.izzel.arclight.common.mixin.core.world.level.LevelMixin; import io.izzel.arclight.common.mod.server.world.WorldSymlink; import io.izzel.arclight.common.mod.util.ArclightCaptures; import io.izzel.arclight.common.mod.util.DelegateWorldInfo; +import io.izzel.arclight.common.mod.util.DistValidate; import io.izzel.arclight.i18n.ArclightConfig; import net.minecraft.core.BlockPos; import net.minecraft.core.particles.ParticleOptions; @@ -34,6 +35,7 @@ import net.minecraft.world.entity.LightningBolt; import net.minecraft.world.level.CustomSpawner; import net.minecraft.world.level.Explosion; import net.minecraft.world.level.ExplosionDamageCalculator; +import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.entity.BlockEntity; @@ -113,7 +115,7 @@ public abstract class ServerLevelMixin extends LevelMixin implements ServerWorld this.generator = gen; this.environment = env; this.biomeProvider = biomeProvider; - if (gen != null) { + if (gen != null && this.chunkSource != null) { CustomChunkGenerator generator = new CustomChunkGenerator((ServerLevel) (Object) this, this.chunkSource.getGenerator(), gen); ((ServerChunkProviderBridge) this.chunkSource).bridge$setChunkGenerator(generator); } @@ -122,21 +124,25 @@ public abstract class ServerLevelMixin extends LevelMixin implements ServerWorld @Inject(method = "(Lnet/minecraft/server/MinecraftServer;Ljava/util/concurrent/Executor;Lnet/minecraft/world/level/storage/LevelStorageSource$LevelStorageAccess;Lnet/minecraft/world/level/storage/ServerLevelData;Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/world/level/dimension/DimensionType;Lnet/minecraft/server/level/progress/ChunkProgressListener;Lnet/minecraft/world/level/chunk/ChunkGenerator;ZJLjava/util/List;Z)V", at = @At("RETURN")) private void arclight$init(MinecraftServer minecraftServer, Executor backgroundExecutor, LevelStorageSource.LevelStorageAccess levelSave, ServerLevelData worldInfo, ResourceKey dimension, DimensionType dimensionType, ChunkProgressListener statusListener, ChunkGenerator chunkGenerator, boolean isDebug, long seed, List specialSpawners, boolean shouldBeTicking, CallbackInfo ci) { - this.pvpMode = minecraftServer.isPvpAllowed(); + this.pvpMode = minecraftServer != null && minecraftServer.isPvpAllowed(); this.convertable = levelSave; - this.uuid = WorldUUID.getUUID(levelSave.getDimensionPath(this.dimension())); + this.uuid = levelSave != null ? WorldUUID.getUUID(levelSave.getDimensionPath(this.dimension())) : UUID.randomUUID(); if (worldInfo instanceof PrimaryLevelData) { this.$$worldDataServer = (PrimaryLevelData) worldInfo; } else if (worldInfo instanceof DerivedLevelData) { // damn spigot again this.$$worldDataServer = DelegateWorldInfo.wrap(((DerivedLevelData) worldInfo)); ((DerivedWorldInfoBridge) worldInfo).bridge$setDimType(this.getTypeKey()); - if (ArclightConfig.spec().getCompat().isSymlinkWorld()) { + if (levelSave != null && ArclightConfig.spec().getCompat().isSymlinkWorld()) { WorldSymlink.create((DerivedLevelData) worldInfo, levelSave.getDimensionPath(this.dimension())); } } - ((ServerChunkProviderBridge) this.chunkSource).bridge$setViewDistance(spigotConfig.viewDistance); - ((WorldInfoBridge) this.$$worldDataServer).bridge$setWorld((ServerLevel) (Object) this); + if (this.chunkSource != null) { + ((ServerChunkProviderBridge) this.chunkSource).bridge$setViewDistance(spigotConfig.viewDistance); + } + if (this.$$worldDataServer != null) { + ((WorldInfoBridge) this.$$worldDataServer).bridge$setWorld((ServerLevel) (Object) this); + } } public LevelChunk getChunkIfLoaded(int x, int z) { @@ -190,9 +196,11 @@ public abstract class ServerLevelMixin extends LevelMixin implements ServerWorld cause = arclight$cause; arclight$cause = null; } - LightningStrikeEvent lightning = CraftEventFactory.callLightningStrikeEvent((LightningStrike) ((EntityBridge) entity).bridge$getBukkitEntity(), cause); - if (lightning.isCancelled()) { - return false; + if (DistValidate.isValid((LevelAccessor) this)) { + LightningStrikeEvent lightning = CraftEventFactory.callLightningStrikeEvent((LightningStrike) ((EntityBridge) entity).bridge$getBukkitEntity(), cause); + if (lightning.isCancelled()) { + return false; + } } return this.addFreshEntity(entity); } @@ -204,7 +212,9 @@ public abstract class ServerLevelMixin extends LevelMixin implements ServerWorld @Inject(method = "save", at = @At(value = "JUMP", ordinal = 0, opcode = Opcodes.IFNULL)) private void arclight$worldSaveEvent(ProgressListener progress, boolean flush, boolean skipSave, CallbackInfo ci) { - Bukkit.getPluginManager().callEvent(new WorldSaveEvent(bridge$getWorld())); + if (DistValidate.isValid((LevelAccessor) this)) { + Bukkit.getPluginManager().callEvent(new WorldSaveEvent(bridge$getWorld())); + } } @Inject(method = "save", at = @At("RETURN")) @@ -264,7 +274,7 @@ public abstract class ServerLevelMixin extends LevelMixin implements ServerWorld private void arclight$addEntityEvent(Entity entityIn, CallbackInfoReturnable cir) { CreatureSpawnEvent.SpawnReason reason = arclight$reason == null ? CreatureSpawnEvent.SpawnReason.DEFAULT : arclight$reason; arclight$reason = null; - if (!CraftEventFactory.doEntityAddEventCalling((ServerLevel) (Object) this, entityIn, reason)) { + if (DistValidate.isValid((LevelAccessor) this) && !CraftEventFactory.doEntityAddEventCalling((ServerLevel) (Object) this, entityIn, reason)) { cir.setReturnValue(false); } } @@ -406,6 +416,11 @@ public abstract class ServerLevelMixin extends LevelMixin implements ServerWorld BlockPos.betweenClosed(i - 2, j, k - 2, i + 2, j, k + 2).forEach((pos) -> { blockList.setBlock(pos, Blocks.OBSIDIAN.defaultBlockState(), 3); }); + if (!DistValidate.isValid(world)) { + blockList.updateList(); + ArclightCaptures.getEndPortalEntity(); + return; + } CraftWorld bworld = ((WorldBridge) world).bridge$getWorld(); boolean spawnPortal = ArclightCaptures.getEndPortalSpawn(); Entity entity = ArclightCaptures.getEndPortalEntity(); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/ArmorStandItemMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/ArmorStandItemMixin.java index f0973eea..720f009e 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/ArmorStandItemMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/ArmorStandItemMixin.java @@ -1,5 +1,6 @@ package io.izzel.arclight.common.mixin.core.world.item; +import io.izzel.arclight.common.mod.util.DistValidate; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.decoration.ArmorStand; import net.minecraft.world.item.ArmorStandItem; @@ -24,7 +25,7 @@ public class ArmorStandItemMixin { @Inject(method = "useOn", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;addFreshEntityWithPassengers(Lnet/minecraft/world/entity/Entity;)V")) public void arclight$entityPlace(UseOnContext context, CallbackInfoReturnable cir) { - if (CraftEventFactory.callEntityPlaceEvent(context, arclight$entity).isCancelled()) { + if (DistValidate.isValid(context) && CraftEventFactory.callEntityPlaceEvent(context, arclight$entity).isCancelled()) { cir.setReturnValue(InteractionResult.FAIL); } arclight$entity = null; diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/BlockItemMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/BlockItemMixin.java index 2b864b0d..6ec97c6d 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/BlockItemMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/BlockItemMixin.java @@ -1,6 +1,7 @@ package io.izzel.arclight.common.mixin.core.world.item; import io.izzel.arclight.common.bridge.core.entity.player.ServerPlayerEntityBridge; +import io.izzel.arclight.common.mod.util.DistValidate; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.server.level.ServerLevel; @@ -52,7 +53,7 @@ public abstract class BlockItemMixin { org.bukkit.block.BlockState state = arclight$state; arclight$state = null; BlockPos pos = context1.getClickedPos(); - if (state != null) { + if (state != null && DistValidate.isValid(context)) { org.bukkit.event.block.BlockPlaceEvent placeEvent = CraftEventFactory.callBlockPlaceEvent((ServerLevel) context1.getLevel(), context1.getPlayer(), context1.getHand(), state, pos.getX(), pos.getY(), pos.getZ()); if (placeEvent != null && (placeEvent.isCancelled() || !placeEvent.canBuild())) { state.update(true, false); @@ -90,7 +91,7 @@ public abstract class BlockItemMixin { Player player = (context.getPlayer() instanceof ServerPlayerEntityBridge) ? ((ServerPlayerEntityBridge) context.getPlayer()).bridge$getBukkitEntity() : null; BlockCanBuildEvent event = new BlockCanBuildEvent(CraftBlock.at(context.getLevel(), context.getClickedPos()), player, CraftBlockData.fromData(state), original); - Bukkit.getPluginManager().callEvent(event); + if (DistValidate.isValid(context)) Bukkit.getPluginManager().callEvent(event); return event.isBuildable(); } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/BoatItemMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/BoatItemMixin.java index 1daaba92..a4f9d88c 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/BoatItemMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/BoatItemMixin.java @@ -1,5 +1,6 @@ package io.izzel.arclight.common.mixin.core.world.item; +import io.izzel.arclight.common.mod.util.DistValidate; import net.minecraft.stats.Stats; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; @@ -66,10 +67,12 @@ public class BoatItemMixin extends Item { } if (result.getType() == HitResult.Type.BLOCK) { - PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(playerIn, Action.RIGHT_CLICK_BLOCK, result.getBlockPos(), result.getDirection(), itemstack, handIn); + if (DistValidate.isValid(worldIn)) { + PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(playerIn, Action.RIGHT_CLICK_BLOCK, result.getBlockPos(), result.getDirection(), itemstack, handIn); - if (event.isCancelled()) { - return new InteractionResultHolder<>(InteractionResult.PASS, itemstack); + if (event.isCancelled()) { + return new InteractionResultHolder<>(InteractionResult.PASS, itemstack); + } } Boat boatentity = new Boat(worldIn, result.getLocation().x, result.getLocation().y, result.getLocation().z); @@ -79,7 +82,7 @@ public class BoatItemMixin extends Item { return new InteractionResultHolder<>(InteractionResult.FAIL, itemstack); } else { if (!worldIn.isClientSide) { - if (CraftEventFactory.callEntityPlaceEvent(worldIn, result.getBlockPos(), result.getDirection(), playerIn, boatentity).isCancelled()) { + if (DistValidate.isValid(worldIn) && CraftEventFactory.callEntityPlaceEvent(worldIn, result.getBlockPos(), result.getDirection(), playerIn, boatentity).isCancelled()) { return new InteractionResultHolder<>(InteractionResult.FAIL, itemstack); } if (!worldIn.addFreshEntity(boatentity)) { diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/BucketItemMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/BucketItemMixin.java index 2d61748d..add9a48b 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/BucketItemMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/BucketItemMixin.java @@ -1,6 +1,7 @@ package io.izzel.arclight.common.mixin.core.world.item; import io.izzel.arclight.common.bridge.core.entity.player.ServerPlayerEntityBridge; +import io.izzel.arclight.common.mod.util.DistValidate; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.network.protocol.game.ClientboundBlockUpdatePacket; @@ -39,7 +40,8 @@ public abstract class BucketItemMixin { @Inject(method = "use", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/BucketPickup;pickupBlock(Lnet/minecraft/world/level/LevelAccessor;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;)Lnet/minecraft/world/item/ItemStack;")) private void arclight$bucketFill(Level worldIn, Player playerIn, InteractionHand handIn, CallbackInfoReturnable> cir, ItemStack stack, BlockHitResult result) { - BlockPos pos = ((BlockHitResult) result).getBlockPos(); + if (!DistValidate.isValid(worldIn)) return; + BlockPos pos = result.getBlockPos(); BlockState state = worldIn.getBlockState(pos); ItemStack dummyFluid = ((BucketPickup) state.getBlock()).pickupBlock(DummyGeneratorAccess.INSTANCE, pos, state); PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) worldIn, playerIn, pos, pos, result.getDirection(), stack, dummyFluid.getItem()); @@ -93,6 +95,7 @@ public abstract class BucketItemMixin { @Inject(method = "emptyContents", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/dimension/DimensionType;ultraWarm()Z")) private void arclight$bucketEmpty(Player player, Level worldIn, BlockPos posIn, BlockHitResult rayTrace, CallbackInfoReturnable cir) { + if (!DistValidate.isValid(worldIn)) return; if (player != null) { PlayerBucketEmptyEvent event = CraftEventFactory.callPlayerBucketEmptyEvent((ServerLevel) worldIn, player, posIn, arclight$click, arclight$direction, arclight$stack); if (event.isCancelled()) { diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/ChorusFruitItemMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/ChorusFruitItemMixin.java index 49b0bb53..6838786d 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/ChorusFruitItemMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/ChorusFruitItemMixin.java @@ -1,6 +1,7 @@ package io.izzel.arclight.common.mixin.core.world.item; import io.izzel.arclight.common.bridge.core.entity.player.ServerPlayerEntityBridge; +import io.izzel.arclight.common.mod.util.DistValidate; import net.minecraft.server.level.ServerPlayer; import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundEvents; @@ -44,7 +45,7 @@ public class ChorusFruitItemMixin extends Item { double d4 = Mth.clamp(entityLiving.getY() + (double) (entityLiving.getRandom().nextInt(16) - 8), 0.0D, worldIn.getHeight() - 1); double d5 = entityLiving.getZ() + (entityLiving.getRandom().nextDouble() - 0.5D) * 16.0D; - if (entityLiving instanceof ServerPlayer) { + if (entityLiving instanceof ServerPlayer && DistValidate.isValid(worldIn)) { Player player = ((ServerPlayerEntityBridge) entityLiving).bridge$getBukkitEntity(); PlayerTeleportEvent event = new PlayerTeleportEvent(player, player.getLocation(), new Location(player.getWorld(), d3, d4, d5), PlayerTeleportEvent.TeleportCause.CHORUS_FRUIT); Bukkit.getPluginManager().callEvent(event); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/CrossbowItemMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/CrossbowItemMixin.java index 827bd1b0..4587adf2 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/CrossbowItemMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/CrossbowItemMixin.java @@ -2,6 +2,7 @@ package io.izzel.arclight.common.mixin.core.world.item; import io.izzel.arclight.common.bridge.core.entity.EntityBridge; import io.izzel.arclight.common.bridge.core.entity.player.ServerPlayerEntityBridge; +import io.izzel.arclight.common.mod.util.DistValidate; import io.izzel.arclight.mixin.Eject; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.InteractionHand; @@ -25,6 +26,10 @@ public class CrossbowItemMixin { @Inject(method = "shootProjectile", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/ItemStack;hurtAndBreak(ILnet/minecraft/world/entity/LivingEntity;Ljava/util/function/Consumer;)V")) private static void arclight$entityShoot(Level worldIn, LivingEntity shooter, InteractionHand handIn, ItemStack crossbow, ItemStack projectile, float soundPitch, boolean isCreativeMode, float velocity, float inaccuracy, float projectileAngle, CallbackInfo ci, boolean flag, Projectile proj) { + if (!DistValidate.isValid(worldIn)) { + arclight$capturedBoolean = true; + return; + } EntityShootBowEvent event = CraftEventFactory.callEntityShootBowEvent(shooter, crossbow, projectile, proj, shooter.getUsedItemHand(), soundPitch, true); if (event.isCancelled()) { event.getProjectile().remove(); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/EnderCrystalItemMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/EnderCrystalItemMixin.java index 0c200c65..5e8728bc 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/EnderCrystalItemMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/EnderCrystalItemMixin.java @@ -1,5 +1,6 @@ package io.izzel.arclight.common.mixin.core.world.item; +import io.izzel.arclight.common.mod.util.DistValidate; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.boss.enderdragon.EndCrystal; import net.minecraft.world.item.EndCrystalItem; @@ -24,7 +25,7 @@ public class EnderCrystalItemMixin { @Inject(method = "useOn", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;addFreshEntity(Lnet/minecraft/world/entity/Entity;)Z")) public void arclight$entityPlace(UseOnContext context, CallbackInfoReturnable cir) { - if (CraftEventFactory.callEntityPlaceEvent(context, arclight$enderCrystalEntity).isCancelled()) { + if (DistValidate.isValid(context) && CraftEventFactory.callEntityPlaceEvent(context, arclight$enderCrystalEntity).isCancelled()) { cir.setReturnValue(InteractionResult.FAIL); } arclight$enderCrystalEntity = null; diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/FireChargeItemMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/FireChargeItemMixin.java index 3abe6924..2d62984c 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/FireChargeItemMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/FireChargeItemMixin.java @@ -1,5 +1,6 @@ package io.izzel.arclight.common.mixin.core.world.item; +import io.izzel.arclight.common.mod.util.DistValidate; import net.minecraft.core.BlockPos; import net.minecraft.world.InteractionResult; import net.minecraft.world.item.FireChargeItem; @@ -19,7 +20,7 @@ public class FireChargeItemMixin { @Inject(method = "useOn", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/FireChargeItem;playSound(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;)V")) public void arclight$blockIgnite(UseOnContext context, CallbackInfoReturnable cir, Level world, BlockPos blockPos) { - if (CraftEventFactory.callBlockIgniteEvent(world, blockPos, BlockIgniteEvent.IgniteCause.FIREBALL, context.getPlayer()).isCancelled()) { + if (DistValidate.isValid(context) && CraftEventFactory.callBlockIgniteEvent(world, blockPos, BlockIgniteEvent.IgniteCause.FIREBALL, context.getPlayer()).isCancelled()) { if (!context.getPlayer().getAbilities().instabuild) { context.getItemInHand().shrink(1); } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/FishingRodItemMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/FishingRodItemMixin.java index 9cce6c1a..4315f561 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/FishingRodItemMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/FishingRodItemMixin.java @@ -2,6 +2,7 @@ package io.izzel.arclight.common.mixin.core.world.item; import io.izzel.arclight.common.bridge.core.entity.EntityBridge; import io.izzel.arclight.common.bridge.core.entity.player.ServerPlayerEntityBridge; +import io.izzel.arclight.common.mod.util.DistValidate; import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; import net.minecraft.stats.Stats; @@ -51,12 +52,14 @@ public class FishingRodItemMixin extends Item { int j = EnchantmentHelper.getFishingLuckBonus(itemstack); FishingHook hook = new FishingHook(playerIn, worldIn, j, k); - PlayerFishEvent playerFishEvent = new PlayerFishEvent(((ServerPlayerEntityBridge) playerIn).bridge$getBukkitEntity(), null, (FishHook) ((EntityBridge) hook).bridge$getBukkitEntity(), PlayerFishEvent.State.FISHING); - Bukkit.getPluginManager().callEvent(playerFishEvent); + if (DistValidate.isValid(worldIn)) { + PlayerFishEvent playerFishEvent = new PlayerFishEvent(((ServerPlayerEntityBridge) playerIn).bridge$getBukkitEntity(), null, (FishHook) ((EntityBridge) hook).bridge$getBukkitEntity(), PlayerFishEvent.State.FISHING); + Bukkit.getPluginManager().callEvent(playerFishEvent); - if (playerFishEvent.isCancelled()) { - playerIn.fishing = null; - return new InteractionResultHolder<>(InteractionResult.PASS, itemstack); + if (playerFishEvent.isCancelled()) { + playerIn.fishing = null; + return new InteractionResultHolder<>(InteractionResult.PASS, itemstack); + } } worldIn.playSound(null, playerIn.getX(), playerIn.getY(), playerIn.getZ(), SoundEvents.FISHING_BOBBER_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (worldIn.getRandom().nextFloat() * 0.4F + 0.8F)); worldIn.addFreshEntity(new FishingHook(playerIn, worldIn, j, k)); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/FlintAndSteelItemMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/FlintAndSteelItemMixin.java index 91ae4075..7a27947c 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/FlintAndSteelItemMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/FlintAndSteelItemMixin.java @@ -1,5 +1,6 @@ package io.izzel.arclight.common.mixin.core.world.item; +import io.izzel.arclight.common.mod.util.DistValidate; import net.minecraft.core.BlockPos; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.player.Player; @@ -18,6 +19,7 @@ public class FlintAndSteelItemMixin { @Inject(method = "useOn", cancellable = true, at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/world/level/Level;playSound(Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/core/BlockPos;Lnet/minecraft/sounds/SoundEvent;Lnet/minecraft/sounds/SoundSource;FF)V")) public void arclight$blockIgnite(UseOnContext context, CallbackInfoReturnable cir) { + if (!DistValidate.isValid(context)) return; Player playerentity = context.getPlayer(); Level world = context.getLevel(); BlockPos blockpos = context.getClickedPos(); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/HangingEntityItemMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/HangingEntityItemMixin.java index 99c89d3f..8c08d532 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/HangingEntityItemMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/HangingEntityItemMixin.java @@ -2,6 +2,7 @@ package io.izzel.arclight.common.mixin.core.world.item; import io.izzel.arclight.common.bridge.core.entity.EntityBridge; import io.izzel.arclight.common.bridge.core.entity.player.PlayerEntityBridge; +import io.izzel.arclight.common.mod.util.DistValidate; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.world.InteractionResult; @@ -30,6 +31,7 @@ public class HangingEntityItemMixin { @Inject(method = "useOn", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/decoration/HangingEntity;playPlacementSound()V")) public void arclight$hangingPlace(UseOnContext context, CallbackInfoReturnable cir, BlockPos blockPos, Direction direction, BlockPos blockPos1, net.minecraft.world.entity.player.Player playerEntity, ItemStack itemStack, Level world, HangingEntity hangingEntity) { + if (!DistValidate.isValid(context)) return; Player who = (context.getPlayer() == null) ? null : (Player) ((PlayerEntityBridge) context.getPlayer()).bridge$getBukkitEntity(); Block blockClicked = CraftBlock.at(world, blockPos); BlockFace blockFace = CraftBlock.notchToBlockFace(direction); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/MinecartItemMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/MinecartItemMixin.java index aaa41e28..85e984b3 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/MinecartItemMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/MinecartItemMixin.java @@ -1,5 +1,6 @@ package io.izzel.arclight.common.mixin.core.world.item; +import io.izzel.arclight.common.mod.util.DistValidate; import io.izzel.arclight.mixin.Eject; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.Entity; @@ -16,7 +17,7 @@ public class MinecartItemMixin { @Eject(method = "useOn", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;addFreshEntity(Lnet/minecraft/world/entity/Entity;)Z")) private boolean arclight$entityPlace(Level world, Entity entityIn, CallbackInfoReturnable cir, UseOnContext context) { - if (CraftEventFactory.callEntityPlaceEvent(context, entityIn).isCancelled()) { + if (DistValidate.isValid(world) && CraftEventFactory.callEntityPlaceEvent(context, entityIn).isCancelled()) { cir.setReturnValue(InteractionResult.FAIL); return false; } else if (!world.addFreshEntity(entityIn)) { diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/TridentItemMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/TridentItemMixin.java index 8073788d..16d16284 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/TridentItemMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/TridentItemMixin.java @@ -2,6 +2,7 @@ package io.izzel.arclight.common.mixin.core.world.item; import io.izzel.arclight.common.bridge.core.entity.player.ServerPlayerEntityBridge; import io.izzel.arclight.common.bridge.core.entity.projectile.TridentEntityBridge; +import io.izzel.arclight.common.mod.util.DistValidate; import io.izzel.arclight.mixin.Eject; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.Entity; @@ -47,6 +48,7 @@ public class TridentItemMixin { @Inject(method = "releaseUsing", at = @At(value = "INVOKE", ordinal = 1, target = "Lnet/minecraft/world/entity/player/Player;getYRot()F")) public void arclight$riptide(ItemStack stack, Level worldIn, LivingEntity entityLiving, int timeLeft, CallbackInfo ci) { + if (!DistValidate.isValid(worldIn)) return; PlayerRiptideEvent event = new PlayerRiptideEvent(((ServerPlayerEntityBridge) entityLiving).bridge$getBukkitEntity(), CraftItemStack.asCraftMirror(stack)); Bukkit.getPluginManager().callEvent(event); } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/BasePressurePlateBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/BasePressurePlateBlockMixin.java index 8af4e8fa..d1d1bc54 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/BasePressurePlateBlockMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/BasePressurePlateBlockMixin.java @@ -1,5 +1,6 @@ package io.izzel.arclight.common.mixin.core.world.level.block; +import io.izzel.arclight.common.mod.util.DistValidate; import net.minecraft.core.BlockPos; import net.minecraft.world.entity.Entity; import net.minecraft.world.level.Level; @@ -29,7 +30,7 @@ public abstract class BasePressurePlateBlockMixin { boolean flag = oldRedstoneStrength > 0; boolean flag1 = newStrength > 0; - if (flag != flag1) { + if (flag != flag1 && DistValidate.isValid(world)) { BlockRedstoneEvent event = new BlockRedstoneEvent(CraftBlock.at(worldIn, blockPos), oldRedstoneStrength, newStrength); Bukkit.getPluginManager().callEvent(event); newStrength = event.getNewCurrent(); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/BlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/BlockMixin.java index 599814bf..9fea682f 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/BlockMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/BlockMixin.java @@ -3,6 +3,7 @@ package io.izzel.arclight.common.mixin.core.world.level.block; import io.izzel.arclight.common.bridge.core.block.BlockBridge; import io.izzel.arclight.common.mixin.core.world.level.block.state.BlockBehaviourMixin; import io.izzel.arclight.common.mod.util.ArclightCaptures; +import io.izzel.arclight.common.mod.util.DistValidate; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; @@ -78,7 +79,8 @@ public abstract class BlockMixin extends BlockBehaviourMixin implements BlockBri List blockDrops = ArclightCaptures.getBlockDrops(); org.bukkit.block.BlockState state = ArclightCaptures.getBlockBreakPlayerState(); BlockBreakEvent breakEvent = ArclightCaptures.resetBlockBreakPlayer(); - if (player instanceof ServerPlayer && blockDrops != null && (breakEvent == null || breakEvent.isDropItems())) { + if (player instanceof ServerPlayer && blockDrops != null && (breakEvent == null || breakEvent.isDropItems()) + && DistValidate.isValid(worldIn)) { CraftBlock craftBlock = CraftBlock.at(((CraftWorld) state.getWorld()).getHandle(), pos); CraftEventFactory.handleBlockDropItemEvent(craftBlock, state, ((ServerPlayer) player), blockDrops); } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/event/BlockBreakEventDispatcher.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/event/BlockBreakEventDispatcher.java index b2b8a52b..07c470d6 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/event/BlockBreakEventDispatcher.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/event/BlockBreakEventDispatcher.java @@ -2,6 +2,7 @@ package io.izzel.arclight.common.mod.server.event; import io.izzel.arclight.common.bridge.core.entity.EntityBridge; import io.izzel.arclight.common.bridge.core.entity.player.ServerPlayerEntityBridge; +import io.izzel.arclight.common.mod.util.DistValidate; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.block.Blocks; @@ -20,7 +21,7 @@ public class BlockBreakEventDispatcher { @SubscribeEvent(receiveCanceled = true) public void onBreakBlock(BlockEvent.BreakEvent event) { - if (!event.getWorld().isClientSide()) { + if (DistValidate.isValid(event.getWorld())) { CraftBlock craftBlock = CraftBlock.at(event.getWorld(), event.getPos()); BlockBreakEvent breakEvent = new BlockBreakEvent(craftBlock, ((ServerPlayerEntityBridge) event.getPlayer()).bridge$getBukkitEntity()); ArclightCaptures.captureBlockBreakPlayer(breakEvent); @@ -34,6 +35,7 @@ public class BlockBreakEventDispatcher { @SubscribeEvent public void onFarmlandBreak(BlockEvent.FarmlandTrampleEvent event) { + if (!DistValidate.isValid(event.getWorld())) return; Entity entity = event.getEntity(); Cancellable cancellable; if (entity instanceof Player) { diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/event/BlockPlaceEventDispatcher.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/event/BlockPlaceEventDispatcher.java index ce2ae9ab..2f66e4e2 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/event/BlockPlaceEventDispatcher.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/event/BlockPlaceEventDispatcher.java @@ -3,6 +3,7 @@ package io.izzel.arclight.common.mod.server.event; import io.izzel.arclight.common.bridge.core.entity.player.ServerPlayerEntityBridge; import io.izzel.arclight.common.mod.util.ArclightBlockSnapshot; import io.izzel.arclight.common.mod.util.ArclightCaptures; +import io.izzel.arclight.common.mod.util.DistValidate; import net.minecraft.core.Direction; import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.Entity; @@ -29,7 +30,7 @@ public class BlockPlaceEventDispatcher { if (entity instanceof ServerPlayerEntityBridge playerEntity) { Player player = playerEntity.bridge$getBukkitEntity(); Direction direction = ArclightCaptures.getPlaceEventDirection(); - if (direction != null) { + if (direction != null && DistValidate.isValid(event.getWorld())) { InteractionHand hand = ArclightCaptures.getPlaceEventHand(InteractionHand.MAIN_HAND); CraftBlock placedBlock = ArclightBlockSnapshot.fromBlockSnapshot(event.getBlockSnapshot(), true); CraftBlock againstBlock = CraftBlock.at(event.getWorld(), event.getPos().relative(direction.getOpposite())); @@ -64,7 +65,7 @@ public class BlockPlaceEventDispatcher { if (entity instanceof ServerPlayerEntityBridge playerEntity) { Player player = playerEntity.bridge$getBukkitEntity(); Direction direction = ArclightCaptures.getPlaceEventDirection(); - if (direction != null) { + if (direction != null && DistValidate.isValid(event.getWorld())) { InteractionHand hand = ArclightCaptures.getPlaceEventHand(InteractionHand.MAIN_HAND); List placedBlocks = new ArrayList<>(event.getReplacedBlockSnapshots().size()); for (BlockSnapshot snapshot : event.getReplacedBlockSnapshots()) { diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/DistValidate.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/DistValidate.java new file mode 100644 index 00000000..d8c00a9c --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/DistValidate.java @@ -0,0 +1,31 @@ +package io.izzel.arclight.common.mod.util; + +import io.izzel.arclight.i18n.ArclightConfig; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.WorldGenRegion; +import net.minecraft.world.item.context.UseOnContext; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.LevelAccessor; + +public class DistValidate { + + public static boolean isValid(UseOnContext context) { + return context != null && isValid(context.getLevel()); + } + + public static boolean isValid(LevelAccessor level) { + return level != null + && !level.isClientSide() + && isLogicWorld(level); + } + + public static boolean isValid(BlockGetter getter) { + return getter instanceof LevelAccessor level && isValid(level); + } + + private static boolean isLogicWorld(LevelAccessor level) { + var cl = level.getClass(); + return cl == ServerLevel.class || cl == WorldGenRegion.class + || ArclightConfig.spec().getCompat().getExtraLogicWorlds().contains(cl.getName()); + } +} diff --git a/i18n-config/src/main/java/io/izzel/arclight/i18n/conf/CompatSpec.java b/i18n-config/src/main/java/io/izzel/arclight/i18n/conf/CompatSpec.java index 1058513b..dadba0e2 100644 --- a/i18n-config/src/main/java/io/izzel/arclight/i18n/conf/CompatSpec.java +++ b/i18n-config/src/main/java/io/izzel/arclight/i18n/conf/CompatSpec.java @@ -5,6 +5,7 @@ import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable; import java.util.Map; import java.util.Optional; +import java.util.Set; @ConfigSerializable public class CompatSpec { @@ -19,6 +20,9 @@ public class CompatSpec { @Setting("symlink-world") private boolean symlinkWorld; + @Setting("extra-logic-worlds") + private Set extraLogicWorlds; + public Map getMaterials() { return materials; } @@ -38,4 +42,8 @@ public class CompatSpec { public boolean isSymlinkWorld() { return symlinkWorld; } + + public Set getExtraLogicWorlds() { + return extraLogicWorlds; + } } diff --git a/i18n-config/src/main/resources/META-INF/arclight.conf b/i18n-config/src/main/resources/META-INF/arclight.conf index 94fafed6..7cbd5bdc 100644 --- a/i18n-config/src/main/resources/META-INF/arclight.conf +++ b/i18n-config/src/main/resources/META-INF/arclight.conf @@ -14,6 +14,7 @@ compatibility { entity-property-overrides { } symlink-world = false + extra-logic-worlds = [] } async-catcher { dump = true