From 6a6a573a7d38b4bce2332b008dbe39def7d42f47 Mon Sep 17 00:00:00 2001 From: IzzelAliz Date: Mon, 1 Aug 2022 17:08:20 +0800 Subject: [PATCH] Update to 1.19.1 --- README.md | 15 +- arclight-common/build.gradle | 2 +- .../bridge/core/block/NoteBlockBridge.java | 10 - .../bridge/core/entity/EntityBridge.java | 4 +- .../core/entity/InternalEntityBridge.java | 3 - .../core/entity/LivingEntityBridge.java | 10 +- .../ai/attributes/RangedAttributeBridge.java | 6 - .../player/ServerPlayerEntityBridge.java | 4 - .../play/ServerPlayNetHandlerBridge.java | 1 - .../server/management/PlayerListBridge.java | 9 +- .../common/bridge/core/world/WorldBridge.java | 2 + .../common/mixin/bukkit/CraftBlockMixin.java | 3 +- .../common/mixin/bukkit/CraftEntityMixin.java | 2 +- .../common/mixin/bukkit/CraftServerMixin.java | 4 +- .../mixin/bukkit/CraftVillagerMixin.java | 3 +- .../common/mixin/bukkit/MaterialMixin.java | 2 +- .../commands/CommandSourceStackMixin.java | 11 + .../mixin/core/commands/CommandsMixin.java | 12 +- .../blocks/BlockStateParserMixin.java | 4 +- .../synchronization/ArgumentTypesMixin.java | 77 +--- .../mixin/core/fluid/LavaFluidMixin.java | 5 +- .../ServerHandshakeNetHandlerMixin.java | 9 +- .../network/ServerLoginNetHandlerMixin.java | 108 +++-- .../network/ServerPlayNetHandlerMixin.java | 372 +++++++++++------- .../network/ServerStatusNetHandlerMixin.java | 1 + .../game/CChatMessagePacketMixin.java | 32 -- .../protocol/game/SChatPacketMixin.java | 41 -- .../core/server/MinecraftServerMixin.java | 161 ++++---- .../server/WorldLoader_PackConfigMixin.java | 21 + .../mixin/core/server/WorldStemMixin.java | 21 - .../dedicated/DedicatedServerMixin.java | 2 +- .../core/server/level/ChunkMapMixin.java | 34 +- .../server/level/DistanceManagerMixin.java | 3 +- .../core/server/level/ServerEntityMixin.java | 35 +- .../core/server/level/ServerLevelMixin.java | 45 ++- .../server/management/PlayerListMixin.java | 53 ++- .../management/ServerPlayerGameModeMixin.java | 53 ++- .../mixin/core/world/ExplosionMixin.java | 19 +- .../core/world/effect/MobEffectUtilMixin.java | 33 ++ .../mixin/core/world/entity/EntityMixin.java | 45 +-- .../core/world/entity/LivingEntityMixin.java | 47 ++- .../mixin/core/world/entity/MobMixin.java | 1 - .../ai/attributes/RangedAttributeMixin.java | 29 -- .../AssignProfessionFromJobSiteMixin.java | 2 +- .../ai/behavior/StartAttackingMixin.java | 2 +- .../world/entity/ai/brain/BrainUtilMixin.java | 8 +- .../world/entity/animal/BucketableMixin.java | 4 +- .../animal/Fox_EatBerriesGoalMixin.java | 2 +- .../entity/animal/frog/TadpoleMixin.java | 32 ++ .../world/entity/animal/goat/GoatMixin.java | 31 ++ .../boss/enderdragon/EnderDragonMixin.java | 27 +- .../entity/decoration/ArmorStandMixin.java | 10 +- .../entity/decoration/ItemFrameMixin.java | 5 +- .../entity/monster/ElderGuardianMixin.java | 15 +- .../EnderMan_EndermanLeaveBlockGoalMixin.java | 5 +- .../EnderMan_EndermanTakeBlockGoalMixin.java | 5 +- .../world/entity/monster/ShulkerMixin.java | 3 + .../Silverfish_WakeUpFriendsGoalMixin.java | 5 +- .../world/entity/monster/StriderMixin.java | 20 + .../world/entity/monster/ZombieMixin.java | 6 +- .../entity/monster/warden/WardenMixin.java | 21 + .../entity/npc/InventoryCarrierMixin.java | 51 +++ .../core/world/entity/npc/VillagerMixin.java | 11 +- .../core/world/entity/player/PlayerMixin.java | 31 +- .../entity/player/ServerPlayerMixin.java | 67 ++-- .../core/world/entity/raid/RaidMixin.java | 6 +- .../entity/vehicle/AbstractMinecartMixin.java | 2 + .../world/entity/vehicle/ChestBoatMixin.java | 67 ++++ .../StructureFeatureManagerMixin.java | 19 - .../feature/structure/SwampHutPieceMixin.java | 11 +- .../template/TemplateManagerMixin.java | 29 -- .../inventory/AbstractContainerMenuMixin.java | 11 +- .../inventory/EnchantmentContainerMixin.java | 5 +- .../world/inventory/PlayerContainerMixin.java | 4 +- .../world/inventory/RepairContainerMixin.java | 4 +- .../mixin/core/world/item/BlockItemMixin.java | 4 +- .../mixin/core/world/item/BoatItemMixin.java | 5 +- .../core/world/item/ChorusFruitItemMixin.java | 8 +- .../core/world/item/FishingRodItemMixin.java | 3 + .../mixin/core/world/item/ItemStackMixin.java | 12 +- .../item/crafting/RecipeManagerMixin.java | 8 +- .../mixin/core/world/level/LevelMixin.java | 54 +-- .../world/level/block/BambooBlockMixin.java | 5 +- .../world/level/block/BaseFireBlockMixin.java | 18 + .../core/world/level/block/BedBlockMixin.java | 81 +++- .../level/block/BigDripleafBlockMixin.java | 57 +++ .../core/world/level/block/BlockMixin.java | 28 +- .../block/BuddingAmethystBlockMixin.java | 19 + .../world/level/block/ButtonBlockMixin.java | 24 +- .../level/block/ChangeOverTimeBlockMixin.java | 71 ++++ .../level/block/ChorusFlowerBlockMixin.java | 4 +- .../world/level/block/CoralBlockMixin.java | 5 +- .../world/level/block/CoralFanBlockMixin.java | 5 +- .../level/block/CoralPlantBlockMixin.java | 5 +- .../level/block/CoralWallFanBlockMixin.java | 5 +- .../world/level/block/DiodeBlockMixin.java | 7 +- .../world/level/block/DirtPathBlockMixin.java | 22 ++ .../world/level/block/DropperBlockMixin.java | 2 +- .../world/level/block/FireBlockMixin.java | 5 +- .../world/level/block/FungusBlockMixin.java | 5 +- .../block/GrowingPlantHeadBlockMixin.java | 5 +- .../world/level/block/LeavesBlockMixin.java | 5 +- .../level/block/LightningRodBlockMixin.java | 44 +++ .../level/block/MultifaceSpreaderMixin.java | 31 ++ .../MultifaceSpreader_SpreadConfigMixin.java | 41 ++ .../world/level/block/MushroomBlockMixin.java | 7 +- .../world/level/block/NoteBlockMixin.java | 35 +- .../world/level/block/NyliumBlockMixin.java | 24 ++ .../world/level/block/ObserverBlockMixin.java | 7 +- .../block/PointedDripstoneBlockMixin.java | 24 ++ .../level/block/PowderSnowBlockMixin.java | 24 ++ .../level/block/RedstoneLampBlockMixin.java | 5 +- .../level/block/RedstoneOreBlockMixin.java | 5 +- .../level/block/RedstoneTorchBlockMixin.java | 7 +- .../level/block/RootedDirtBlockMixin.java | 19 + .../level/block/ScaffoldingBlockMixin.java | 5 +- .../world/level/block/SculkBlockMixin.java | 21 + .../level/block/SculkSensorBlockMixin.java | 65 +++ .../level/block/SculkShriekerBlockMixin.java | 27 ++ .../level/block/SculkVeinBlockMixin.java | 38 ++ .../world/level/block/SnowBlockMixin.java | 5 +- .../level/block/SnowLayerBlockMixin.java | 24 ++ .../block/SpreadableSnowyDirtBlockMixin.java | 5 +- .../world/level/block/StemBlockMixin.java | 19 +- .../level/block/SweetBerryBushBlockMixin.java | 28 +- .../core/world/level/block/TntBlockMixin.java | 2 +- .../level/block/TripWireHookBlockMixin.java | 2 +- .../level/block/TurtleEggBlockMixin.java | 7 +- .../world/level/block/VineBlockMixin.java | 7 +- .../AbstractFurnaceBlockEntityMixin.java | 4 +- .../entity/BrewingStandBlockEntityMixin.java | 4 +- .../block/entity/CampfireTileEntityMixin.java | 11 +- .../block/entity/ChestBlockEntityMixin.java | 3 +- .../block/entity/CommandBlockLogicMixin.java | 7 +- .../entity/ContainerOpenersCounterMixin.java | 68 ++++ .../block/entity/LecternBlockEntityMixin.java | 3 +- .../entity/SculkCatalystBlockEntityMixin.java | 25 ++ .../block/entity/SignBlockEntityMixin.java | 3 +- .../properties/IntegerPropertyMixin.java | 20 - .../world/level/chunk/ChunkAccessMixin.java | 3 +- .../ChunkGeneratorMixin.java | 18 +- .../level/chunk/LevelChunkSectionMixin.java | 11 +- .../level/chunk/storage/ChunkLoaderMixin.java | 2 +- .../vibrations/VibrationListenerMixin.java | 47 ++- .../level/redstone/NeighborUpdaterMixin.java | 59 +++ .../level/storage/loot/LootTableMixin.java | 43 +- .../predicates/SurvivesExplosionMixin.java | 5 +- .../core/world/spawner/BaseSpawnerMixin.java | 2 + ...nerMixin.java => NaturalSpawnerMixin.java} | 7 +- .../world/spawner/PatrolSpawnerMixin.java | 11 +- .../storage/LevelStorageSourceMixin.java | 2 + ...StorageSource_LevelStorageAccessMixin.java | 8 +- ...oMixin.java => PrimaryLevelDataMixin.java} | 2 +- .../common/mixin/forge/NetworkHooksMixin.java | 2 +- .../dfu/BlockEntityTypeMixin_DFU.java | 17 - .../dfu/CraftMagicNumbersMixin_DFU.java | 21 - .../dfu/DataFixesManagerMixin_DFU.java | 19 - .../dfu/EntityType_BuilderMixin_DFU.java | 15 - .../mixin/optimization/dfu/MainMixin_DFU.java | 22 -- .../network/ChunkMapMixin_Optimize.java | 2 +- .../common/mod/ArclightConnector.java | 4 - .../common/mod/ArclightMixinPlugin.java | 2 +- .../common/mod/server/ArclightContainer.java | 9 + .../common/mod/server/ArclightServer.java | 22 ++ .../common/mod/server/BukkitRegistry.java | 74 ++-- .../entity/ArclightModChestedHorse.java | 2 +- .../mod/server/entity/ArclightModEntity.java | 2 +- .../mod/server/entity/ArclightModHorse.java | 2 +- .../entity/ArclightModLivingEntity.java | 2 +- .../server/entity/ArclightModMinecart.java | 2 +- .../entity/ArclightModMinecartContainer.java | 2 +- .../mod/server/entity/ArclightModMob.java | 2 +- .../server/entity/ArclightModProjectile.java | 2 +- .../mod/server/entity/ArclightModRaider.java | 2 +- .../ArclightEventDispatcherRegistry.java | 1 - .../event/BlockBreakEventDispatcher.java | 12 +- .../event/BlockPlaceEventDispatcher.java | 10 +- .../mod/server/event/ChunkEventHandler.java | 36 -- .../server/event/EntityEventDispatcher.java | 4 +- .../EntityPotionEffectEventDispatcher.java | 13 +- .../event/ItemEntityEventDispatcher.java | 2 +- .../server/event/WorldEventDispatcher.java | 8 +- .../common/mod/util/ArclightCaptures.java | 29 ++ .../common/mod/util/ArclightPingEvent.java | 4 +- .../common/mod/util/PluginEventHandler.java | 73 +++- .../mod/util/remapper/ClassLoaderRepo.java | 24 +- .../resources/META-INF/accesstransformer.cfg | 34 ++ .../main/resources/mixins.arclight.core.json | 39 +- ....arclight.impl.forge.optimization.dfu.json | 14 - arclight-forge/build.gradle | 43 +- .../arclight/boot/AbstractBootstrap.java | 2 +- .../boot/mod/ArclightLocator_Forge.java | 7 +- .../src/main/resources/async_catcher.json | 3 +- build.gradle | 8 +- .../forgeinstaller/ForgeInstaller.java | 4 +- .../arclight/i18n/conf/OptimizationSpec.java | 7 - 196 files changed, 2399 insertions(+), 1448 deletions(-) delete mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/block/NoteBlockBridge.java delete mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/entity/ai/attributes/RangedAttributeBridge.java delete mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/network/protocol/game/CChatMessagePacketMixin.java delete mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/network/protocol/game/SChatPacketMixin.java create mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/WorldLoader_PackConfigMixin.java delete mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/WorldStemMixin.java create mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/effect/MobEffectUtilMixin.java delete mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/ai/attributes/RangedAttributeMixin.java create mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/animal/frog/TadpoleMixin.java create mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/animal/goat/GoatMixin.java create mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/monster/StriderMixin.java create mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/monster/warden/WardenMixin.java create mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/npc/InventoryCarrierMixin.java create mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/vehicle/ChestBoatMixin.java delete mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/gen/feature/structure/StructureFeatureManagerMixin.java delete mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/gen/feature/template/TemplateManagerMixin.java create mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/BigDripleafBlockMixin.java create mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/BuddingAmethystBlockMixin.java create mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/ChangeOverTimeBlockMixin.java create mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/DirtPathBlockMixin.java create mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/LightningRodBlockMixin.java create mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/MultifaceSpreaderMixin.java create mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/MultifaceSpreader_SpreadConfigMixin.java create mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/NyliumBlockMixin.java create mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/PowderSnowBlockMixin.java create mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/RootedDirtBlockMixin.java create mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/SculkBlockMixin.java create mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/SculkSensorBlockMixin.java create mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/SculkShriekerBlockMixin.java create mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/SculkVeinBlockMixin.java create mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/SnowLayerBlockMixin.java create mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/entity/ContainerOpenersCounterMixin.java create mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/entity/SculkCatalystBlockEntityMixin.java delete mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/state/properties/IntegerPropertyMixin.java rename arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/{levelgen => chunk}/ChunkGeneratorMixin.java (81%) create mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/redstone/NeighborUpdaterMixin.java rename arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/spawner/{WorldEntitySpawnerMixin.java => NaturalSpawnerMixin.java} (97%) rename arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/storage/{ServerWorldInfoMixin.java => PrimaryLevelDataMixin.java} (97%) delete mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/optimization/dfu/BlockEntityTypeMixin_DFU.java delete mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/optimization/dfu/CraftMagicNumbersMixin_DFU.java delete mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/optimization/dfu/DataFixesManagerMixin_DFU.java delete mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/optimization/dfu/EntityType_BuilderMixin_DFU.java delete mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/optimization/dfu/MainMixin_DFU.java delete mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mod/server/event/ChunkEventHandler.java delete mode 100644 arclight-common/src/main/resources/mixins.arclight.impl.forge.optimization.dfu.json diff --git a/README.md b/README.md index a5a696ed..2ca3314e 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,14 @@ A Bukkit server implementation utilizing Mixin. ![Actions](https://img.shields.io/github/workflow/status/IzzelAliz/Arclight/Java%20CI%20with%20Gradle?style=flat-square) ![GitHub](https://img.shields.io/github/license/IzzelAliz/Arclight?style=flat-square) -| Minecraft | Forge | Status | Build | -| :----: |:-------:| :---: | :---: | -| 1.18.x | 40.1.59 | ACTIVE | [![1.18 Status](https://img.shields.io/appveyor/build/IzzelAliz/arclight-18?style=flat-square)](https://ci.appveyor.com/project/IzzelAliz/arclight-18) | -| 1.17.x | 37.1.0 | [LEGACY](https://github.com/IzzelAliz/Arclight/releases/tag/1.17/1.0.2) | [![1.17 Status](https://img.shields.io/appveyor/build/IzzelAliz/arclight-17?style=flat-square)](https://ci.appveyor.com/project/IzzelAliz/arclight-17) | -| 1.16.x | 36.2.26 | ACTIVE | [![1.16 Status](https://img.shields.io/appveyor/build/IzzelAliz/arclight-16?style=flat-square)](https://ci.appveyor.com/project/IzzelAliz/arclight-16) | -| 1.15.x | 31.2.48 | [LEGACY](https://github.com/IzzelAliz/Arclight/releases/tag/1.15/1.0.19) | [![1.15 Status](https://img.shields.io/appveyor/build/IzzelAliz/arclight-15?style=flat-square)](https://ci.appveyor.com/project/IzzelAliz/arclight-15) | -| 1.14.x | 28.2.0 | [LEGACY](https://github.com/IzzelAliz/Arclight/releases/tag/1.0.6) | [![1.14 Status](https://img.shields.io/appveyor/build/IzzelAliz/arclight?style=flat-square)](https://ci.appveyor.com/project/IzzelAliz/arclight) | +| Minecraft | Forge | Status | Build | +|:---------:|:-------:| :---: |:------------------------------------------------------------------------------------------------------------------------------------------------------:| +| 1.19.x | 42.0.0 | ACTIVE | [![1.19 Status](https://img.shields.io/appveyor/build/IzzelAliz/arclight-19?style=flat-square)](https://ci.appveyor.com/project/IzzelAliz/arclight-19) | +| 1.18.x | 40.1.59 | ACTIVE | [![1.18 Status](https://img.shields.io/appveyor/build/IzzelAliz/arclight-18?style=flat-square)](https://ci.appveyor.com/project/IzzelAliz/arclight-18) | +| 1.17.x | 37.1.0 | [LEGACY](https://github.com/IzzelAliz/Arclight/releases/tag/1.17/1.0.2) | [![1.17 Status](https://img.shields.io/appveyor/build/IzzelAliz/arclight-17?style=flat-square)](https://ci.appveyor.com/project/IzzelAliz/arclight-17) | +| 1.16.x | 36.2.26 | ACTIVE | [![1.16 Status](https://img.shields.io/appveyor/build/IzzelAliz/arclight-16?style=flat-square)](https://ci.appveyor.com/project/IzzelAliz/arclight-16) | +| 1.15.x | 31.2.48 | [LEGACY](https://github.com/IzzelAliz/Arclight/releases/tag/1.15/1.0.19) | [![1.15 Status](https://img.shields.io/appveyor/build/IzzelAliz/arclight-15?style=flat-square)](https://ci.appveyor.com/project/IzzelAliz/arclight-15) | +| 1.14.x | 28.2.0 | [LEGACY](https://github.com/IzzelAliz/Arclight/releases/tag/1.0.6) | [![1.14 Status](https://img.shields.io/appveyor/build/IzzelAliz/arclight?style=flat-square)](https://ci.appveyor.com/project/IzzelAliz/arclight) | * Legacy version still accepts pull requests. diff --git a/arclight-common/build.gradle b/arclight-common/build.gradle index b323cb87..870875d6 100644 --- a/arclight-common/build.gradle +++ b/arclight-common/build.gradle @@ -24,7 +24,7 @@ apply plugin: 'io.izzel.arclight' arclight { mcVersion = minecraftVersion forgeVersion = project.ext.forgeVersion - bukkitVersion = 'v1_18_R2' + bukkitVersion = 'v1_19_R1' wipeVersion = true reobfVersion = true accessTransformer = project.file('bukkit.at') diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/block/NoteBlockBridge.java b/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/block/NoteBlockBridge.java deleted file mode 100644 index 48534f39..00000000 --- a/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/block/NoteBlockBridge.java +++ /dev/null @@ -1,10 +0,0 @@ -package io.izzel.arclight.common.bridge.core.block; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.state.BlockState; - -public interface NoteBlockBridge { - - void bridge$play(Level worldIn, BlockPos pos, BlockState state); -} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/entity/EntityBridge.java b/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/entity/EntityBridge.java index d3afe892..22d394bd 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/entity/EntityBridge.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/entity/EntityBridge.java @@ -1,7 +1,7 @@ package io.izzel.arclight.common.bridge.core.entity; import io.izzel.arclight.common.bridge.core.command.ICommandSourceBridge; -import net.minecraft.core.BlockPos; +import net.minecraft.core.PositionImpl; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.Entity; import org.bukkit.craftbukkit.v.entity.CraftEntity; @@ -11,7 +11,7 @@ import java.util.List; public interface EntityBridge extends ICommandSourceBridge { - Entity bridge$teleportTo(ServerLevel world, BlockPos blockPos); + Entity bridge$teleportTo(ServerLevel world, PositionImpl blockPos); void bridge$setOnFire(int tick, boolean callEvent); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/entity/InternalEntityBridge.java b/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/entity/InternalEntityBridge.java index f8411b3e..007ee67d 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/entity/InternalEntityBridge.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/entity/InternalEntityBridge.java @@ -1,11 +1,8 @@ package io.izzel.arclight.common.bridge.core.entity; -import net.minecraft.core.BlockPos; import org.bukkit.craftbukkit.v.entity.CraftEntity; public interface InternalEntityBridge { CraftEntity internal$getBukkitEntity(); - - BlockPos internal$capturedPos(); } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/entity/LivingEntityBridge.java b/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/entity/LivingEntityBridge.java index ae3c32f3..de827148 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/entity/LivingEntityBridge.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/entity/LivingEntityBridge.java @@ -1,20 +1,20 @@ package io.izzel.arclight.common.bridge.core.entity; +import net.minecraft.world.effect.MobEffect; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.item.ItemStack; import org.bukkit.craftbukkit.v.entity.CraftLivingEntity; import org.bukkit.event.entity.EntityPotionEffectEvent; import org.bukkit.event.entity.EntityRegainHealthEvent; import java.util.Optional; -import net.minecraft.world.effect.MobEffect; -import net.minecraft.world.effect.MobEffectInstance; -import net.minecraft.world.entity.EquipmentSlot; -import net.minecraft.world.item.ItemStack; public interface LivingEntityBridge extends EntityBridge { void bridge$setSlot(EquipmentSlot slotIn, ItemStack stack, boolean silent); - void bridge$playEquipSound(ItemStack stack, boolean silent); + void bridge$playEquipSound(EquipmentSlot slot, ItemStack oldItem, ItemStack newItem, boolean silent); boolean bridge$canPickUpLoot(); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/entity/ai/attributes/RangedAttributeBridge.java b/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/entity/ai/attributes/RangedAttributeBridge.java deleted file mode 100644 index 82f76fe0..00000000 --- a/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/entity/ai/attributes/RangedAttributeBridge.java +++ /dev/null @@ -1,6 +0,0 @@ -package io.izzel.arclight.common.bridge.core.entity.ai.attributes; - -public interface RangedAttributeBridge { - - void bridge$setMaximumValue(double maximumValue); -} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/entity/player/ServerPlayerEntityBridge.java b/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/entity/player/ServerPlayerEntityBridge.java index c7f60c15..30bbc0d1 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/entity/player/ServerPlayerEntityBridge.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/entity/player/ServerPlayerEntityBridge.java @@ -26,10 +26,6 @@ public interface ServerPlayerEntityBridge extends PlayerEntityBridge { void bridge$setCompassTarget(Location location); - void bridge$sendMessage(Component[] ichatbasecomponent, UUID uuid); - - void bridge$sendMessage(Component component, UUID uuid); - boolean bridge$isJoining(); void bridge$reset(); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/network/play/ServerPlayNetHandlerBridge.java b/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/network/play/ServerPlayNetHandlerBridge.java index e2784e85..f85ed150 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/network/play/ServerPlayNetHandlerBridge.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/network/play/ServerPlayNetHandlerBridge.java @@ -3,7 +3,6 @@ package io.izzel.arclight.common.bridge.core.network.play; import org.bukkit.Location; import org.bukkit.event.player.PlayerTeleportEvent; -// todo public interface ServerPlayNetHandlerBridge { void bridge$pushTeleportCause(PlayerTeleportEvent.TeleportCause cause); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/server/management/PlayerListBridge.java b/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/server/management/PlayerListBridge.java index 55ed8e46..57c056da 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/server/management/PlayerListBridge.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/server/management/PlayerListBridge.java @@ -1,13 +1,14 @@ package io.izzel.arclight.common.bridge.core.server.management; import com.mojang.authlib.GameProfile; +import net.minecraft.network.chat.Component; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.network.ServerLoginPacketListenerImpl; +import net.minecraft.world.entity.player.ProfilePublicKey; import org.bukkit.craftbukkit.v.CraftServer; import java.net.SocketAddress; import java.util.List; -import net.minecraft.network.chat.Component; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.server.network.ServerLoginPacketListenerImpl; public interface PlayerListBridge { @@ -17,7 +18,7 @@ public interface PlayerListBridge { CraftServer bridge$getCraftServer(); - ServerPlayer bridge$canPlayerLogin(SocketAddress socketAddress, GameProfile gameProfile, ServerLoginPacketListenerImpl handler); + ServerPlayer bridge$canPlayerLogin(SocketAddress socketAddress, GameProfile gameProfile, ServerLoginPacketListenerImpl handler, ProfilePublicKey profilePublicKey); void bridge$sendMessage(Component[] components); } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/world/WorldBridge.java b/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/world/WorldBridge.java index 52bb64fd..6c27ebb9 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/world/WorldBridge.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/world/WorldBridge.java @@ -34,4 +34,6 @@ public interface WorldBridge extends IWorldWriterBridge, IWorldBridge { Object2LongOpenHashMap bridge$ticksPerSpawnCategory(); ResourceKey bridge$getTypeKey(); + + void bridge$setLastPhysicsProblem(BlockPos pos); } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/CraftBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/CraftBlockMixin.java index 67e46df7..e4bcc79d 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/CraftBlockMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/CraftBlockMixin.java @@ -4,6 +4,7 @@ import io.izzel.arclight.common.bridge.bukkit.MaterialBridge; import io.izzel.arclight.common.mod.util.ResourceLocationUtil; import net.minecraft.core.Holder; import net.minecraft.core.Registry; +import net.minecraftforge.registries.ForgeRegistries; import org.bukkit.Material; import org.bukkit.block.Biome; import org.bukkit.block.BlockState; @@ -36,6 +37,6 @@ public abstract class CraftBlockMixin { */ @Overwrite public static Biome biomeBaseToBiome(Registry registry, Holder base) { - return Biome.valueOf(ResourceLocationUtil.standardize(base.value().getRegistryName())); + return Biome.valueOf(ResourceLocationUtil.standardize(ForgeRegistries.BIOMES.getKey(base.value()))); } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/CraftEntityMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/CraftEntityMixin.java index 16f0ca45..c1ea705c 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/CraftEntityMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/CraftEntityMixin.java @@ -56,7 +56,7 @@ public abstract class CraftEntityMixin implements org.bukkit.entity.Entity { @Override public @NotNull EntityType getType() { if (this.arclight$type == null) { - ResourceLocation location = ForgeRegistries.ENTITIES.getKey(entity.getType()); + ResourceLocation location = ForgeRegistries.ENTITY_TYPES.getKey(entity.getType()); if (location == null) throw new IllegalArgumentException("Unregistered entity type " + entity.getType()); if (location.getNamespace().equals("minecraft")) { this.arclight$type = Objects.requireNonNull(EntityType.fromName(location.getPath().toUpperCase(Locale.ROOT))); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/CraftServerMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/CraftServerMixin.java index c0cb2290..d138f498 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/CraftServerMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/CraftServerMixin.java @@ -13,7 +13,7 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.server.players.PlayerList; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.CommandEvent; -import net.minecraftforge.event.world.WorldEvent; +import net.minecraftforge.event.level.LevelEvent; import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.command.CommandSender; @@ -112,7 +112,7 @@ public abstract class CraftServerMixin implements CraftServerBridge { @Inject(method = "unloadWorld(Lorg/bukkit/World;Z)Z", remap = false, require = 1, at = @At(value = "INVOKE", ordinal = 1, target = "Ljava/util/Map;remove(Ljava/lang/Object;)Ljava/lang/Object;")) private void arclight$unloadForge(World world, boolean save, CallbackInfoReturnable cir) { - MinecraftForge.EVENT_BUS.post(new WorldEvent.Unload(((CraftWorld) world).getHandle())); + MinecraftForge.EVENT_BUS.post(new LevelEvent.Unload(((CraftWorld) world).getHandle())); this.console.markWorldsDirty(); } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/CraftVillagerMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/CraftVillagerMixin.java index 9aa97ce4..88fe4fb4 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/CraftVillagerMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/CraftVillagerMixin.java @@ -2,6 +2,7 @@ package io.izzel.arclight.common.mixin.bukkit; import io.izzel.arclight.common.mod.util.ResourceLocationUtil; import net.minecraft.world.entity.npc.VillagerProfession; +import net.minecraftforge.registries.ForgeRegistries; import org.bukkit.craftbukkit.v.entity.CraftVillager; import org.bukkit.entity.Villager; import org.spongepowered.asm.mixin.Mixin; @@ -16,6 +17,6 @@ public class CraftVillagerMixin { */ @Overwrite public static Villager.Profession nmsToBukkitProfession(VillagerProfession nms) { - return Villager.Profession.valueOf(ResourceLocationUtil.standardize(nms.getRegistryName())); + return Villager.Profession.valueOf(ResourceLocationUtil.standardize(ForgeRegistries.VILLAGER_PROFESSIONS.getKey(nms))); } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/MaterialMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/MaterialMixin.java index 99c7fcfe..ec407a30 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/MaterialMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/MaterialMixin.java @@ -461,7 +461,7 @@ public abstract class MaterialMixin implements MaterialBridge { private static int tryGetMaxStackSize(Item item) { try { - return item.getItemStackLimit(new ItemStack(item)); + return item.getMaxStackSize(new ItemStack(item)); } catch (Throwable t) { try { return item.getMaxStackSize(); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/commands/CommandSourceStackMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/commands/CommandSourceStackMixin.java index 8ca4f400..d1694d32 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/commands/CommandSourceStackMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/commands/CommandSourceStackMixin.java @@ -1,12 +1,17 @@ package io.izzel.arclight.common.mixin.core.commands; +import com.mojang.authlib.GameProfile; import com.mojang.brigadier.tree.CommandNode; import io.izzel.arclight.common.bridge.core.command.CommandSourceBridge; import io.izzel.arclight.common.bridge.core.command.ICommandSourceBridge; +import io.izzel.arclight.common.bridge.core.entity.player.ServerPlayerEntityBridge; import io.izzel.arclight.common.mod.compat.CommandNodeHooks; import net.minecraft.commands.CommandSource; import net.minecraft.commands.CommandSourceStack; import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.players.PlayerList; +import net.minecraftforge.common.util.FakePlayer; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import org.bukkit.craftbukkit.v.CraftServer; @@ -16,6 +21,7 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(CommandSourceStack.class) @@ -38,6 +44,11 @@ public abstract class CommandSourceStackMixin implements CommandSourceBridge { } } + @Redirect(method = "broadcastToAdmins", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/players/PlayerList;isOp(Lcom/mojang/authlib/GameProfile;)Z")) + private boolean arclight$feedbackPermission(PlayerList instance, GameProfile profile) { + return ((ServerPlayerEntityBridge) instance.getPlayer(profile.getId())).bridge$getBukkitEntity().hasPermission("minecraft.admin.command_feedback"); + } + public boolean hasPermission(int i, String bukkitPermission) { // World is null when loading functions return ((getLevel() == null || !((CraftServer) Bukkit.getServer()).ignoreVanillaPermissions) && this.permissionLevel >= i) || getBukkitSender().hasPermission(bukkitPermission); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/commands/CommandsMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/commands/CommandsMixin.java index 5d6de087..5b7c9fe3 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/commands/CommandsMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/commands/CommandsMixin.java @@ -2,6 +2,7 @@ package io.izzel.arclight.common.mixin.core.commands; import com.google.common.collect.Maps; import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.ParseResults; import com.mojang.brigadier.tree.CommandNode; import com.mojang.brigadier.tree.RootCommandNode; import io.izzel.arclight.common.bridge.core.entity.player.ServerPlayerEntityBridge; @@ -33,7 +34,8 @@ import java.util.Map; public abstract class CommandsMixin { // @formatter:off - @Shadow public abstract int performCommand(CommandSourceStack source, String command); + @Shadow public abstract int performCommand(ParseResults p_242844_, String p_242841_); + @Shadow public abstract int performPrefixedCommand(CommandSourceStack p_230958_, String p_230959_); @Mutable @Shadow @Final private CommandDispatcher dispatcher; @Shadow protected abstract void fillUsableCommands(CommandNode rootCommandSource, CommandNode rootSuggestion, CommandSourceStack source, Map, CommandNode> commandNodeToSuggestionNode); // @formatter:on @@ -43,8 +45,12 @@ public abstract class CommandsMixin { this.dispatcher.setConsumer((context, b, i) -> context.getSource().onCommandComplete(context, b, i)); } - public int performCommand(CommandSourceStack source, String command, String label, boolean strip) { - return this.performCommand(source, command); + public int performPrefixedCommand(CommandSourceStack commandSourceStack, String s, String label) { + return this.performPrefixedCommand(commandSourceStack, s); + } + + public int performCommand(ParseResults parseResults, String s, String label) { + return this.performCommand(parseResults, s); } /** diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/commands/arguments/blocks/BlockStateParserMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/commands/arguments/blocks/BlockStateParserMixin.java index e15ab803..2dd27db7 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/commands/arguments/blocks/BlockStateParserMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/commands/arguments/blocks/BlockStateParserMixin.java @@ -2,6 +2,8 @@ package io.izzel.arclight.common.mixin.core.commands.arguments.blocks; import com.mojang.brigadier.StringReader; import net.minecraft.commands.arguments.blocks.BlockStateParser; +import net.minecraft.core.HolderLookup; +import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.properties.Property; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -22,7 +24,7 @@ public class BlockStateParserMixin { // @formatter:on @Inject(method = "", at = @At("RETURN")) - private void arclight$init(StringReader readerIn, boolean allowTags, CallbackInfo ci) { + private void arclight$init(HolderLookup registry, StringReader readerIn, boolean forTesting, boolean allowTags, CallbackInfo ci) { this.properties = new LinkedHashMap<>(properties); } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/commands/synchronization/ArgumentTypesMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/commands/synchronization/ArgumentTypesMixin.java index 3f580872..47dca695 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/commands/synchronization/ArgumentTypesMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/commands/synchronization/ArgumentTypesMixin.java @@ -1,81 +1,10 @@ package io.izzel.arclight.common.mixin.core.commands.synchronization; -import com.mojang.brigadier.arguments.ArgumentType; -import io.netty.buffer.Unpooled; -import net.minecraft.commands.synchronization.ArgumentTypes; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.resources.ResourceLocation; -import org.slf4j.Logger; -import org.spigotmc.SpigotConfig; -import org.spongepowered.asm.mixin.Final; +import net.minecraft.commands.synchronization.ArgumentTypeInfos; 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.CallbackInfo; -import javax.annotation.Nullable; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -@Mixin(ArgumentTypes.class) +@Mixin(ArgumentTypeInfos.class) public abstract class ArgumentTypesMixin { - // @formatter:off - @Shadow @Final private static Logger LOGGER; - @Shadow @Nullable private static ArgumentTypes.Entry get(ArgumentType type) { return null; } - @Shadow @Final private static Map> BY_NAME; - // @formatter:on - - private static final Set INTERNAL_TYPES = new HashSet<>(); - - @Inject(method = "bootStrap", at = @At("HEAD")) - private static void arclight$beginRegister(CallbackInfo ci) { - INTERNAL_TYPES.addAll(BY_NAME.keySet()); - } - - @Inject(method = "bootStrap", at = @At("RETURN")) - private static void arclight$endRegister(CallbackInfo ci) { - HashSet set = new HashSet<>(BY_NAME.keySet()); - set.removeAll(INTERNAL_TYPES); - INTERNAL_TYPES.clear(); - INTERNAL_TYPES.addAll(set); - INTERNAL_TYPES.add(new ResourceLocation("forge", "enum")); - INTERNAL_TYPES.add(new ResourceLocation("forge", "modid")); - } - - private static boolean arclight$reentrant = false; - - /** - * @author IzzelAliz - * @reason - */ - @Overwrite - public static > void serialize(FriendlyByteBuf buffer, T type) { - ArgumentTypes.Entry entry = (ArgumentTypes.Entry) get(type); - if (entry == null) { - LOGGER.error("Could not serialize {} ({}) - will not be sent to client!", type, type.getClass()); - buffer.writeResourceLocation(new ResourceLocation("")); - } else { - boolean wrap; - if (!arclight$reentrant && SpigotConfig.bungee && !INTERNAL_TYPES.contains(entry.name)) { - arclight$reentrant = wrap = true; - } else { - wrap = false; - } - if (wrap) { - buffer.writeUtf("arclight:wrapped"); - } - buffer.writeResourceLocation(entry.name); - FriendlyByteBuf buf = wrap ? new FriendlyByteBuf(Unpooled.buffer()) : buffer; - entry.serializer.serializeToNetwork(type, buf); - if (wrap) { - buffer.writeVarInt(buf.writerIndex()); - buffer.writeBytes(buf); - arclight$reentrant = false; - } - } - } + // TODO FIXME 1.19 command arguments } 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 409c5400..606db720 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 @@ -5,6 +5,7 @@ import io.izzel.arclight.common.mod.util.DistValidate; import io.izzel.arclight.mixin.Eject; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; import net.minecraft.world.level.GameRules; import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelAccessor; @@ -21,8 +22,6 @@ import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.util.Random; - @Mixin(LavaFluid.class) public abstract class LavaFluidMixin { @@ -36,7 +35,7 @@ public abstract class LavaFluidMixin { * @reason */ @Overwrite - public void randomTick(Level world, BlockPos pos, FluidState state, Random random) { + public void randomTick(Level world, BlockPos pos, FluidState state, RandomSource random) { if (world.getGameRules().getBoolean(GameRules.RULE_DOFIRETICK)) { int i = random.nextInt(3); if (i > 0) { diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/network/ServerHandshakeNetHandlerMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/network/ServerHandshakeNetHandlerMixin.java index cf8e1833..46c80b71 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/network/ServerHandshakeNetHandlerMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/network/ServerHandshakeNetHandlerMixin.java @@ -9,7 +9,6 @@ import net.minecraft.SharedConstants; import net.minecraft.network.Connection; import net.minecraft.network.ConnectionProtocol; import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.TranslatableComponent; import net.minecraft.network.protocol.handshake.ClientIntentionPacket; import net.minecraft.network.protocol.login.ClientboundLoginDisconnectPacket; import net.minecraft.server.MinecraftServer; @@ -61,7 +60,7 @@ public class ServerHandshakeNetHandlerMixin { synchronized (throttleTracker) { if (throttleTracker.containsKey(address) && !"127.0.0.1".equals(address.getHostAddress()) && currentTime - throttleTracker.get(address) < connectionThrottle) { throttleTracker.put(address, currentTime); - TranslatableComponent component = new TranslatableComponent("Connection throttled! Please wait before reconnecting."); + var component = Component.translatable("Connection throttled! Please wait before reconnecting."); this.connection.send(new ClientboundLoginDisconnectPacket(component)); this.connection.disconnect(component); return; @@ -79,13 +78,13 @@ public class ServerHandshakeNetHandlerMixin { if (packetIn.getProtocolVersion() > SharedConstants.getCurrentVersion().getProtocolVersion()) { - TranslatableComponent component = new TranslatableComponent(MessageFormat.format(SpigotConfig.outdatedServerMessage.replaceAll("'", "''"), SharedConstants.getCurrentVersion().getName())); + var component = Component.translatable(MessageFormat.format(SpigotConfig.outdatedServerMessage.replaceAll("'", "''"), SharedConstants.getCurrentVersion().getName())); this.connection.send(new ClientboundLoginDisconnectPacket(component)); this.connection.disconnect(component); break; } if (packetIn.getProtocolVersion() < SharedConstants.getCurrentVersion().getProtocolVersion()) { - TranslatableComponent component = new TranslatableComponent(MessageFormat.format(SpigotConfig.outdatedClientMessage.replaceAll("'", "''"), SharedConstants.getCurrentVersion().getName())); + var component = Component.translatable(MessageFormat.format(SpigotConfig.outdatedClientMessage.replaceAll("'", "''"), SharedConstants.getCurrentVersion().getName())); this.connection.send(new ClientboundLoginDisconnectPacket(component)); this.connection.disconnect(component); break; @@ -100,7 +99,7 @@ public class ServerHandshakeNetHandlerMixin { this.connection.address = new InetSocketAddress(split[1], ((InetSocketAddress) this.connection.getRemoteAddress()).getPort()); ((NetworkManagerBridge) this.connection).bridge$setSpoofedUUID(UUIDTypeAdapter.fromString(split[2])); } else { - TranslatableComponent component = new TranslatableComponent("If you wish to use IP forwarding, please enable it in your BungeeCord config as well!"); + var component = Component.literal("If you wish to use IP forwarding, please enable it in your BungeeCord config as well!"); this.connection.send(new ClientboundLoginDisconnectPacket(component)); this.connection.disconnect(component); return; diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/network/ServerLoginNetHandlerMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/network/ServerLoginNetHandlerMixin.java index 07208f8b..68a2c860 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/network/ServerLoginNetHandlerMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/network/ServerLoginNetHandlerMixin.java @@ -7,15 +7,15 @@ import io.izzel.arclight.common.bridge.core.network.login.ServerLoginNetHandlerB import io.izzel.arclight.common.bridge.core.server.MinecraftServerBridge; import io.izzel.arclight.common.bridge.core.server.management.PlayerListBridge; import net.minecraft.DefaultUncaughtExceptionHandler; +import net.minecraft.core.UUIDUtil; import net.minecraft.network.Connection; +import net.minecraft.network.PacketSendListener; import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.TextComponent; -import net.minecraft.network.chat.TranslatableComponent; +import net.minecraft.network.chat.ThrowingComponent; import net.minecraft.network.protocol.game.ClientboundDisconnectPacket; import net.minecraft.network.protocol.login.ClientboundGameProfilePacket; import net.minecraft.network.protocol.login.ClientboundHelloPacket; import net.minecraft.network.protocol.login.ClientboundLoginCompressionPacket; -import net.minecraft.network.protocol.login.ClientboundLoginDisconnectPacket; import net.minecraft.network.protocol.login.ServerboundHelloPacket; import net.minecraft.network.protocol.login.ServerboundKeyPacket; import net.minecraft.server.MinecraftServer; @@ -23,7 +23,8 @@ import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.network.ServerLoginPacketListenerImpl; import net.minecraft.util.Crypt; import net.minecraft.util.CryptException; -import net.minecraft.world.entity.player.Player; +import net.minecraft.util.SignatureValidator; +import net.minecraft.world.entity.player.ProfilePublicKey; import net.minecraftforge.fml.util.thread.SidedThreadGroups; import org.apache.commons.lang3.Validate; import org.bukkit.Bukkit; @@ -45,10 +46,11 @@ import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.security.PrivateKey; -import java.util.Arrays; import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger; +import static net.minecraft.server.network.ServerLoginPacketListenerImpl.isValidUsername; + @Mixin(ServerLoginPacketListenerImpl.class) public abstract class ServerLoginNetHandlerMixin implements ServerLoginNetHandlerBridge { @@ -64,6 +66,8 @@ public abstract class ServerLoginNetHandlerMixin implements ServerLoginNetHandle @Shadow public abstract void disconnect(Component reason); @Shadow public abstract String getUserName(); @Shadow private ServerPlayer delayedAcceptPlayer; + @Shadow @Nullable private ProfilePublicKey.Data profilePublicKeyData; + @Shadow @Nullable private static ProfilePublicKey validatePublicKey(@org.jetbrains.annotations.Nullable ProfilePublicKey.Data p_240244_, UUID p_240245_, SignatureValidator p_240246_, boolean p_240247_) throws ThrowingComponent { return null; } // @formatter:on public String hostname; @@ -79,14 +83,7 @@ public abstract class ServerLoginNetHandlerMixin implements ServerLoginNetHandle } public void disconnect(final String s) { - try { - final Component ichatbasecomponent = new TextComponent(s); - LOGGER.info("Disconnecting {}: {}", this.getUserName(), s); - this.connection.send(new ClientboundLoginDisconnectPacket(ichatbasecomponent)); - this.connection.disconnect(ichatbasecomponent); - } catch (Exception exception) { - LOGGER.error("Error whilst disconnecting player", exception); - } + this.disconnect(Component.literal(s)); } /** @@ -100,16 +97,34 @@ public abstract class ServerLoginNetHandlerMixin implements ServerLoginNetHandle this.loginGameProfile = this.getOfflineProfile(this.loginGameProfile); } */ + ProfilePublicKey profilePublicKey = null; - ServerPlayer entity = ((PlayerListBridge) this.server.getPlayerList()).bridge$canPlayerLogin(this.connection.getRemoteAddress(), this.gameProfile, (ServerLoginPacketListenerImpl) (Object) this); + if (!this.server.usesAuthentication()) { + // this.gameProfile = this.createFakeProfile(this.gameProfile); // Spigot - Moved to initUUID + // Spigot end + } else { + try { + SignatureValidator signaturevalidator = this.server.getServiceSignatureValidator(); + + profilePublicKey = validatePublicKey(this.profilePublicKeyData, this.gameProfile.getId(), signaturevalidator, this.server.enforceSecureProfile()); + } catch (ThrowingComponent e) { + LOGGER.error(e.getMessage(), e.getCause()); + if (!this.connection.isMemoryConnection()) { + this.disconnect(e.getComponent()); + return; + } + } + } + + ServerPlayer entity = ((PlayerListBridge) this.server.getPlayerList()).bridge$canPlayerLogin(this.connection.getRemoteAddress(), this.gameProfile, (ServerLoginPacketListenerImpl) (Object) this, profilePublicKey); if (entity == null) { // this.disconnect(itextcomponent); } else { this.state = ServerLoginPacketListenerImpl.State.ACCEPTED; if (this.server.getCompressionThreshold() >= 0 && !this.connection.isMemoryConnection()) { - this.connection.send(new ClientboundLoginCompressionPacket(this.server.getCompressionThreshold()), (p_210149_1_) -> { + this.connection.send(new ClientboundLoginCompressionPacket(this.server.getCompressionThreshold()), PacketSendListener.thenRun(() -> { this.connection.setupCompression(this.server.getCompressionThreshold(), true); - }); + })); } this.connection.send(new ClientboundGameProfilePacket(this.gameProfile)); @@ -123,7 +138,7 @@ public abstract class ServerLoginNetHandlerMixin implements ServerLoginNetHandle } } catch (Exception exception) { LOGGER.error("Couldn't place player in world", exception); - TranslatableComponent chatmessage = new TranslatableComponent("multiplayer.disconnect.invalid_player_data"); + var chatmessage = Component.translatable("multiplayer.disconnect.invalid_player_data"); this.connection.send(new ClientboundDisconnectPacket(chatmessage)); this.connection.disconnect(chatmessage); @@ -138,31 +153,39 @@ public abstract class ServerLoginNetHandlerMixin implements ServerLoginNetHandle @Overwrite public void handleHello(ServerboundHelloPacket packetIn) { Validate.validState(this.state == ServerLoginPacketListenerImpl.State.HELLO, "Unexpected hello packet"); - this.gameProfile = packetIn.getGameProfile(); - if (this.server.usesAuthentication() && !this.connection.isMemoryConnection()) { - this.state = ServerLoginPacketListenerImpl.State.KEY; - this.connection.send(new ClientboundHelloPacket("", this.server.getKeyPair().getPublic().getEncoded(), this.nonce)); + Validate.validState(this.state == ServerLoginPacketListenerImpl.State.HELLO, "Unexpected hello packet"); + Validate.validState(isValidUsername(packetIn.name()), "Invalid characters in username"); + this.profilePublicKeyData = packetIn.publicKey().orElse(null); + GameProfile gameprofile = this.server.getSingleplayerProfile(); + if (gameprofile != null && packetIn.name().equalsIgnoreCase(gameprofile.getName())) { + this.gameProfile = gameprofile; + this.state = ServerLoginPacketListenerImpl.State.NEGOTIATING; // FORGE: continue NEGOTIATING, we move to READY_TO_ACCEPT after Forge is ready } else { - class Handler extends Thread { + this.gameProfile = new GameProfile(null, packetIn.name()); + if (this.server.usesAuthentication() && !this.connection.isMemoryConnection()) { + this.state = ServerLoginPacketListenerImpl.State.KEY; + this.connection.send(new ClientboundHelloPacket("", this.server.getKeyPair().getPublic().getEncoded(), this.nonce)); + } else { + class Handler extends Thread { - Handler() { - super(SidedThreadGroups.SERVER, "User Authenticator #" + UNIQUE_THREAD_ID.incrementAndGet()); - } + Handler() { + super(SidedThreadGroups.SERVER, "User Authenticator #" + UNIQUE_THREAD_ID.incrementAndGet()); + } - @Override - public void run() { - try { - initUUID(); - arclight$preLogin(); - } catch (Exception ex) { - disconnect("Failed to verify username!"); - LOGGER.warn("Exception verifying {} ", gameProfile.getName(), ex); + @Override + public void run() { + try { + initUUID(); + arclight$preLogin(); + } catch (Exception ex) { + disconnect("Failed to verify username!"); + LOGGER.warn("Exception verifying {} ", gameProfile.getName(), ex); + } } } + new Handler().start(); } - new Handler().start(); } - } public void initUUID() { @@ -170,7 +193,7 @@ public abstract class ServerLoginNetHandlerMixin implements ServerLoginNetHandle if (((NetworkManagerBridge) this.connection).bridge$getSpoofedUUID() != null) { uuid = ((NetworkManagerBridge) this.connection).bridge$getSpoofedUUID(); } else { - uuid = Player.createPlayerUUID(this.gameProfile.getName()); + uuid = UUIDUtil.createOfflinePlayerUUID(this.gameProfile.getName()); } this.gameProfile = new GameProfile(uuid, this.gameProfile.getName()); if (((NetworkManagerBridge) this.connection).bridge$getSpoofedProfile() != null) { @@ -189,11 +212,16 @@ public abstract class ServerLoginNetHandlerMixin implements ServerLoginNetHandle @Overwrite public void handleKey(ServerboundKeyPacket packetIn) { Validate.validState(this.state == ServerLoginPacketListenerImpl.State.KEY, "Unexpected key packet"); - PrivateKey privatekey = this.server.getKeyPair().getPrivate(); final String s; try { - if (!Arrays.equals(this.nonce, packetIn.getNonce(privatekey))) { + PrivateKey privatekey = this.server.getKeyPair().getPrivate(); + if (this.profilePublicKeyData != null) { + ProfilePublicKey profilepublickey = ProfilePublicKey.createTrusted(this.profilePublicKeyData); + if (!packetIn.isChallengeSignatureValid(this.nonce, profilepublickey)) { + throw new IllegalStateException("Protocol error"); + } + } else if (!packetIn.isNonceValid(this.nonce, privatekey)) { throw new IllegalStateException("Protocol error"); } @@ -228,7 +256,7 @@ public abstract class ServerLoginNetHandlerMixin implements ServerLoginNetHandle gameProfile = createFakeProfile(gameprofile); state = ServerLoginPacketListenerImpl.State.NEGOTIATING; } else { - disconnect(new TranslatableComponent("multiplayer.disconnect.unverified_username")); + disconnect(Component.translatable("multiplayer.disconnect.unverified_username")); LOGGER.error("Username '{}' tried to join with an invalid session", gameprofile.getName()); } } catch (Exception var3) { @@ -237,7 +265,7 @@ public abstract class ServerLoginNetHandlerMixin implements ServerLoginNetHandle gameProfile = createFakeProfile(gameprofile); state = ServerLoginPacketListenerImpl.State.NEGOTIATING; } else { - disconnect(new TranslatableComponent("multiplayer.disconnect.authservers_down")); + disconnect(Component.translatable("multiplayer.disconnect.authservers_down")); LOGGER.error("Couldn't verify username because servers are unavailable"); } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/network/ServerPlayNetHandlerMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/network/ServerPlayNetHandlerMixin.java index f9f3618e..36d42357 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/network/ServerPlayNetHandlerMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/network/ServerPlayNetHandlerMixin.java @@ -1,6 +1,7 @@ package io.izzel.arclight.common.mixin.core.network; import com.google.common.base.Charsets; +import com.mojang.brigadier.ParseResults; import io.izzel.arclight.common.bridge.core.entity.EntityBridge; import io.izzel.arclight.common.bridge.core.entity.player.ServerPlayerEntityBridge; import io.izzel.arclight.common.bridge.core.inventory.container.ContainerBridge; @@ -10,23 +11,28 @@ import io.izzel.arclight.common.bridge.core.server.MinecraftServerBridge; import io.izzel.arclight.common.bridge.core.server.management.PlayerInteractionManagerBridge; import io.izzel.arclight.common.bridge.core.server.management.PlayerListBridge; import io.izzel.arclight.common.mod.ArclightConstants; +import io.izzel.arclight.common.mod.server.ArclightServer; import io.izzel.arclight.common.mod.util.ArclightCaptures; -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.GenericFutureListener; import it.unimi.dsi.fastutil.ints.Int2ObjectMaps; import net.minecraft.ChatFormatting; -import net.minecraft.SharedConstants; -import net.minecraft.Util; import net.minecraft.advancements.CriteriaTriggers; import net.minecraft.commands.CommandRuntimeException; +import net.minecraft.commands.CommandSigningContext; +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.commands.Commands; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.StringTag; import net.minecraft.network.Connection; +import net.minecraft.network.PacketSendListener; +import net.minecraft.network.chat.ChatDecorator; import net.minecraft.network.chat.ChatType; import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.TextComponent; -import net.minecraft.network.chat.TranslatableComponent; +import net.minecraft.network.chat.FilterMask; +import net.minecraft.network.chat.LastSeenMessages; +import net.minecraft.network.chat.OutgoingPlayerChatMessage; +import net.minecraft.network.chat.PlayerChatMessage; +import net.minecraft.network.chat.PreviewableCommand; import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.PacketUtils; import net.minecraft.network.protocol.game.*; @@ -34,9 +40,10 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.network.FilteredText; import net.minecraft.server.network.ServerGamePacketListenerImpl; -import net.minecraft.server.network.TextFilter; import net.minecraft.server.players.PlayerList; +import net.minecraft.util.FutureChain; import net.minecraft.util.Mth; import net.minecraft.util.StringUtil; import net.minecraft.world.InteractionHand; @@ -71,8 +78,6 @@ import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.Vec3; import net.minecraftforge.common.ForgeHooks; -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Location; @@ -97,7 +102,9 @@ import org.bukkit.event.inventory.InventoryCreativeEvent; import org.bukkit.event.inventory.InventoryType; import org.bukkit.event.inventory.SmithItemEvent; import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.bukkit.event.player.AsyncPlayerChatPreviewEvent; import org.bukkit.event.player.PlayerAnimationEvent; +import org.bukkit.event.player.PlayerAnimationType; import org.bukkit.event.player.PlayerChatEvent; import org.bukkit.event.player.PlayerCommandPreprocessEvent; import org.bukkit.event.player.PlayerInteractAtEntityEvent; @@ -116,9 +123,11 @@ import org.bukkit.inventory.CraftingInventory; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.InventoryView; import org.bukkit.inventory.SmithingInventory; +import org.slf4j.Logger; import org.spigotmc.SpigotConfig; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -126,12 +135,15 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.Slice; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; +import java.time.Instant; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.Set; -import java.util.UUID; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.function.UnaryOperator; import java.util.logging.Level; @@ -174,12 +186,24 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB @Shadow private int dropSpamTickCount; @Shadow protected abstract boolean noBlocksAround(Entity p_241162_1_); @Shadow protected abstract boolean isPlayerCollidingWithAnythingNew(LevelReader p_241163_1_, AABB p_241163_2_); - @Shadow protected abstract void updateBookPages(List p_143635_, UnaryOperator p_143636_, ItemStack p_143637_); @Shadow private static double clampHorizontal(double p_143610_) { return 0; } @Shadow private static double clampVertical(double p_143654_) { return 0; } @Shadow private static boolean containsInvalidValues(double p_143664_, double p_143665_, double p_143666_, float p_143667_, float p_143668_) { return false; } + @Shadow @Final @Mutable private FutureChain chatMessageChain; + @Shadow protected abstract void updateBookPages(List p_143635_, UnaryOperator p_143636_, ItemStack p_143637_); + @Shadow public abstract void ackBlockChangesUpTo(int p_215202_); + @Shadow private static boolean isChatMessageIllegal(String p_215215_) { return false; } + @Shadow protected abstract boolean tryHandleChat(String p_242372_, Instant p_242311_, LastSeenMessages.Update p_242217_); + @Shadow protected abstract PlayerChatMessage getSignedMessage(ServerboundChatPacket p_242875_); + @Shadow protected abstract boolean verifyChatMessage(PlayerChatMessage p_242942_); + @Shadow protected abstract CompletableFuture filterTextPacket(String p_243213_); + @Shadow protected abstract ParseResults parseCommand(String p_242938_); + @Shadow protected abstract Map collectSignedArguments(ServerboundChatCommandPacket p_242876_, PreviewableCommand p_242848_); // @formatter:on + @Shadow + protected abstract void detectRateSpam(); + private static final int SURVIVAL_PLACE_DISTANCE_SQUARED = 6 * 6; private static final int CREATIVE_PLACE_DISTANCE_SQUARED = 7 * 7; private CraftServer cserver; @@ -218,6 +242,7 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB lastPitch = Float.MAX_VALUE; lastYaw = Float.MAX_VALUE; justTeleported = false; + this.chatMessageChain = new FutureChain(ArclightServer.getChatExecutor()); } /** @@ -233,6 +258,26 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB if (this.processedDisconnect) { return; } + if (!this.cserver.isPrimaryThread()) { + Waitable waitable = new Waitable<>() { + @Override + protected Object evaluate() { + disconnect(s); + return null; + } + }; + + ((MinecraftServerBridge) this.server).bridge$queuedProcess(waitable); + + try { + waitable.get(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } catch (ExecutionException e) { + throw new RuntimeException(e); + } + return; + } String leaveMessage = ChatFormatting.YELLOW + this.player.getScoreboardName() + " left the game."; PlayerKickEvent event = new PlayerKickEvent(getCraftPlayer(), s, leaveMessage); if (this.cserver.getServer().isRunning()) { @@ -241,10 +286,9 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB if (event.isCancelled()) { return; } - s = event.getReason(); ArclightCaptures.captureQuitMessage(event.getLeaveMessage()); - Component textComponent = CraftChatMessage.fromString(s, true)[0]; - this.connection.send(new ClientboundDisconnectPacket(textComponent), future -> this.connection.disconnect(textComponent)); + Component textComponent = CraftChatMessage.fromString(event.getReason(), true)[0]; + this.connection.send(new ClientboundDisconnectPacket(textComponent), PacketSendListener.thenRun(() -> this.connection.disconnect(textComponent))); this.onDisconnect(textComponent); this.connection.setReadOnly(); this.server.executeBlocking(this.connection::handleDisconnection); @@ -263,7 +307,7 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB public void handleMoveVehicle(final ServerboundMoveVehiclePacket packetplayinvehiclemove) { PacketUtils.ensureRunningOnSameThread(packetplayinvehiclemove, (ServerGamePacketListenerImpl) (Object) this, this.player.getLevel()); if (containsInvalidValues(packetplayinvehiclemove.getX(), packetplayinvehiclemove.getY(), packetplayinvehiclemove.getZ(), packetplayinvehiclemove.getYRot(), packetplayinvehiclemove.getXRot())) { - this.disconnect(new TranslatableComponent("multiplayer.disconnect.invalid_vehicle_movement")); + this.disconnect(Component.translatable("multiplayer.disconnect.invalid_vehicle_movement")); } else { Entity entity = this.player.getRootVehicle(); if (entity != this.player && entity.getControllingPassenger() == this.player && entity == this.lastVehicle) { @@ -418,7 +462,6 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB this.lastBookTick = ArclightConstants.currentTick - 20; } if (this.lastBookTick + 20 > ArclightConstants.currentTick) { - PacketUtils.ensureRunningOnSameThread(packetIn, (ServerGamePacketListenerImpl) (Object) this, this.server); this.disconnect("Book edited too quickly!"); return; } @@ -430,7 +473,7 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB * @reason */ @Overwrite - private void updateBookContents(List list, int slot) { + private void updateBookContents(List list, int slot) { ItemStack old = this.player.getInventory().getItem(slot); if (old.is(Items.WRITABLE_BOOK)) { ItemStack itemstack = old.copy(); @@ -444,7 +487,7 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB * @reason */ @Overwrite - private void signBook(TextFilter.FilteredText text, List list, int slot) { + private void signBook(FilteredText text, List list, int slot) { ItemStack old = this.player.getInventory().getItem(slot); if (old.is(Items.WRITABLE_BOOK)) { ItemStack itemStack = new ItemStack(Items.WRITTEN_BOOK); @@ -455,13 +498,13 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB itemStack.addTagElement("author", StringTag.valueOf(this.player.getName().getString())); if (this.player.isTextFilteringEnabled()) { - itemStack.addTagElement("title", StringTag.valueOf(text.getFiltered())); + itemStack.addTagElement("title", StringTag.valueOf(text.filteredOrEmpty())); } else { - itemStack.addTagElement("filtered_title", StringTag.valueOf(text.getFiltered())); - itemStack.addTagElement("title", StringTag.valueOf(text.getRaw())); + itemStack.addTagElement("filtered_title", StringTag.valueOf(text.filteredOrEmpty())); + itemStack.addTagElement("title", StringTag.valueOf(text.raw())); } - this.updateBookPages(list, (p_143659_) -> Component.Serializer.toJson(new TextComponent(p_143659_)), itemStack); + this.updateBookPages(list, (p_143659_) -> Component.Serializer.toJson(Component.literal(p_143659_)), itemStack); this.player.getInventory().setItem(slot, CraftEventFactory.handleEditBookEvent(this.player, slot, old, itemStack)); } } @@ -474,7 +517,7 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB public void handleMovePlayer(ServerboundMovePlayerPacket packetplayinflying) { PacketUtils.ensureRunningOnSameThread(packetplayinflying, (ServerGamePacketListenerImpl) (Object) this, this.player.getLevel()); if (containsInvalidValues(packetplayinflying.getX(0.0D), packetplayinflying.getY(0.0D), packetplayinflying.getZ(0.0D), packetplayinflying.getYRot(0.0F), packetplayinflying.getXRot(0.0F))) { - this.disconnect(new TranslatableComponent("multiplayer.disconnect.invalid_player_movement")); + this.disconnect(Component.translatable("multiplayer.disconnect.invalid_player_movement")); } else { ServerLevel worldserver = this.player.getLevel(); if (!this.player.wonGame && !((ServerPlayerEntityBridge) this.player).bridge$isMovementBlocked()) { @@ -724,7 +767,8 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB case START_DESTROY_BLOCK: case ABORT_DESTROY_BLOCK: case STOP_DESTROY_BLOCK: { - this.player.gameMode.handleBlockBreakAction(blockposition, packetplayinblockdig_enumplayerdigtype, packetplayinblockdig.getDirection(), this.player.level.getMaxBuildHeight()); + this.player.gameMode.handleBlockBreakAction(blockposition, packetplayinblockdig_enumplayerdigtype, packetplayinblockdig.getDirection(), this.player.level.getMaxBuildHeight(), packetplayinblockdig.getSequence()); + this.player.connection.ackBlockChangesUpTo(packetplayinblockdig.getSequence()); return; } default: { @@ -778,6 +822,7 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB if (!this.checkLimit(((TimestampedPacket) packet).bridge$timestamp())) { return; } + this.ackBlockChangesUpTo(packet.getSequence()); ServerLevel worldserver = this.player.getLevel(); InteractionHand enumhand = packet.getHand(); ItemStack itemstack = this.player.getItemInHand(enumhand); @@ -840,8 +885,8 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB } } - @Redirect(method = "onDisconnect", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/players/PlayerList;broadcastMessage(Lnet/minecraft/network/chat/Component;Lnet/minecraft/network/chat/ChatType;Ljava/util/UUID;)V")) - public void arclight$captureQuit(PlayerList playerList, Component p_232641_1_, ChatType p_232641_2_, UUID p_232641_3_) { + @Redirect(method = "onDisconnect", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/players/PlayerList;broadcastSystemMessage(Lnet/minecraft/network/chat/Component;Z)V")) + public void arclight$captureQuit(PlayerList instance, Component p_240618_, boolean p_240644_) { // do nothing } @@ -853,8 +898,8 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB } } - @Inject(method = "send(Lnet/minecraft/network/protocol/Packet;Lio/netty/util/concurrent/GenericFutureListener;)V", cancellable = true, at = @At("HEAD")) - private void arclight$updateCompassTarget(Packet packetIn, GenericFutureListener> futureListeners, CallbackInfo ci) { + @Inject(method = "send(Lnet/minecraft/network/protocol/Packet;Lnet/minecraft/network/PacketSendListener;)V", cancellable = true, at = @At("HEAD")) + private void arclight$updateCompassTarget(Packet packetIn, PacketSendListener futureListeners, CallbackInfo ci) { if (packetIn == null || processedDisconnect) { ci.cancel(); return; @@ -902,90 +947,99 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB if (this.server.isStopped()) { return; } - String s = StringUtils.normalizeSpace(packet.getMessage()); - for (int i = 0; i < s.length(); ++i) { - if (!SharedConstants.isAllowedChatCharacter(s.charAt(i))) { - this.disconnect(new TranslatableComponent("multiplayer.disconnect.illegal_characters")); + if (isChatMessageIllegal(packet.message())) { + this.disconnect(Component.translatable("multiplayer.disconnect.illegal_characters")); + } else { + if (this.tryHandleChat(packet.message(), packet.timeStamp(), packet.lastSeenMessages())) { + PlayerChatMessage playerchatmessage = this.getSignedMessage(packet); + + if (this.verifyChatMessage(playerchatmessage)) { + this.chatMessageChain.append(() -> { + CompletableFuture completablefuture = this.filterTextPacket(playerchatmessage.signedContent().plain()); + CompletableFuture completablefuture1 = ForgeHooks.getServerChatSubmittedDecorator().decorate(this.player, playerchatmessage); + + return CompletableFuture.allOf(completablefuture, completablefuture1).thenAcceptAsync((ovoid) -> { + FilterMask filtermask = completablefuture.join().mask(); + PlayerChatMessage playerchatmessage1 = completablefuture1.join().filter(filtermask); + + this.broadcastChatMessage(playerchatmessage1); + }, ArclightServer.getChatExecutor()); // CraftBukkit - async chat + }); + } + } + } + } + + @Redirect(method = "queryChatPreview", at = @At(value = "INVOKE", remap = false, target = "Lnet/minecraftforge/common/ForgeHooks;getServerChatPreviewDecorator()Lnet/minecraft/network/chat/ChatDecorator;")) + private ChatDecorator arclight$asyncChatPreview() { + return (player, component) -> ForgeHooks.getServerChatPreviewDecorator().decorate(player, component) + .thenApplyAsync(forgeComponent -> { + AsyncPlayerChatPreviewEvent event = new AsyncPlayerChatPreviewEvent(true, ((ServerPlayerEntityBridge) player).bridge$getBukkitEntity(), CraftChatMessage.fromComponent(forgeComponent), new LazyPlayerSet(server)); + String originalFormat = event.getFormat(), originalMessage = event.getMessage(); + this.cserver.getPluginManager().callEvent(event); + + if (originalFormat.equals(event.getFormat()) && originalMessage.equals(event.getMessage()) && event.getPlayer().getName().equalsIgnoreCase(event.getPlayer().getDisplayName())) { + return forgeComponent; + } + + return CraftChatMessage.fromStringOrNull(String.format(event.getFormat(), event.getPlayer().getDisplayName(), event.getMessage())); + }, ArclightServer.getChatExecutor()); + } + + /** + * @author IzzelAliz + * @reason + */ + @Overwrite + private void performChatCommand(ServerboundChatCommandPacket packet) { + String command = "/" + packet.command(); + LOGGER.info(this.player.getScoreboardName() + " issued server command: " + command); + + PlayerCommandPreprocessEvent event = new PlayerCommandPreprocessEvent(getCraftPlayer(), command, new LazyPlayerSet(server)); + this.cserver.getPluginManager().callEvent(event); + + if (event.isCancelled()) { + return; + } + command = event.getMessage().substring(1); + + ParseResults parseresults = this.parseCommand(command); + Map map = (packet.command().equals(command)) ? this.collectSignedArguments(packet, PreviewableCommand.of(parseresults)) : Collections.emptyMap(); + + for (PlayerChatMessage playerchatmessage : map.values()) { + if (!this.verifyChatMessage(playerchatmessage)) { return; } } - if (s.startsWith("/")) { - PacketUtils.ensureRunningOnSameThread(packet, (ServerGamePacketListenerImpl) (Object) this, this.player.getLevel()); - } - this.handleChat(TextFilter.FilteredText.passThrough(s)); + + CommandSigningContext commandsigningcontext = new CommandSigningContext.SignedArguments(map); + parseresults = Commands.mapSource(parseresults, (p_242749_) -> { + return p_242749_.withSigningContext(commandsigningcontext); + }); + this.server.getCommands().performCommand(parseresults, command); } - private void handleChat(TextFilter.FilteredText text) { - if (this.player.isRemoved() || this.player.getChatVisibility() == ChatVisiblity.HIDDEN) { - this.send(new ClientboundChatPacket((new TranslatableComponent("chat.cannotSend")).withStyle(ChatFormatting.RED), ChatType.SYSTEM, Util.NIL_UUID)); - } else { - this.player.resetLastActionTime(); - String s = text.getRaw(); - boolean isSync = s.startsWith("/"); - if (isSync) { - try { - this.cserver.playerCommandState = true; - this.handleCommand(s); - } finally { - this.cserver.playerCommandState = false; - } - } else if (s.isEmpty()) { - LOGGER.warn(this.player.getScoreboardName() + " tried to send an empty message"); - } else if (this.getCraftPlayer().isConversing()) { - String conversationInput = s; - ((MinecraftServerBridge) this.server).bridge$queuedProcess(() -> this.getCraftPlayer().acceptConversationInput(conversationInput)); - } else if (this.player.getChatVisibility() == ChatVisiblity.SYSTEM) { - this.send(new ClientboundChatPacket((new TranslatableComponent("chat.cannotSend")).withStyle(ChatFormatting.RED), ChatType.SYSTEM, Util.NIL_UUID)); - } else { - this.chat(s, true); - } - boolean counted = true; - for (String exclude : org.spigotmc.SpigotConfig.spamExclusions) { - if (exclude != null && s.startsWith(exclude)) { - counted = false; - break; - } - } - if (counted) { - this.chatSpamTickCount += 20; - if (this.chatSpamTickCount > 200 && !this.server.getPlayerList().isOp(this.player.getGameProfile())) { - if (!isSync) { - class Disconnect2 extends Waitable { - - @Override - protected Object evaluate() { - disconnect(new TranslatableComponent("disconnect.spam")); - return null; - } - } - Waitable waitable2 = new Disconnect2(); - ((MinecraftServerBridge) this.server).bridge$queuedProcess(waitable2); - try { - waitable2.get(); - return; - } catch (InterruptedException e4) { - Thread.currentThread().interrupt(); - return; - } catch (ExecutionException e2) { - throw new RuntimeException(e2); - } - } - this.disconnect(new TranslatableComponent("disconnect.spam")); - } - } + @Inject(method = "tryHandleChat", cancellable = true, at = @At("HEAD")) + private void arclight$deadMenTellNoTales(String p_242372_, Instant p_242311_, LastSeenMessages.Update p_242217_, CallbackInfoReturnable cir) { + if (this.player.isRemoved()) { + this.send(new ClientboundSystemChatPacket(Component.translatable("chat.disabled.options").withStyle(ChatFormatting.RED), false)); + cir.setReturnValue(false); } } - public void chat(String s, boolean async) { + // TODO ChatType.RAW + public void chat(String s, PlayerChatMessage original, boolean async) { if (s.isEmpty() || this.player.getChatVisibility() == ChatVisiblity.HIDDEN) { return; } ServerGamePacketListenerImpl handler = (ServerGamePacketListenerImpl) (Object) this; + OutgoingPlayerChatMessage outgoing = OutgoingPlayerChatMessage.create(original); if (!async && s.startsWith("/")) { this.handleCommand(s); } else if (this.player.getChatVisibility() != ChatVisiblity.SYSTEM) { Player thisPlayer = this.getCraftPlayer(); AsyncPlayerChatEvent event = new AsyncPlayerChatEvent(async, thisPlayer, s, new LazyPlayerSet(this.server)); + String originalFormat = event.getFormat(), originalMessage = event.getMessage(); this.cserver.getPluginManager().callEvent(event); if (PlayerChatEvent.getHandlerList().getRegisteredListeners().length != 0) { PlayerChatEvent queueEvent = new PlayerChatEvent(thisPlayer, event.getMessage(), event.getFormat(), event.getRecipients()); @@ -996,22 +1050,32 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB protected Object evaluate() { Bukkit.getPluginManager().callEvent(queueEvent); if (queueEvent.isCancelled()) { + if (outgoing != null) { + outgoing.sendHeadersToRemainingPlayers(server.getPlayerList()); + } return null; } String message = String.format(queueEvent.getFormat(), queueEvent.getPlayer().getDisplayName(), queueEvent.getMessage()); - var event = ForgeHooks.onServerChatEvent(handler, queueEvent.getMessage(), ForgeHooks.newChatWithLinks(message), queueEvent.getMessage(), ForgeHooks.newChatWithLinks(message)); - var component = event == null ? null : event.getComponent(); - if (component == null) return null; - Bukkit.getConsoleSender().sendMessage(CraftChatMessage.fromComponent(component)); if (((LazyPlayerSet) queueEvent.getRecipients()).isLazy()) { - for (ServerPlayer player : server.getPlayerList().players) { - ((ServerPlayerEntityBridge) player).bridge$sendMessage(component, thisPlayer.getUniqueId()); + if (!org.spigotmc.SpigotConfig.bungee && originalFormat.equals(queueEvent.getFormat()) && originalMessage.equals(queueEvent.getMessage()) && queueEvent.getPlayer().getName().equalsIgnoreCase(queueEvent.getPlayer().getDisplayName())) { // Spigot + server.getPlayerList().broadcastChatMessage(original, player, ChatType.bind(ChatType.CHAT, player)); + return null; + } else if (!org.spigotmc.SpigotConfig.bungee && CraftChatMessage.fromComponent(original.serverContent()).equals(message)) { // Spigot + // TODO server.getPlayerList().broadcastChatMessage(original, player, ChatType.bind(ChatType.RAW, player)); + return null; + } + for (ServerPlayer recipient : server.getPlayerList().players) { + ((ServerPlayerEntityBridge) recipient).bridge$getBukkitEntity().sendMessage(player.getUUID(), message); } } else { for (Player player2 : queueEvent.getRecipients()) { - ((ServerPlayerEntityBridge) ((CraftPlayer) player2).getHandle()).bridge$sendMessage(component, thisPlayer.getUniqueId()); + player2.sendMessage(thisPlayer.getUniqueId(), message); } } + Bukkit.getConsoleSender().sendMessage(message); + if (outgoing != null) { + outgoing.sendHeadersToRemainingPlayers(server.getPlayerList()); + } return null; } } @@ -1032,45 +1096,38 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB } } if (event.isCancelled()) { + if (outgoing != null) { + outgoing.sendHeadersToRemainingPlayers(server.getPlayerList()); + } return; } - s = String.format(event.getFormat(), event.getPlayer().getDisplayName(), event.getMessage()); - Component chatWithLinks = ForgeHooks.newChatWithLinks(s); - class ForgeChat extends Waitable { - @Override - protected Void evaluate() { - // this is called on main thread - var chatEvent = ForgeHooks.onServerChatEvent(handler, event.getMessage(), chatWithLinks, event.getMessage(), chatWithLinks); - var component = chatEvent != null ? chatEvent.getComponent() : null; - if (component == null) return null; - Bukkit.getConsoleSender().sendMessage(CraftChatMessage.fromComponent(component)); - if (((LazyPlayerSet) event.getRecipients()).isLazy()) { - for (ServerPlayer recipient : server.getPlayerList().players) { - ((ServerPlayerEntityBridge) recipient).bridge$sendMessage(component, thisPlayer.getUniqueId()); - } - } else { - for (Player recipient2 : event.getRecipients()) { - ((ServerPlayerEntityBridge) ((CraftPlayer) recipient2).getHandle()).bridge$sendMessage(component, thisPlayer.getUniqueId()); - } - } - return null; + s = String.format(event.getFormat(), event.getPlayer().getDisplayName(), event.getMessage()); + if (((LazyPlayerSet) event.getRecipients()).isLazy()) { + if (!org.spigotmc.SpigotConfig.bungee && originalFormat.equals(event.getFormat()) && originalMessage.equals(event.getMessage()) && event.getPlayer().getName().equalsIgnoreCase(event.getPlayer().getDisplayName())) { // Spigot + server.getPlayerList().broadcastChatMessage(original, player, ChatType.bind(ChatType.CHAT, player)); + return; + } else if (!org.spigotmc.SpigotConfig.bungee && CraftChatMessage.fromComponent(original.serverContent()).equals(s)) { // Spigot + // TODO server.getPlayerList().broadcastChatMessage(original, player, ChatType.bind(ChatType.RAW, player)); + return; + } + + for (ServerPlayer recipient : server.getPlayerList().players) { + ((ServerPlayerEntityBridge) recipient).bridge$getBukkitEntity().sendMessage(player.getUUID(), s); + } + } else { + for (Player recipient : event.getRecipients()) { + recipient.sendMessage(player.getUUID(), s); } } - Waitable waitable = new ForgeChat(); - if (async) { - ((MinecraftServerBridge) server).bridge$queuedProcess(waitable); - } else { - waitable.run(); + Bukkit.getConsoleSender().sendMessage(s); + + if (outgoing != null) { + outgoing.sendHeadersToRemainingPlayers(server.getPlayerList()); } } } - /** - * @author IzzelAliz - * @reason - */ - @Overwrite private void handleCommand(String s) { if (SpigotConfig.logCommands) { LOGGER.info(this.player.getScoreboardName() + " issued server command: " + s); @@ -1089,6 +1146,27 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB } } + /** + * @author IzzelAliz + * @reason + */ + @Overwrite + private void broadcastChatMessage(PlayerChatMessage playerchatmessage) { + String s = playerchatmessage.signedContent().plain(); + if (s.isEmpty()) { + LOGGER.warn(this.player.getScoreboardName() + " tried to send an empty message"); + } else if (getCraftPlayer().isConversing()) { + final String conversationInput = s; + ((MinecraftServerBridge) this.server).bridge$queuedProcess(() -> getCraftPlayer().acceptConversationInput(conversationInput)); + } else if (this.player.getChatVisibility() == ChatVisiblity.SYSTEM) { // Re-add "Command Only" flag check + this.send(new ClientboundSystemChatPacket(Component.translatable("chat.cannotSend").withStyle(ChatFormatting.RED), false)); + } else { + this.chat(s, playerchatmessage, true); + } + // this.server.getPlayerList().broadcastChatMessage(playerchatmessage, this.player, ChatMessageType.bind(ChatMessageType.CHAT, (Entity) this.player)); + this.detectRateSpam(); + } + /** * @author IzzelAliz * @reason @@ -1118,7 +1196,7 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB if (result == null || result.getType() != HitResult.Type.BLOCK) { CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_AIR, this.player.getInventory().getSelected(), InteractionHand.MAIN_HAND); } - PlayerAnimationEvent event = new PlayerAnimationEvent(this.getCraftPlayer()); + PlayerAnimationEvent event = new PlayerAnimationEvent(this.getCraftPlayer(), packet.getHand() == InteractionHand.MAIN_HAND ? PlayerAnimationType.ARM_SWING : PlayerAnimationType.OFF_ARM_SWING); this.cserver.getPluginManager().callEvent(event); if (event.isCancelled()) { return; @@ -1184,7 +1262,7 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB // Fish bucket - SPIGOT-4048 if ((entity instanceof Bucketable && entity instanceof LivingEntity && origItem != null && origItem.asItem() == Items.WATER_BUCKET) && (event.isCancelled() || player.getInventory().getSelected() == null || player.getInventory().getSelected().getItem() != origItem)) { - send(new ClientboundAddMobPacket((LivingEntity) entity)); + send(new ClientboundAddEntityPacket((LivingEntity) entity)); player.containerMenu.sendAllDataToRemote(); } @@ -1247,7 +1325,7 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB player.containerMenu.sendAllDataToRemote(); } } else { - disconnect(new TranslatableComponent("multiplayer.disconnect.invalid_entity_attacked")); + disconnect(Component.translatable("multiplayer.disconnect.invalid_entity_attacked")); LOGGER.warn("Player {} tried to attack an invalid entity", player.getName().getString()); } } @@ -1279,6 +1357,8 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB boolean cancelled = this.player.isSpectator(); // CraftBukkit - see below if if (false/*this.player.isSpectator()*/) { // CraftBukkit this.player.containerMenu.sendAllDataToRemote(); + } else if (!this.player.containerMenu.stillValid(this.player)) { + LOGGER.debug("Player {} interacted with invalid menu {}", this.player, this.player.containerMenu); } else { boolean flag = packet.getStateId() != this.player.containerMenu.getStateId(); @@ -1599,9 +1679,11 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB final CompoundTag nbttagcompound = BlockItem.getBlockEntityData(itemstack); if (!itemstack.isEmpty() && nbttagcompound != null && nbttagcompound.contains("x") && nbttagcompound.contains("y") && nbttagcompound.contains("z")) { BlockPos blockpos = BlockEntity.getPosFromTag(nbttagcompound); - BlockEntity blockentity = this.player.level.getBlockEntity(blockpos); - if (blockentity != null) { - blockentity.saveToItem(itemstack); + if (this.player.level.isLoaded(blockpos)) { + BlockEntity blockentity = this.player.level.getBlockEntity(blockpos); + if (blockentity != null) { + blockentity.saveToItem(itemstack); + } } } final boolean flag2 = packetplayinsetcreativeslot.getSlotNum() >= 1 && packetplayinsetcreativeslot.getSlotNum() <= 45; @@ -1653,7 +1735,7 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB * @reason */ @Overwrite - private void updateSignText(ServerboundSignUpdatePacket packet, List list) { + private void updateSignText(ServerboundSignUpdatePacket packet, List list) { if (((ServerPlayerEntityBridge) player).bridge$isMovementBlocked()) { return; } @@ -1680,12 +1762,12 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB String[] lines = new String[4]; for (int i = 0; i < list.size(); ++i) { - TextFilter.FilteredText text = list.get(i); + FilteredText text = list.get(i); if (this.player.isTextFilteringEnabled()) { - lines[i] = ChatFormatting.stripFormatting(new TextComponent(ChatFormatting.stripFormatting(text.getFiltered())).getString()); + lines[i] = ChatFormatting.stripFormatting(text.filteredOrEmpty()); } else { - lines[i] = ChatFormatting.stripFormatting(new TextComponent(ChatFormatting.stripFormatting(text.getRaw())).getString()); + lines[i] = ChatFormatting.stripFormatting(text.raw()); } } SignChangeEvent event = new SignChangeEvent(player.getWorld().getBlockAt(x, y, z), player, lines); @@ -1703,11 +1785,6 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB } } - @Inject(method = "handleKeepAlive", at = @At("HEAD")) - private void arclight$syncKeepAlive(ServerboundKeepAlivePacket packetIn, CallbackInfo ci) { - PacketUtils.ensureRunningOnSameThread(packetIn, (ServerGamePacketListenerImpl) (Object) this, this.player.getLevel()); - } - /** * @author IzzelAliz * @reason @@ -1729,6 +1806,7 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB private static final ResourceLocation CUSTOM_REGISTER = new ResourceLocation("register"); private static final ResourceLocation CUSTOM_UNREGISTER = new ResourceLocation("unregister"); + // TODO FIXME handle custom payload on main thread @Inject(method = "handleCustomPayload", cancellable = true, at = @At(value = "INVOKE", remap = false, target = "Lnet/minecraftforge/network/NetworkHooks;onCustomPayload(Lnet/minecraftforge/network/ICustomPacket;Lnet/minecraft/network/Connection;)Z")) private void arclight$customPayload(ServerboundCustomPayloadPacket packet, CallbackInfo ci) { if (packet.identifier.equals(CUSTOM_REGISTER)) { diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/network/ServerStatusNetHandlerMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/network/ServerStatusNetHandlerMixin.java index 920d65e8..32be32c3 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/network/ServerStatusNetHandlerMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/network/ServerStatusNetHandlerMixin.java @@ -54,6 +54,7 @@ public class ServerStatusNetHandlerMixin { playerSample.setSample(profiles.toArray(new GameProfile[0])); } ServerStatus ping = new ServerStatus(); + ping.setPreviewsChat(event.shouldSendChatPreviews()); ping.setFavicon(event.icon.value); ping.setDescription(CraftChatMessage.fromString(event.getMotd(), true)[0]); ping.setPlayers(playerSample); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/network/protocol/game/CChatMessagePacketMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/network/protocol/game/CChatMessagePacketMixin.java deleted file mode 100644 index ca6d4504..00000000 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/network/protocol/game/CChatMessagePacketMixin.java +++ /dev/null @@ -1,32 +0,0 @@ -package io.izzel.arclight.common.mixin.core.network.protocol.game; - -import com.google.common.util.concurrent.ThreadFactoryBuilder; -import net.minecraft.network.protocol.game.ServerGamePacketListener; -import net.minecraft.network.protocol.game.ServerboundChatPacket; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -@Mixin(ServerboundChatPacket.class) -public class CChatMessagePacketMixin { - - @Shadow @Final private String message; - - private static final ExecutorService executors = Executors.newCachedThreadPool( - new ThreadFactoryBuilder().setDaemon(true).setNameFormat("Async Chat Thread - #%d").build() - ); - - @Inject(method = "handle(Lnet/minecraft/network/protocol/game/ServerGamePacketListener;)V", cancellable = true, at = @At("HEAD")) - private void arclight$asyncChat(ServerGamePacketListener handler, CallbackInfo ci) { - if (!this.message.startsWith("/")) { - executors.submit(() -> handler.handleChat((ServerboundChatPacket) (Object) this)); - ci.cancel(); - } - } -} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/network/protocol/game/SChatPacketMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/network/protocol/game/SChatPacketMixin.java deleted file mode 100644 index c654b7e6..00000000 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/network/protocol/game/SChatPacketMixin.java +++ /dev/null @@ -1,41 +0,0 @@ -package io.izzel.arclight.common.mixin.core.network.protocol.game; - -import net.md_5.bungee.api.chat.BaseComponent; -import net.md_5.bungee.chat.ComponentSerializer; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.network.chat.ChatType; -import net.minecraft.network.chat.Component; -import net.minecraft.network.protocol.game.ClientboundChatPacket; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; -import org.spongepowered.asm.mixin.Shadow; - -import java.io.IOException; -import java.util.UUID; - -@Mixin(ClientboundChatPacket.class) -public class SChatPacketMixin { - - // @formatter:off - @Shadow private Component message; - @Shadow private ChatType type; - @Shadow private UUID sender; - // @formatter:on - - public BaseComponent[] components; - - /** - * @author IzzelAliz - * @reason - */ - @Overwrite - public void write(FriendlyByteBuf buf) throws IOException { - if (components != null) { - buf.writeUtf(ComponentSerializer.toString(components)); - } else { - buf.writeComponent(this.message); - } - buf.writeByte(this.type.getIndex()); - buf.writeUUID(this.sender); - } -} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/MinecraftServerMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/MinecraftServerMixin.java index 353314b2..f69756c6 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/MinecraftServerMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/MinecraftServerMixin.java @@ -1,8 +1,6 @@ package io.izzel.arclight.common.mixin.core.server; import com.google.common.collect.ImmutableList; -import com.mojang.authlib.GameProfileRepository; -import com.mojang.authlib.minecraft.MinecraftSessionService; import com.mojang.datafixers.DataFixer; import com.mojang.serialization.DynamicOps; import io.izzel.arclight.common.bridge.core.command.ICommandSourceBridge; @@ -26,7 +24,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.RegistryAccess; import net.minecraft.nbt.NbtOps; import net.minecraft.nbt.Tag; -import net.minecraft.network.chat.TextComponent; +import net.minecraft.network.chat.Component; import net.minecraft.network.protocol.status.ServerStatus; import net.minecraft.obfuscate.DontObfuscate; import net.minecraft.resources.RegistryOps; @@ -34,6 +32,7 @@ import net.minecraft.resources.ResourceKey; import net.minecraft.server.MinecraftServer; import net.minecraft.server.ReloadableServerResources; import net.minecraft.server.ServerFunctionManager; +import net.minecraft.server.Services; import net.minecraft.server.TickTask; import net.minecraft.server.WorldStem; import net.minecraft.server.level.ServerChunkCache; @@ -46,7 +45,6 @@ import net.minecraft.server.packs.repository.Pack; import net.minecraft.server.packs.repository.PackRepository; import net.minecraft.server.packs.resources.CloseableResourceManager; import net.minecraft.server.packs.resources.MultiPackResourceManager; -import net.minecraft.server.players.GameProfileCache; import net.minecraft.server.players.PlayerList; import net.minecraft.util.Unit; import net.minecraft.util.profiling.ProfilerFiller; @@ -58,11 +56,12 @@ import net.minecraft.world.level.ForcedChunksSavedData; import net.minecraft.world.level.Level; import net.minecraft.world.level.border.WorldBorder; import net.minecraft.world.level.levelgen.WorldGenSettings; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager; import net.minecraft.world.level.storage.LevelStorageSource; import net.minecraft.world.level.storage.ServerLevelData; import net.minecraft.world.level.storage.WorldData; import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.level.LevelEvent; import net.minecraftforge.internal.BrandingControl; import net.minecraftforge.server.ServerLifecycleHooks; import org.bukkit.Bukkit; @@ -93,10 +92,8 @@ import java.io.File; import java.io.IOException; import java.lang.management.ManagementFactory; import java.net.Proxy; -import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Collection; -import java.util.Date; import java.util.Map; import java.util.Objects; import java.util.concurrent.CompletableFuture; @@ -142,7 +139,6 @@ public abstract class MinecraftServerMixin extends ReentrantBlockableEventLoop 2000L && this.nextTickTime - this.lastOverloadWarning >= 15000L) { - long j = i / 50L; - - if (server.getWarnOnOverload()) { - LOGGER.warn("Can't keep up! Is the server overloaded? Running {}ms or {} ticks behind", i, j); - } - - this.nextTickTime += j * 50L; - this.lastOverloadWarning = this.nextTickTime; - } - - if (tickCount++ % SAMPLE_INTERVAL == 0) { - double currentTps = 1E3 / (curTime - tickSection) * SAMPLE_INTERVAL; - recentTps[0] = calcTps(recentTps[0], 0.92, currentTps); // 1/exp(5sec/1min) - recentTps[1] = calcTps(recentTps[1], 0.9835, currentTps); // 1/exp(5sec/5min) - recentTps[2] = calcTps(recentTps[2], 0.9945, currentTps); // 1/exp(5sec/15min) - tickSection = curTime; - } - - currentTick = (int) (System.currentTimeMillis() / 50); - - this.nextTickTime += 50L; - this.startMetricsRecordingTick(); - this.profiler.push("tick"); - this.tickServer(this::haveTime); - this.profiler.popPush("nextTickWait"); - this.mayHaveDelayedTasks = true; - this.delayedTasksMaxNextTickTime = Math.max(Util.getMillis() + 50L, this.nextTickTime); - this.waitUntilNextTick(); - this.profiler.pop(); - this.endMetricsRecordingTick(); - this.isReady = true; - JvmProfiler.INSTANCE.onServerTick(this.averageTickTime); - } - ServerLifecycleHooks.handleServerStopping((MinecraftServer) (Object) this); - ServerLifecycleHooks.expectServerStopped(); // has to come before finalTick to avoid race conditions - } else { - ServerLifecycleHooks.expectServerStopped(); // has to come before finalTick to avoid race conditions - this.onServerCrash(null); + if (!this.initServer()) { + throw new IllegalStateException("Failed to initialize server"); } + ServerLifecycleHooks.handleServerStarted((MinecraftServer) (Object) this); + this.nextTickTime = Util.getMillis(); + this.status.setDescription(Component.literal(this.motd)); + this.status.setVersion(new ServerStatus.Version(SharedConstants.getCurrentVersion().getName(), SharedConstants.getCurrentVersion().getProtocolVersion())); + this.status.setPreviewsChat(this.previewsChat()); + this.status.setEnforcesSecureChat(this.enforceSecureProfile()); + this.updateStatusIcon(this.status); + + Arrays.fill(recentTps, 20); + long curTime, tickSection = Util.getMillis(), tickCount = 1; + + while (this.running) { + long i = (curTime = Util.getMillis()) - this.nextTickTime; + if (i > 2000L && this.nextTickTime - this.lastOverloadWarning >= 15000L) { + long j = i / 50L; + + if (server.getWarnOnOverload()) { + LOGGER.warn("Can't keep up! Is the server overloaded? Running {}ms or {} ticks behind", i, j); + } + + this.nextTickTime += j * 50L; + this.lastOverloadWarning = this.nextTickTime; + } + + if (tickCount++ % SAMPLE_INTERVAL == 0) { + double currentTps = 1E3 / (curTime - tickSection) * SAMPLE_INTERVAL; + recentTps[0] = calcTps(recentTps[0], 0.92, currentTps); // 1/exp(5sec/1min) + recentTps[1] = calcTps(recentTps[1], 0.9835, currentTps); // 1/exp(5sec/5min) + recentTps[2] = calcTps(recentTps[2], 0.9945, currentTps); // 1/exp(5sec/15min) + tickSection = curTime; + } + + currentTick = (int) (System.currentTimeMillis() / 50); + + this.nextTickTime += 50L; + this.startMetricsRecordingTick(); + this.profiler.push("tick"); + this.tickServer(this::haveTime); + this.profiler.popPush("nextTickWait"); + this.mayHaveDelayedTasks = true; + this.delayedTasksMaxNextTickTime = Math.max(Util.getMillis() + 50L, this.nextTickTime); + this.waitUntilNextTick(); + this.profiler.pop(); + this.endMetricsRecordingTick(); + this.isReady = true; + JvmProfiler.INSTANCE.onServerTick(this.averageTickTime); + } + ServerLifecycleHooks.handleServerStopping((MinecraftServer) (Object) this); + ServerLifecycleHooks.expectServerStopped(); // has to come before finalTick to avoid race conditions } catch (Throwable throwable1) { LOGGER.error("Encountered an unexpected exception", throwable1); - - if (throwable1.getCause() != null) { - LOGGER.error("\tCause of unexpected exception was", throwable1.getCause()); - } - - CrashReport crashreport; - if (throwable1 instanceof ReportedException) { - crashreport = ((ReportedException) throwable1).getReport(); - } else { - crashreport = new CrashReport("Exception in server tick loop", throwable1); - } - + CrashReport crashreport = constructOrExtractCrashReport(throwable1); this.fillSystemReport(crashreport.getSystemReport()); - File file1 = new File(new File(this.getServerDirectory(), "crash-reports"), "crash-" + (new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss")).format(new Date()) + "-server.txt"); + File file1 = new File(new File(this.getServerDirectory(), "crash-reports"), "crash-" + Util.getFilenameFormattedDateTime() + "-server.txt"); if (crashreport.saveToFile(file1)) { LOGGER.error("This crash report has been saved to: {}", file1.getAbsolutePath()); } else { LOGGER.error("We were unable to save this crash report to disk."); } - ServerLifecycleHooks.expectServerStopped(); // has to come before finalTick to avoid race conditions + net.minecraftforge.server.ServerLifecycleHooks.expectServerStopped(); // Forge: Has to come before MinecraftServer#onServerCrash to avoid race conditions this.onServerCrash(crashreport); } finally { try { @@ -293,8 +282,8 @@ public abstract class MinecraftServerMixin extends ReentrantBlockableEventLoop { CloseableResourceManager closeableresourcemanager = new MultiPackResourceManager(PackType.SERVER_DATA, p_212913_); return ReloadableServerResources.loadResources(closeableresourcemanager, registryaccess$frozen, this.isDedicatedServer() ? Commands.CommandSelection.DEDICATED : Commands.CommandSelection.INTEGRATED, this.getFunctionCompilationLevel(), this.executor, this).whenComplete((p_212907_, p_212908_) -> { - if (p_212908_ != null) { - closeableresourcemanager.close(); - } + if (p_212908_ != null) { + closeableresourcemanager.close(); + } }).thenApply((p_212904_) -> { - return new MinecraftServer.ReloadableResources(closeableresourcemanager, p_212904_); + return new MinecraftServer.ReloadableResources(closeableresourcemanager, p_212904_); }); }).thenAcceptAsync((p_212919_) -> { this.resources.close(); - this.resources= p_212919_; + this.resources = p_212919_; this.server.syncCommands(); this.packRepository.setSelected(p_129862_); this.worldData.setDataPackConfig(getSelectedPacks(this.packRepository)); @@ -530,7 +519,7 @@ public abstract class MinecraftServerMixin extends ReentrantBlockableEventLoop getChunks(); @Shadow protected abstract void tick(); @Shadow @Mutable public ChunkGenerator generator; + @Shadow @Final public ServerLevel level; + @Shadow private RandomState randomState; @Invoker("tick") public abstract void bridge$tick(BooleanSupplier hasMoreTime); @Invoker("setViewDistance") public abstract void bridge$setViewDistance(int i); // @formatter:on - @Redirect(method = "readChunk", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;dimension()Lnet/minecraft/resources/ResourceKey;")) + @Inject(method = "", at = @At("RETURN")) + private void arclight$updateRandom(ServerLevel p_214836_, LevelStorageSource.LevelStorageAccess p_214837_, DataFixer p_214838_, StructureTemplateManager p_214839_, Executor p_214840_, BlockableEventLoop p_214841_, LightChunkGetter p_214842_, ChunkGenerator p_214843_, ChunkProgressListener p_214844_, ChunkStatusUpdateListener p_214845_, Supplier p_214846_, int p_214847_, boolean p_214848_, CallbackInfo ci) { + this.bridge$setChunkGenerator(this.generator); + } + + @Redirect(method = "upgradeChunkTag", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;dimension()Lnet/minecraft/resources/ResourceKey;")) private ResourceKey arclight$useTypeKey(ServerLevel serverWorld) { return ((WorldBridge) serverWorld).bridge$getTypeKey(); } @@ -61,5 +85,13 @@ public abstract class ChunkMapMixin implements ChunkMapBridge { @Override public void bridge$setChunkGenerator(ChunkGenerator generator) { this.generator = generator; + if (generator instanceof CustomChunkGenerator custom) { + generator = custom.getDelegate(); + } + if (generator instanceof NoiseBasedChunkGenerator noisebasedchunkgenerator) { + this.randomState = RandomState.create(noisebasedchunkgenerator.generatorSettings().value(), this.level.registryAccess().registryOrThrow(Registry.NOISE_REGISTRY), this.level.getSeed()); + } else { + this.randomState = RandomState.create(NoiseGeneratorSettings.dummy(), this.level.registryAccess().registryOrThrow(Registry.NOISE_REGISTRY), this.level.getSeed()); + } } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/level/DistanceManagerMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/level/DistanceManagerMixin.java index ff1b917f..6b2836aa 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/level/DistanceManagerMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/level/DistanceManagerMixin.java @@ -33,7 +33,8 @@ public abstract class DistanceManagerMixin implements TicketManagerBridge { @Shadow private static int getTicketLevelAt(SortedArraySet> p_229844_0_) { return 0; } @Shadow @Final public Long2ObjectOpenHashMap>> tickets; @Shadow abstract TickingTracker tickingTracker(); - @Shadow@Final private Long2ObjectOpenHashMap>> forcedTickets;@Invoker("purgeStaleTickets") public abstract void bridge$tick(); + @Shadow @Final private Long2ObjectOpenHashMap>> forcedTickets; + @Invoker("purgeStaleTickets") public abstract void bridge$tick(); // @formatter:on @Inject(method = "removePlayer", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", remap = false, target = "Lit/unimi/dsi/fastutil/objects/ObjectSet;remove(Ljava/lang/Object;)Z")) diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/level/ServerEntityMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/level/ServerEntityMixin.java index 9a383e1c..ab4406d5 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/level/ServerEntityMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/level/ServerEntityMixin.java @@ -6,7 +6,6 @@ import io.izzel.arclight.common.bridge.core.entity.player.ServerPlayerEntityBrid import io.izzel.arclight.common.bridge.core.world.ServerEntityBridge; import io.izzel.arclight.common.mod.ArclightConstants; import net.minecraft.network.protocol.Packet; -import net.minecraft.network.protocol.game.ClientboundAddMobPacket; import net.minecraft.network.protocol.game.ClientboundMoveEntityPacket; import net.minecraft.network.protocol.game.ClientboundRotateHeadPacket; import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket; @@ -17,6 +16,7 @@ import net.minecraft.network.protocol.game.ClientboundSetPassengersPacket; import net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket; import net.minecraft.network.protocol.game.ClientboundUpdateAttributesPacket; import net.minecraft.network.protocol.game.ClientboundUpdateMobEffectPacket; +import net.minecraft.network.protocol.game.VecDeltaCodec; import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.server.level.ServerEntity; import net.minecraft.server.level.ServerLevel; @@ -69,12 +69,9 @@ public abstract class ServerEntityMixin implements ServerEntityBridge { @Shadow @Final private int updateInterval; @Shadow private int yRotp; @Shadow private int xRotp; - @Shadow protected abstract void updateSentPos(); + @Shadow @Final private VecDeltaCodec positionCodec; @Shadow private boolean wasRiding; @Shadow private int teleportDelay; - @Shadow private long xp; - @Shadow private long yp; - @Shadow private long zp; @Shadow private boolean wasOnGround; @Shadow @Final private boolean trackDelta; @Shadow private Vec3 ap; @@ -150,29 +147,22 @@ public abstract class ServerEntityMixin implements ServerEntityBridge { this.yRotp = i1; this.xRotp = l1; } - this.updateSentPos(); + this.positionCodec.setBase(this.entity.trackingPosition()); this.sendDirtyEntityData(); this.wasRiding = true; } else { this.teleportDelay += elapsedTicks; int l = Mth.floor(this.entity.getYRot() * 256.0F / 360.0F); int k1 = Mth.floor(this.entity.getXRot() * 256.0F / 360.0F); - Vec3 vector3d = this.entity.position().subtract(ClientboundMoveEntityPacket.packetToEntity(this.xp, this.yp, this.zp)); - boolean flag3 = vector3d.lengthSqr() >= (double) 7.6293945E-6F; + Vec3 vector3d = this.entity.trackingPosition(); + boolean flag3 = this.positionCodec.delta(vector3d).lengthSqr() >= 7.62939453125E-6D; Packet ipacket1 = null; boolean flag4 = flag3 || this.tickCount / 60 != this.lastPosUpdate; boolean flag = Math.abs(l - this.yRotp) >= 1 || Math.abs(k1 - this.xRotp) >= 1; - if (flag4) { - this.updateSentPos(); - } - if (flag) { - this.yRotp = l; - this.xRotp = k1; - } if (this.tickCount > 0 || this.entity instanceof AbstractArrow) { - long i = ClientboundMoveEntityPacket.entityToPacket(vector3d.x); - long j = ClientboundMoveEntityPacket.entityToPacket(vector3d.y); - long k = ClientboundMoveEntityPacket.entityToPacket(vector3d.z); + long i = this.positionCodec.encodeX(vector3d); + long j = this.positionCodec.encodeY(vector3d); + long k = this.positionCodec.encodeZ(vector3d); boolean flag1 = i < -32768L || i > 32767L || j < -32768L || j > 32767L || k < -32768L || k > 32767L; if (!flag1 && this.teleportDelay <= 400 && !this.wasRiding && this.wasOnGround == this.entity.isOnGround()) { if ((!flag4 || !flag) && !(this.entity instanceof AbstractArrow)) { @@ -202,6 +192,13 @@ public abstract class ServerEntityMixin implements ServerEntityBridge { this.broadcast.accept(ipacket1); } this.sendDirtyEntityData(); + if (flag4) { + this.positionCodec.setBase(vector3d); + } + if (flag) { + this.yRotp = l; + this.xRotp = k1; + } this.wasRiding = false; } int j1 = Mth.floor(this.entity.getYHeadRot() * 256.0F / 360.0F); @@ -279,7 +276,7 @@ public abstract class ServerEntityMixin implements ServerEntityBridge { } } this.ap = this.entity.getDeltaMovement(); - if (flag && !(packet instanceof ClientboundAddMobPacket)) { + if (flag && !(this.entity instanceof LivingEntity)) { consumer.accept(new ClientboundSetEntityMotionPacket(this.entity.getId(), this.ap)); } if (this.entity instanceof LivingEntity) { 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 fbfc2be5..96f8a4ae 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 @@ -20,7 +20,6 @@ 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.Holder; import net.minecraft.core.Registry; import net.minecraft.core.particles.ParticleOptions; import net.minecraft.network.protocol.Packet; @@ -39,34 +38,38 @@ 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.Level; 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; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkGenerator; import net.minecraft.world.level.chunk.LevelChunk; -import net.minecraft.world.level.dimension.DimensionType; import net.minecraft.world.level.dimension.LevelStem; import net.minecraft.world.level.entity.PersistentEntitySectionManager; +import net.minecraft.world.level.gameevent.GameEvent; import net.minecraft.world.level.saveddata.maps.MapItemSavedData; import net.minecraft.world.level.storage.DerivedLevelData; import net.minecraft.world.level.storage.DimensionDataStorage; import net.minecraft.world.level.storage.LevelStorageSource; import net.minecraft.world.level.storage.PrimaryLevelData; import net.minecraft.world.level.storage.ServerLevelData; +import net.minecraft.world.phys.Vec3; import org.bukkit.Bukkit; +import org.bukkit.Location; import org.bukkit.craftbukkit.v.CraftWorld; import org.bukkit.craftbukkit.v.entity.CraftHumanEntity; import org.bukkit.craftbukkit.v.event.CraftEventFactory; import org.bukkit.craftbukkit.v.generator.CustomChunkGenerator; import org.bukkit.craftbukkit.v.util.BlockStateListPopulator; +import org.bukkit.craftbukkit.v.util.CraftNamespacedKey; import org.bukkit.craftbukkit.v.util.WorldUUID; import org.bukkit.entity.HumanEntity; import org.bukkit.entity.LightningStrike; import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.event.server.MapInitializeEvent; import org.bukkit.event.weather.LightningStrikeEvent; +import org.bukkit.event.world.GenericGameEvent; import org.bukkit.event.world.PortalCreateEvent; import org.bukkit.event.world.TimeSkipEvent; import org.bukkit.event.world.WorldSaveEvent; @@ -109,8 +112,7 @@ public abstract class ServerLevelMixin extends LevelMixin implements ServerWorld // @formatter:on @SuppressWarnings({"FieldCanBeLocal", "unused"}) - public PrimaryLevelData M; // TODO f_8549_ check on update - private int tickPosition; + public PrimaryLevelData N; // TODO f_8549_ check on update public LevelStorageSource.LevelStorageAccess convertable; public UUID uuid; public ResourceKey typeKey; @@ -120,12 +122,12 @@ public abstract class ServerLevelMixin extends LevelMixin implements ServerWorld return this.typeKey; } - public void arclight$constructor(MinecraftServer server, Executor backgroundExecutor, LevelStorageSource.LevelStorageAccess levelSave, ServerLevelData serverWorldInfo, ResourceKey dimension, Holder dimensionType, ChunkProgressListener statusListener, ChunkGenerator chunkGenerator, boolean isDebug, long seed, List specialSpawners, boolean shouldBeTicking) { + public void arclight$constructor(MinecraftServer minecraftServer, Executor backgroundExecutor, LevelStorageSource.LevelStorageAccess levelSave, ServerLevelData worldInfo, ResourceKey dimension, LevelStem levelStem, ChunkProgressListener statusListener, boolean isDebug, long seed, List specialSpawners, boolean shouldBeTicking) { throw new RuntimeException(); } - public void arclight$constructor(MinecraftServer server, Executor backgroundExecutor, LevelStorageSource.LevelStorageAccess levelSave, ServerLevelData serverWorldInfo, ResourceKey dimension, Holder dimensionType, ChunkProgressListener statusListener, ChunkGenerator chunkGenerator, boolean isDebug, long seed, List specialSpawners, boolean shouldBeTicking, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider) { - arclight$constructor(server, backgroundExecutor, levelSave, serverWorldInfo, dimension, dimensionType, statusListener, chunkGenerator, isDebug, seed, specialSpawners, shouldBeTicking); + public void arclight$constructor(MinecraftServer minecraftServer, Executor backgroundExecutor, LevelStorageSource.LevelStorageAccess levelSave, PrimaryLevelData worldInfo, ResourceKey dimension, LevelStem levelStem, ChunkProgressListener statusListener, boolean isDebug, long seed, List specialSpawners, boolean shouldBeTicking, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider) { + arclight$constructor(minecraftServer, backgroundExecutor, levelSave, worldInfo, dimension, levelStem, statusListener, isDebug, seed, specialSpawners, shouldBeTicking); this.generator = gen; this.environment = env; this.biomeProvider = biomeProvider; @@ -136,8 +138,8 @@ public abstract class ServerLevelMixin extends LevelMixin implements ServerWorld bridge$getWorld(); } - @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/core/Holder;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, Holder dimensionType, ChunkProgressListener statusListener, ChunkGenerator chunkGenerator, boolean isDebug, long seed, List specialSpawners, boolean shouldBeTicking, CallbackInfo ci) { + @Inject(method = "", at = @At("RETURN")) + private void arclight$init(MinecraftServer minecraftServer, Executor backgroundExecutor, LevelStorageSource.LevelStorageAccess levelSave, ServerLevelData worldInfo, ResourceKey dimension, LevelStem levelStem, ChunkProgressListener statusListener, boolean isDebug, long seed, List specialSpawners, boolean shouldBeTicking, CallbackInfo ci) { this.pvpMode = minecraftServer.isPvpAllowed(); this.convertable = levelSave; var typeKey = ((LevelStorageSourceBridge.LevelStorageAccessBridge) levelSave).bridge$getTypeKey(); @@ -145,18 +147,18 @@ public abstract class ServerLevelMixin extends LevelMixin implements ServerWorld this.typeKey = typeKey; } else { var dimensions = shadow$getServer().getWorldData().worldGenSettings().dimensions(); - var levelStem = dimensions.get(dimension.location()); - if (levelStem != null) { - this.typeKey = ResourceKey.create(Registry.LEVEL_STEM_REGISTRY, dimension.location()); + var key = dimensions.getKey(levelStem); + if (key != null) { + this.typeKey = ResourceKey.create(Registry.LEVEL_STEM_REGISTRY, key); } else { throw new IllegalStateException("No level stem for dimension " + dimension.location()); } } if (worldInfo instanceof PrimaryLevelData) { - this.M = (PrimaryLevelData) worldInfo; + this.N = (PrimaryLevelData) worldInfo; } else if (worldInfo instanceof DerivedLevelData) { // damn spigot again - this.M = DelegateWorldInfo.wrap(((DerivedLevelData) worldInfo)); + this.N = DelegateWorldInfo.wrap(((DerivedLevelData) worldInfo)); ((DerivedWorldInfoBridge) worldInfo).bridge$setDimType(this.getTypeKey()); if (ArclightConfig.spec().getCompat().isSymlinkWorld()) { WorldSymlink.create((DerivedLevelData) worldInfo, levelSave.getDimensionPath(this.dimension()).toFile()); @@ -165,7 +167,7 @@ public abstract class ServerLevelMixin extends LevelMixin implements ServerWorld this.spigotConfig = new SpigotWorldConfig(worldInfo.getLevelName()); this.uuid = WorldUUID.getUUID(levelSave.getDimensionPath(this.dimension()).toFile()); ((ServerChunkProviderBridge) this.chunkSource).bridge$setViewDistance(spigotConfig.viewDistance); - ((WorldInfoBridge) this.M).bridge$setWorld((ServerLevel) (Object) this); + ((WorldInfoBridge) this.N).bridge$setWorld((ServerLevel) (Object) this); var data = this.getDataStorage().computeIfAbsent(LevelPersistentData::new, () -> new LevelPersistentData(null), "bukkit_pdc"); this.bridge$getWorld().readBukkitValues(data.getTag()); } @@ -176,6 +178,17 @@ public abstract class ServerLevelMixin extends LevelMixin implements ServerWorld data.save(this.world); } + @Inject(method = "gameEvent", cancellable = true, at = @At("HEAD")) + private void arclight$gameEventEvent(GameEvent gameEvent, Vec3 pos, GameEvent.Context context, CallbackInfo ci) { + var entity = context.sourceEntity(); + var i = gameEvent.getNotificationRadius(); + GenericGameEvent event = new GenericGameEvent(org.bukkit.GameEvent.getByKey(CraftNamespacedKey.fromMinecraft(Registry.GAME_EVENT.getKey(gameEvent))), new Location(this.getWorld(), pos.x(), pos.y(), pos.z()), (entity == null) ? null : ((EntityBridge) entity).bridge$getBukkitEntity(), i, !Bukkit.isPrimaryThread()); + Bukkit.getPluginManager().callEvent(event); + if (event.isCancelled()) { + ci.cancel(); + } + } + public LevelChunk getChunkIfLoaded(int x, int z) { return this.chunkSource.getChunk(x, z, false); } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/management/PlayerListMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/management/PlayerListMixin.java index 4639633f..d16bd10e 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/management/PlayerListMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/management/PlayerListMixin.java @@ -14,16 +14,13 @@ import io.izzel.arclight.common.bridge.core.world.WorldBridge; import io.izzel.arclight.common.mod.server.ArclightServer; import io.izzel.arclight.common.mod.util.ArclightCaptures; import io.izzel.arclight.mixin.Eject; -import net.minecraft.Util; import net.minecraft.core.BlockPos; import net.minecraft.core.RegistryAccess; +import net.minecraft.core.UUIDUtil; import net.minecraft.network.Connection; -import net.minecraft.network.chat.ChatType; import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.TranslatableComponent; import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.game.ClientboundChangeDifficultyPacket; -import net.minecraft.network.protocol.game.ClientboundChatPacket; import net.minecraft.network.protocol.game.ClientboundEntityEventPacket; import net.minecraft.network.protocol.game.ClientboundGameEventPacket; import net.minecraft.network.protocol.game.ClientboundRespawnPacket; @@ -52,6 +49,7 @@ import net.minecraft.util.Mth; import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.player.ProfilePublicKey; import net.minecraft.world.level.GameRules; import net.minecraft.world.level.Level; import net.minecraft.world.level.biome.BiomeManager; @@ -116,14 +114,12 @@ public abstract class PlayerListMixin implements PlayerListBridge { @Shadow @Final private MinecraftServer server; @Shadow public abstract UserBanList getBans(); @Shadow public abstract IpBanList getIpBans(); - @Shadow(remap = false) public abstract boolean removePlayer(ServerPlayer player); @Shadow public abstract void sendLevelInfo(ServerPlayer playerIn, ServerLevel worldIn); @Shadow public abstract void sendPlayerPermissionLevel(ServerPlayer player); - @Shadow(remap = false) public abstract boolean addPlayer(ServerPlayer player); @Shadow @Final private Map playersByUUID; @Shadow public abstract void sendAllPlayerInfo(ServerPlayer playerIn); - @Shadow public abstract void broadcastMessage(Component p_232641_1_, ChatType p_232641_2_, UUID p_232641_3_); @Shadow @Nullable public abstract ServerPlayer getPlayer(UUID playerUUID); + @Shadow public abstract void broadcastSystemMessage(Component p_240618_, boolean p_240644_); // @formatter:on private CraftServer cserver; @@ -160,8 +156,8 @@ public abstract class PlayerListMixin implements PlayerListBridge { return ((WorldBridge) playerIn.getLevel()).bridge$spigotConfig().simulationDistance; } - @Eject(method = "placeNewPlayer", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/players/PlayerList;broadcastMessage(Lnet/minecraft/network/chat/Component;Lnet/minecraft/network/chat/ChatType;Ljava/util/UUID;)V")) - private void arclight$playerJoin(PlayerList playerList, Component component, ChatType chatType, UUID uuid, CallbackInfo ci, Connection netManager, ServerPlayer playerIn) { + @Eject(method = "placeNewPlayer", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/players/PlayerList;broadcastSystemMessage(Lnet/minecraft/network/chat/Component;Z)V")) + private void arclight$playerJoin(PlayerList playerList, Component component, boolean flag, CallbackInfo ci, Connection netManager, ServerPlayer playerIn) { PlayerJoinEvent playerJoinEvent = new PlayerJoinEvent(((ServerPlayerEntityBridge) playerIn).bridge$getBukkitEntity(), CraftChatMessage.fromComponent(component)); this.players.add(playerIn); this.playersByUUID.put(playerIn.getUUID(), playerIn); @@ -174,7 +170,7 @@ public abstract class PlayerListMixin implements PlayerListBridge { String joinMessage = playerJoinEvent.getJoinMessage(); if (joinMessage != null && joinMessage.length() > 0) { for (Component line : CraftChatMessage.fromString(joinMessage)) { - this.server.getPlayerList().broadcastAll(new ClientboundChatPacket(line, ChatType.SYSTEM, Util.NIL_UUID)); + this.server.getPlayerList().broadcastSystemMessage(line, flag); } } } @@ -201,8 +197,8 @@ public abstract class PlayerListMixin implements PlayerListBridge { } @Override - public ServerPlayer bridge$canPlayerLogin(SocketAddress socketAddress, GameProfile gameProfile, ServerLoginPacketListenerImpl handler) { - UUID uuid = net.minecraft.world.entity.player.Player.createPlayerUUID(gameProfile); + public ServerPlayer bridge$canPlayerLogin(SocketAddress socketAddress, GameProfile gameProfile, ServerLoginPacketListenerImpl handler, ProfilePublicKey profilePublicKey) { + UUID uuid = UUIDUtil.getOrCreatePlayerUUID(gameProfile); List list = Lists.newArrayList(); for (ServerPlayer entityplayer : this.players) { if (entityplayer.getUUID().equals(uuid)) { @@ -211,9 +207,9 @@ public abstract class PlayerListMixin implements PlayerListBridge { } for (ServerPlayer entityplayer : list) { this.save(entityplayer); - entityplayer.connection.disconnect(new TranslatableComponent("multiplayer.disconnect.duplicate_login")); + entityplayer.connection.disconnect(Component.translatable("multiplayer.disconnect.duplicate_login")); } - ServerPlayer entity = new ServerPlayer(this.server, this.server.getLevel(Level.OVERWORLD), gameProfile); + ServerPlayer entity = new ServerPlayer(this.server, this.server.getLevel(Level.OVERWORLD), gameProfile, profilePublicKey); Player player = ((ServerPlayerEntityBridge) entity).bridge$getBukkitEntity(); String hostname = handler == null ? "" : ((ServerLoginNetHandlerBridge) handler).bridge$getHostname(); @@ -222,18 +218,18 @@ public abstract class PlayerListMixin implements PlayerListBridge { PlayerLoginEvent event = new PlayerLoginEvent(player, hostname, ((InetSocketAddress) socketAddress).getAddress(), realAddress); if (this.getBans().isBanned(gameProfile) && !this.getBans().get(gameProfile).hasExpired()) { UserBanListEntry gameprofilebanentry = this.bans.get(gameProfile); - TranslatableComponent chatmessage = new TranslatableComponent("multiplayer.disconnect.banned.reason", gameprofilebanentry.getReason()); + var chatmessage = Component.translatable("multiplayer.disconnect.banned.reason", gameprofilebanentry.getReason()); if (gameprofilebanentry.getExpires() != null) { - chatmessage.append(new TranslatableComponent("multiplayer.disconnect.banned.expiration", BAN_DATE_FORMAT.format(gameprofilebanentry.getExpires()))); + chatmessage.append(Component.translatable("multiplayer.disconnect.banned.expiration", BAN_DATE_FORMAT.format(gameprofilebanentry.getExpires()))); } event.disallow(PlayerLoginEvent.Result.KICK_BANNED, CraftChatMessage.fromComponent(chatmessage)); } else if (!this.isWhiteListed(gameProfile)) { event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, SpigotConfig.whitelistMessage); } else if (this.getIpBans().isBanned(socketAddress) && !this.getIpBans().get(socketAddress).hasExpired()) { IpBanListEntry ipbanentry = this.ipBans.get(socketAddress); - TranslatableComponent chatmessage = new TranslatableComponent("multiplayer.disconnect.banned_ip.reason", ipbanentry.getReason()); + var chatmessage = Component.translatable("multiplayer.disconnect.banned_ip.reason", ipbanentry.getReason()); if (ipbanentry.getExpires() != null) { - chatmessage.append(new TranslatableComponent("multiplayer.disconnect.banned_ip.expiration", BAN_DATE_FORMAT.format(ipbanentry.getExpires()))); + chatmessage.append(Component.translatable("multiplayer.disconnect.banned_ip.expiration", BAN_DATE_FORMAT.format(ipbanentry.getExpires()))); } event.disallow(PlayerLoginEvent.Result.KICK_BANNED, CraftChatMessage.fromComponent(chatmessage)); } else if (this.players.size() >= this.maxPlayers && !this.canBypassPlayerLimit(gameProfile)) { @@ -249,10 +245,9 @@ public abstract class PlayerListMixin implements PlayerListBridge { return entity; } - // todo check these two public ServerPlayer respawn(ServerPlayer playerIn, ServerLevel worldIn, boolean flag, Location location, boolean avoidSuffocation) { playerIn.stopRiding(); - this.removePlayer(playerIn); + this.players.remove(playerIn); playerIn.getLevel().removePlayerImmediately(playerIn, Entity.RemovalReason.DISCARDED); playerIn.revive(); BlockPos pos = playerIn.getRespawnPosition(); @@ -325,7 +320,7 @@ public abstract class PlayerListMixin implements PlayerListBridge { playerIn.setPos(playerIn.getX(), playerIn.getY() + 1.0, playerIn.getZ()); } LevelData worlddata = serverWorld.getLevelData(); - playerIn.connection.send(new ClientboundRespawnPacket(serverWorld.dimensionTypeRegistration(), serverWorld.dimension(), BiomeManager.obfuscateSeed(serverWorld.getSeed()), playerIn.gameMode.getGameModeForPlayer(), playerIn.gameMode.getPreviousGameModeForPlayer(), serverWorld.isDebug(), serverWorld.isFlat(), flag)); + playerIn.connection.send(new ClientboundRespawnPacket(serverWorld.dimensionTypeId(), serverWorld.dimension(), BiomeManager.obfuscateSeed(serverWorld.getSeed()), playerIn.gameMode.getGameModeForPlayer(), playerIn.gameMode.getPreviousGameModeForPlayer(), serverWorld.isDebug(), serverWorld.isFlat(), flag, playerIn.getLastDeathLocation())); playerIn.connection.send(new ClientboundSetChunkCacheRadiusPacket(((WorldBridge) serverWorld).bridge$spigotConfig().viewDistance)); playerIn.connection.send(new ClientboundSetSimulationDistancePacket(((WorldBridge) serverWorld).bridge$spigotConfig().simulationDistance)); playerIn.setLevel(serverWorld); @@ -338,13 +333,13 @@ public abstract class PlayerListMixin implements PlayerListBridge { this.sendPlayerPermissionLevel(playerIn); if (!((ServerPlayNetHandlerBridge) playerIn.connection).bridge$isDisconnected()) { serverWorld.addDuringCommandTeleport(playerIn); - this.addPlayer(playerIn); + this.players.add(playerIn); this.playersByUUID.put(playerIn.getUUID(), playerIn); } playerIn.setHealth(playerIn.getHealth()); ForgeEventFactory.firePlayerChangedDimensionEvent(playerIn, ((CraftWorld) fromWorld).getHandle().dimension, serverWorld.dimension); if (flag3) { - playerIn.connection.send(new ClientboundSoundPacket(SoundEvents.RESPAWN_ANCHOR_DEPLETE, SoundSource.BLOCKS, pos.getX(), pos.getY(), pos.getZ(), 1.0f, 1.0f)); + playerIn.connection.send(new ClientboundSoundPacket(SoundEvents.RESPAWN_ANCHOR_DEPLETE, SoundSource.BLOCKS, pos.getX(), pos.getY(), pos.getZ(), 1.0f, 1.0f, serverWorld.random.nextLong())); } this.sendAllPlayerInfo(playerIn); playerIn.onUpdateAbilities(); @@ -377,7 +372,7 @@ public abstract class PlayerListMixin implements PlayerListBridge { boolean avoidSuffocation = arclight$suffo == null || arclight$suffo; arclight$suffo = null; playerIn.stopRiding(); - this.removePlayer(playerIn); + this.players.remove(playerIn); playerIn.getLevel().removePlayerImmediately(playerIn, Entity.RemovalReason.DISCARDED); BlockPos pos = playerIn.getRespawnPosition(); float f = playerIn.getRespawnAngle(); @@ -439,7 +434,7 @@ public abstract class PlayerListMixin implements PlayerListBridge { ServerLevel serverWorld = ((CraftWorld) location.getWorld()).getHandle(); - ServerPlayer serverplayerentity = new ServerPlayer(this.server, serverWorld, playerIn.getGameProfile()); + ServerPlayer serverplayerentity = new ServerPlayer(this.server, serverWorld, playerIn.getGameProfile(), playerIn.getProfilePublicKey()); // Forward to new player instance ((InternalEntityBridge) playerIn).internal$getBukkitEntity().setHandle(serverplayerentity); @@ -471,7 +466,7 @@ public abstract class PlayerListMixin implements PlayerListBridge { } LevelData iworldinfo = serverplayerentity.level.getLevelData(); - serverplayerentity.connection.send(new ClientboundRespawnPacket(serverplayerentity.level.dimensionTypeRegistration(), serverplayerentity.level.dimension(), BiomeManager.obfuscateSeed(serverplayerentity.getLevel().getSeed()), serverplayerentity.gameMode.getGameModeForPlayer(), serverplayerentity.gameMode.getPreviousGameModeForPlayer(), serverplayerentity.getLevel().isDebug(), serverplayerentity.getLevel().isFlat(), conqueredEnd)); + serverplayerentity.connection.send(new ClientboundRespawnPacket(serverplayerentity.level.dimensionTypeId(), serverplayerentity.level.dimension(), BiomeManager.obfuscateSeed(serverplayerentity.getLevel().getSeed()), serverplayerentity.gameMode.getGameModeForPlayer(), serverplayerentity.gameMode.getPreviousGameModeForPlayer(), serverplayerentity.getLevel().isDebug(), serverplayerentity.getLevel().isFlat(), conqueredEnd, serverplayerentity.getLastDeathLocation())); serverplayerentity.connection.send(new ClientboundSetChunkCacheRadiusPacket(((WorldBridge) serverWorld).bridge$spigotConfig().viewDistance)); serverplayerentity.connection.send(new ClientboundSetSimulationDistancePacket(((WorldBridge) serverWorld).bridge$spigotConfig().simulationDistance)); serverplayerentity.setLevel(serverWorld); @@ -484,14 +479,14 @@ public abstract class PlayerListMixin implements PlayerListBridge { this.sendPlayerPermissionLevel(serverplayerentity); if (!((ServerPlayNetHandlerBridge) serverplayerentity.connection).bridge$isDisconnected()) { serverWorld.addRespawnedPlayer(serverplayerentity); - this.addPlayer(serverplayerentity); + this.players.add(serverplayerentity); this.playersByUUID.put(serverplayerentity.getUUID(), serverplayerentity); } serverplayerentity.initInventoryMenu(); serverplayerentity.setHealth(serverplayerentity.getHealth()); ForgeEventFactory.firePlayerRespawnEvent(serverplayerentity, conqueredEnd); if (flag2) { - serverplayerentity.connection.send(new ClientboundSoundPacket(SoundEvents.RESPAWN_ANCHOR_DEPLETE, SoundSource.BLOCKS, (double) pos.getX(), (double) pos.getY(), (double) pos.getZ(), 1.0F, 1.0F)); + serverplayerentity.connection.send(new ClientboundSoundPacket(SoundEvents.RESPAWN_ANCHOR_DEPLETE, SoundSource.BLOCKS, (double) pos.getX(), (double) pos.getY(), (double) pos.getZ(), 1.0F, 1.0F, serverWorld.random.nextLong())); } this.sendAllPlayerInfo(serverplayerentity); serverplayerentity.onUpdateAbilities(); @@ -542,7 +537,7 @@ public abstract class PlayerListMixin implements PlayerListBridge { public void broadcastMessage(Component[] components) { for (Component component : components) { - this.broadcastMessage(component, ChatType.SYSTEM, Util.NIL_UUID); + broadcastSystemMessage(component, false); } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/management/ServerPlayerGameModeMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/management/ServerPlayerGameModeMixin.java index d00f8e54..71ccf58e 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/management/ServerPlayerGameModeMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/management/ServerPlayerGameModeMixin.java @@ -7,7 +7,6 @@ import io.izzel.arclight.common.mod.util.ArclightCaptures; import net.minecraft.advancements.CriteriaTriggers; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; -import net.minecraft.network.protocol.game.ClientboundBlockBreakAckPacket; import net.minecraft.network.protocol.game.ClientboundBlockUpdatePacket; import net.minecraft.network.protocol.game.ServerboundPlayerActionPacket; import net.minecraft.server.level.ServerLevel; @@ -20,10 +19,8 @@ import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.item.DoubleHighBlockItem; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.context.UseOnContext; -import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.GameType; import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.CakeBlock; import net.minecraft.world.level.block.DoorBlock; import net.minecraft.world.level.block.TrapDoorBlock; @@ -69,7 +66,8 @@ public abstract class ServerPlayerGameModeMixin implements PlayerInteractionMana @Shadow private boolean hasDelayedDestroy; @Shadow private BlockPos delayedDestroyPos; @Shadow private int delayedTickStart; - @Shadow public abstract void destroyAndAck(BlockPos p_229860_1_, ServerboundPlayerActionPacket.Action p_229860_2_, String p_229860_3_); + @Shadow public abstract void destroyAndAck(BlockPos p_215117_, int p_215118_, String p_215119_); + @Shadow protected abstract void debugLogging(BlockPos p_215126_, boolean p_215127_, int p_215128_, String p_215129_); // @formatter:on public boolean interactResult = false; @@ -89,34 +87,25 @@ public abstract class ServerPlayerGameModeMixin implements PlayerInteractionMana * @reason */ @Overwrite - public void handleBlockBreakAction(BlockPos blockPos, ServerboundPlayerActionPacket.Action action, Direction direction, int i) { + public void handleBlockBreakAction(BlockPos blockPos, ServerboundPlayerActionPacket.Action action, Direction direction, int i, int j) { if (!this.level.hasChunkAt(blockPos)) { return; } - double d0 = this.player.getX() - (blockPos.getX() + 0.5); - double d2 = this.player.getY() - (blockPos.getY() + 0.5) + 1.5; - double d3 = this.player.getZ() - (blockPos.getZ() + 0.5); - double d4 = d0 * d0 + d2 * d2 + d3 * d3; net.minecraftforge.event.entity.player.PlayerInteractEvent.LeftClickBlock forgeEvent = net.minecraftforge.common.ForgeHooks.onLeftClickBlock(player, blockPos, direction); if (forgeEvent.isCanceled() || (!this.isCreative() && forgeEvent.getUseItem() == net.minecraftforge.eventbus.api.Event.Result.DENY)) { // Restore block and te data - player.connection.send(new ClientboundBlockBreakAckPacket(blockPos, level.getBlockState(blockPos), action, false, "mod canceled")); level.sendBlockUpdated(blockPos, level.getBlockState(blockPos), level.getBlockState(blockPos), 3); return; } if (!this.player.canInteractWith(blockPos, 1)) { - BlockState state; - if (this.player.level.getServer() != null && this.player.chunkPosition().getChessboardDistance(new ChunkPos(blockPos)) < this.player.level.getServer().getPlayerList().getViewDistance()) { - state = this.level.getBlockState(blockPos); - } else { - state = Blocks.AIR.defaultBlockState(); - } - this.player.connection.send(new ClientboundBlockBreakAckPacket(blockPos, state, action, false, "too far")); + this.debugLogging(blockPos, false, j, "too far"); } else if (blockPos.getY() >= i) { - this.player.connection.send(new ClientboundBlockBreakAckPacket(blockPos, this.level.getBlockState(blockPos), action, false, "too high")); + this.player.connection.send(new ClientboundBlockUpdatePacket(blockPos, this.level.getBlockState(blockPos))); + this.debugLogging(blockPos, false, j, "too high"); } else if (action == ServerboundPlayerActionPacket.Action.START_DESTROY_BLOCK) { if (!this.level.mayInteract(this.player, blockPos)) { CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_BLOCK, blockPos, direction, this.player.getInventory().getSelected(), InteractionHand.MAIN_HAND); - this.player.connection.send(new ClientboundBlockBreakAckPacket(blockPos, this.level.getBlockState(blockPos), action, false, "may not interact")); + this.player.connection.send(new ClientboundBlockUpdatePacket(blockPos, this.level.getBlockState(blockPos))); + this.debugLogging(blockPos, false, j, "may not interact"); BlockEntity tileentity = this.level.getBlockEntity(blockPos); if (tileentity != null) { this.player.connection.send(tileentity.getUpdatePacket()); @@ -133,11 +122,12 @@ public abstract class ServerPlayerGameModeMixin implements PlayerInteractionMana return; } if (this.isCreative()) { - this.destroyAndAck(blockPos, action, "creative destroy"); + this.destroyAndAck(blockPos, j, "creative destroy"); return; } if (this.player.blockActionRestricted(this.level, blockPos, this.gameModeForPlayer)) { - this.player.connection.send(new ClientboundBlockBreakAckPacket(blockPos, this.level.getBlockState(blockPos), action, false, "block action restricted")); + this.player.connection.send(new ClientboundBlockUpdatePacket(blockPos, this.level.getBlockState(blockPos))); + this.debugLogging(blockPos, false, j, "block action restricted"); return; } this.destroyProgressStart = this.gameTicks; @@ -173,18 +163,19 @@ public abstract class ServerPlayerGameModeMixin implements PlayerInteractionMana f = 2.0f; } if (!iblockdata.isAir() && f >= 1.0f) { - this.destroyAndAck(blockPos, action, "insta mine"); + this.destroyAndAck(blockPos, j, "insta mine"); } else { if (this.isDestroyingBlock) { - this.player.connection.send(new ClientboundBlockBreakAckPacket(this.destroyPos, this.level.getBlockState(this.destroyPos), ServerboundPlayerActionPacket.Action.START_DESTROY_BLOCK, false, "abort destroying since another started (client insta mine, server disagreed)")); + this.player.connection.send(new ClientboundBlockUpdatePacket(this.destroyPos, this.level.getBlockState(this.destroyPos))); + this.debugLogging(blockPos, false, j, "abort destroying since another started (client insta mine, server disagreed)"); } this.isDestroyingBlock = true; this.destroyPos = blockPos; - int j = (int) (f * 10.0f); - this.level.destroyBlockProgress(this.player.getId(), blockPos, j); - this.player.connection.send(new ClientboundBlockBreakAckPacket(blockPos, this.level.getBlockState(blockPos), action, true, "actual start of destroying")); + int state = (int) (f * 10.0f); + this.level.destroyBlockProgress(this.player.getId(), blockPos, state); + this.debugLogging(blockPos, true, j, "actual start of destroying"); CraftEventFactory.callBlockDamageAbortEvent(this.player, blockPos, this.player.getInventory().getSelected()); - this.lastSentState = j; + this.lastSentState = state; } } else if (action == ServerboundPlayerActionPacket.Action.STOP_DESTROY_BLOCK) { if (blockPos.equals(this.destroyPos)) { @@ -195,7 +186,7 @@ public abstract class ServerPlayerGameModeMixin implements PlayerInteractionMana if (f2 >= 0.7f) { this.isDestroyingBlock = false; this.level.destroyBlockProgress(this.player.getId(), blockPos, -1); - this.destroyAndAck(blockPos, action, "destroyed"); + this.destroyAndAck(blockPos, j, "destroyed"); return; } if (!this.hasDelayedDestroy) { @@ -206,16 +197,16 @@ public abstract class ServerPlayerGameModeMixin implements PlayerInteractionMana } } } - this.player.connection.send(new ClientboundBlockBreakAckPacket(blockPos, this.level.getBlockState(blockPos), action, true, "stopped destroying")); + this.debugLogging(blockPos, true, j, "stopped destroying"); } else if (action == ServerboundPlayerActionPacket.Action.ABORT_DESTROY_BLOCK) { this.isDestroyingBlock = false; if (!Objects.equals(this.destroyPos, blockPos)) { ArclightMod.LOGGER.debug("Mismatch in destroy block pos: " + this.destroyPos + " " + blockPos); this.level.destroyBlockProgress(this.player.getId(), this.destroyPos, -1); - this.player.connection.send(new ClientboundBlockBreakAckPacket(this.destroyPos, this.level.getBlockState(this.destroyPos), action, true, "aborted mismatched destroying")); + this.debugLogging(blockPos, true, j, "aborted mismatched destroying"); } this.level.destroyBlockProgress(this.player.getId(), blockPos, -1); - this.player.connection.send(new ClientboundBlockBreakAckPacket(blockPos, this.level.getBlockState(blockPos), action, true, "aborted destroying")); + this.debugLogging(blockPos, true, j, "aborted destroying"); } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/ExplosionMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/ExplosionMixin.java index 752c0718..5d2354ef 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/ExplosionMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/ExplosionMixin.java @@ -7,12 +7,14 @@ import io.izzel.arclight.common.bridge.core.entity.EntityBridge; import io.izzel.arclight.common.bridge.core.world.ExplosionBridge; import io.izzel.arclight.common.bridge.core.world.WorldBridge; import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import net.minecraft.Util; import net.minecraft.core.BlockPos; import net.minecraft.core.particles.ParticleTypes; import net.minecraft.server.level.ServerLevel; import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; import net.minecraft.util.Mth; +import net.minecraft.util.RandomSource; import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.LivingEntity; @@ -49,11 +51,10 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.util.Collections; +import javax.annotation.Nullable; import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.Random; import java.util.Set; @Mixin(Explosion.class) @@ -63,7 +64,7 @@ public abstract class ExplosionMixin implements ExplosionBridge { @Shadow @Final private Level level; @Shadow @Final private Explosion.BlockInteraction blockInteraction; @Shadow @Mutable @Final private float radius; - @Shadow @Final private List toBlow; + @Shadow @Final private ObjectArrayList toBlow; @Shadow @Final private double x; @Shadow @Final private double y; @Shadow @Final private double z; @@ -75,9 +76,10 @@ public abstract class ExplosionMixin implements ExplosionBridge { @Accessor("radius") public abstract void bridge$setSize(float size); @Accessor("blockInteraction") public abstract Explosion.BlockInteraction bridge$getMode(); @Shadow @Final private boolean fire; - @Shadow @Final private Random random; + @Shadow @Final private RandomSource random; @Shadow private static void addBlockDrops(ObjectArrayList> dropPositionArray, ItemStack stack, BlockPos pos) { } @Shadow @Final private ExplosionDamageCalculator damageCalculator; + @Shadow @Nullable public abstract LivingEntity getSourceMob(); // @formatter:on @@ -245,7 +247,8 @@ public abstract class ExplosionMixin implements ExplosionBridge { if (flag) { ObjectArrayList> objectarraylist = new ObjectArrayList<>(); - Collections.shuffle(this.toBlow, this.level.random); + boolean flag2 = this.getSourceMob() instanceof Player; + Util.shuffle(this.toBlow, this.level.random); float yield = this.callBlockExplodeEvent(); @@ -260,20 +263,20 @@ public abstract class ExplosionMixin implements ExplosionBridge { if (!blockstate.isAir()) { BlockPos blockpos1 = blockpos.immutable(); this.level.getProfiler().push("explosion_blocks"); - if (blockstate.canDropFromExplosion(this.level, blockpos, (Explosion) (Object) this) && this.level instanceof ServerLevel) { + if (blockstate.canDropFromExplosion(this.level, blockpos, (Explosion) (Object) this) && this.level instanceof ServerLevel serverLevel) { BlockEntity tileentity = blockstate.hasBlockEntity() ? this.level.getBlockEntity(blockpos) : null; - LootContext.Builder lootcontext$builder = (new LootContext.Builder((ServerLevel) this.level)).withRandom(this.level.random).withParameter(LootContextParams.ORIGIN, Vec3.atCenterOf(blockpos)).withParameter(LootContextParams.TOOL, ItemStack.EMPTY).withOptionalParameter(LootContextParams.BLOCK_ENTITY, tileentity).withOptionalParameter(LootContextParams.THIS_ENTITY, this.source); + LootContext.Builder lootcontext$builder = new LootContext.Builder(serverLevel).withRandom(this.level.random).withParameter(LootContextParams.ORIGIN, Vec3.atCenterOf(blockpos)).withParameter(LootContextParams.TOOL, ItemStack.EMPTY).withOptionalParameter(LootContextParams.BLOCK_ENTITY, tileentity).withOptionalParameter(LootContextParams.THIS_ENTITY, this.source); if (this.blockInteraction == Explosion.BlockInteraction.DESTROY || yield < 1.0F) { lootcontext$builder.withParameter(LootContextParams.EXPLOSION_RADIUS, 1.0F / yield); } + blockstate.spawnAfterBreak(serverLevel, blockpos, ItemStack.EMPTY, flag2); blockstate.getDrops(lootcontext$builder).forEach((stack) -> { addBlockDrops(objectarraylist, stack, blockpos1); }); } blockstate.onBlockExploded(this.level, blockpos, (Explosion) (Object) this); - block.wasExploded(this.level, blockpos, (Explosion) (Object) this); this.level.getProfiler().pop(); } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/effect/MobEffectUtilMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/effect/MobEffectUtilMixin.java new file mode 100644 index 00000000..b9e0bb81 --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/effect/MobEffectUtilMixin.java @@ -0,0 +1,33 @@ +package io.izzel.arclight.common.mixin.core.world.effect; + +import io.izzel.arclight.common.bridge.core.entity.player.ServerPlayerEntityBridge; +import io.izzel.arclight.common.mod.util.ArclightCaptures; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.effect.MobEffect; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.effect.MobEffectUtil; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.phys.Vec3; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; + +import java.util.List; + +@Mixin(MobEffectUtil.class) +public class MobEffectUtilMixin { + + @Inject(method = "addEffectToPlayersAround", locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", remap = false, target = "Ljava/util/List;forEach(Ljava/util/function/Consumer;)V")) + private static void arclight$pushCause(ServerLevel p_216947_, Entity p_216948_, Vec3 p_216949_, double p_216950_, MobEffectInstance p_216951_, int p_216952_, CallbackInfoReturnable> cir, + MobEffect effect, List players) { + var cause = ArclightCaptures.getEffectCause(); + if (cause != null) { + for (ServerPlayer player : players) { + ((ServerPlayerEntityBridge) player).bridge$pushEffectCause(cause); + } + } + } +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/EntityMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/EntityMixin.java index d4759174..ba6a50ef 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/EntityMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/EntityMixin.java @@ -16,6 +16,7 @@ import net.minecraft.BlockUtil; import net.minecraft.commands.CommandSourceStack; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; +import net.minecraft.core.PositionImpl; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.network.syncher.EntityDataAccessor; @@ -25,8 +26,8 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.sounds.SoundEvent; import net.minecraft.tags.FluidTags; -import net.minecraft.tags.TagKey; import net.minecraft.util.Mth; +import net.minecraft.util.RandomSource; import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityDimensions; @@ -47,7 +48,6 @@ import net.minecraft.world.level.dimension.DimensionType; import net.minecraft.world.level.dimension.LevelStem; import net.minecraft.world.level.gameevent.GameEvent; import net.minecraft.world.level.levelgen.Heightmap; -import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.FluidState; import net.minecraft.world.level.portal.PortalInfo; import net.minecraft.world.level.portal.PortalShape; @@ -99,7 +99,6 @@ import javax.annotation.Nullable; import java.util.Collection; import java.util.List; import java.util.Optional; -import java.util.Random; import java.util.UUID; @SuppressWarnings("ConstantConditions") @@ -135,7 +134,7 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge, @Shadow @Nullable public abstract MinecraftServer getServer(); @Shadow public abstract Vec3 getDeltaMovement(); @Shadow public abstract EntityType getType(); - @Shadow @Final protected Random random; + @Shadow @Final protected RandomSource random; @Shadow public abstract float getBbWidth(); @Shadow public abstract float getBbHeight(); @Shadow public abstract boolean isInvisible(); @@ -216,6 +215,7 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge, @Shadow public abstract void setSharedFlagOnFire(boolean p_146869_); @Shadow public abstract int getMaxAirSupply(); @Shadow public abstract int getAirSupply(); + @Shadow public abstract void gameEvent(GameEvent p_146851_); // @formatter:on private static final int CURRENT_LEVEL = 2; @@ -389,9 +389,9 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge, if ((Object) this instanceof ServerPlayer) this.handleNetherPortal();// CraftBukkit - // Moved up to postTick } - @Redirect(method = "updateFluidHeightAndDoFluidPushing", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/material/FluidState;getFlow(Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/phys/Vec3;")) - private Vec3 arclight$setLava(FluidState instance, BlockGetter level, BlockPos pos, TagKey tag) { - if (tag == FluidTags.LAVA) { + @Redirect(method = "updateFluidHeightAndDoFluidPushing()V", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/material/FluidState;getFlow(Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/phys/Vec3;")) + private Vec3 arclight$setLava(FluidState instance, BlockGetter level, BlockPos pos) { + if (instance.getType().is(FluidTags.LAVA)) { lastLavaContact = pos.immutable(); } return instance.getFlow(level, pos); @@ -830,24 +830,15 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge, return this.boardingCooldown; } - private transient BlockPos arclight$tpPos; + private transient PositionImpl arclight$tpPos; - @Override - public BlockPos internal$capturedPos() { - try { - return arclight$tpPos; - } finally { - arclight$tpPos = null; - } - } - - public Entity teleportTo(ServerLevel world, BlockPos blockPos) { + public Entity teleportTo(ServerLevel world, PositionImpl blockPos) { arclight$tpPos = blockPos; return changeDimension(world); } @Override - public Entity bridge$teleportTo(ServerLevel world, BlockPos blockPos) { + public Entity bridge$teleportTo(ServerLevel world, PositionImpl blockPos) { return teleportTo(world, blockPos); } @@ -866,7 +857,10 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge, return null; } this.level.getProfiler().push("reposition"); - PortalInfo portalinfo = teleporter.getPortalInfo((Entity) (Object) this, server, this::findDimensionEntryPoint); + var bukkitPos = arclight$tpPos; + arclight$tpPos = null; + PortalInfo portalinfo = bukkitPos == null ? teleporter.getPortalInfo((Entity) (Object) this, server, this::findDimensionEntryPoint) + : new PortalInfo(new Vec3(bukkitPos.x(), bukkitPos.y(), bukkitPos.z()), Vec3.ZERO, this.yRot, this.xRot); if (portalinfo == null) { return null; } else { @@ -935,7 +929,7 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge, double d0 = DimensionType.getTeleportationScale(this.level.dimensionType(), world.dimensionType()); BlockPos blockpos1 = worldborder.clampToBounds(this.getX() * d0, this.getY(), this.getZ() * d0); - CraftPortalEvent event = this.callPortalEvent((Entity) (Object) this, world, blockpos1, PlayerTeleportEvent.TeleportCause.NETHER_PORTAL, flag2 ? 16 : 128, 16); + CraftPortalEvent event = this.callPortalEvent((Entity) (Object) this, world, new PositionImpl(blockpos1.getX(), blockpos1.getY(), blockpos1.getZ()), PlayerTeleportEvent.TeleportCause.NETHER_PORTAL, flag2 ? 16 : 128, 16); if (event == null) { return null; } @@ -969,23 +963,22 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge, blockpos = world.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, world.getSharedSpawnPos()); } - CraftPortalEvent event = this.callPortalEvent((Entity) (Object) this, world, blockpos, PlayerTeleportEvent.TeleportCause.END_PORTAL, 0, 0); + CraftPortalEvent event = this.callPortalEvent((Entity) (Object) this, world, new PositionImpl(blockpos.getX() + 0.5D, blockpos.getY(), blockpos.getZ() + 0.5D), PlayerTeleportEvent.TeleportCause.END_PORTAL, 0, 0); if (event == null) { return null; } - blockpos = new BlockPos(event.getTo().getX(), event.getTo().getY(), event.getTo().getZ()); - PortalInfo portalInfo = new PortalInfo(new Vec3((double) blockpos.getX() + 0.5D, blockpos.getY(), (double) blockpos.getZ() + 0.5D), this.getDeltaMovement(), this.getYRot(), this.getXRot()); + PortalInfo portalInfo = new PortalInfo(new Vec3(event.getTo().getX(), event.getTo().getY(), event.getTo().getZ()), this.getDeltaMovement(), this.getYRot(), this.getXRot()); ((PortalInfoBridge) portalInfo).bridge$setWorld(((CraftWorld) event.getTo().getWorld()).getHandle()); ((PortalInfoBridge) portalInfo).bridge$setPortalEventInfo(event); return portalInfo; } } - protected CraftPortalEvent callPortalEvent(Entity entity, ServerLevel exitWorldServer, BlockPos exitPosition, PlayerTeleportEvent.TeleportCause cause, int searchRadius, int creationRadius) { + protected CraftPortalEvent callPortalEvent(Entity entity, ServerLevel exitWorldServer, PositionImpl exitPosition, PlayerTeleportEvent.TeleportCause cause, int searchRadius, int creationRadius) { CraftEntity bukkitEntity = ((EntityBridge) entity).bridge$getBukkitEntity(); Location enter = bukkitEntity.getLocation(); - Location exit = new Location(((WorldBridge) exitWorldServer).bridge$getWorld(), exitPosition.getX(), exitPosition.getY(), exitPosition.getZ()); + Location exit = new Location(((WorldBridge) exitWorldServer).bridge$getWorld(), exitPosition.x(), exitPosition.y(), exitPosition.z()); EntityPortalEvent event = new EntityPortalEvent(bukkitEntity, enter, exit, searchRadius); Bukkit.getPluginManager().callEvent(event); if (event.isCancelled() || event.getTo() == null || event.getTo().getWorld() == null || !entity.isAlive()) { diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/LivingEntityMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/LivingEntityMixin.java index c5c9fa8f..ad970be7 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/LivingEntityMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/LivingEntityMixin.java @@ -23,6 +23,7 @@ import net.minecraft.server.level.ServerPlayer; import net.minecraft.sounds.SoundEvent; import net.minecraft.stats.Stats; import net.minecraft.util.Mth; +import net.minecraft.util.RandomSource; import net.minecraft.world.InteractionHand; import net.minecraft.world.damagesource.CombatTracker; import net.minecraft.world.damagesource.DamageSource; @@ -41,6 +42,7 @@ import net.minecraft.world.entity.ai.attributes.AttributeInstance; import net.minecraft.world.entity.ai.attributes.AttributeMap; import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.animal.Animal; +import net.minecraft.world.entity.boss.enderdragon.EnderDragon; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; @@ -51,7 +53,7 @@ import net.minecraft.world.level.gameevent.GameEvent; import net.minecraftforge.common.ForgeHooks; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.ForgeEventFactory; -import net.minecraftforge.event.entity.living.PotionEvent; +import net.minecraftforge.event.entity.living.MobEffectEvent; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.craftbukkit.v.attribute.CraftAttributeMap; @@ -86,7 +88,6 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.Random; import java.util.Set; import java.util.UUID; import java.util.function.Consumer; @@ -101,7 +102,6 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt @Shadow public abstract float getHealth(); @Shadow public abstract void setHealth(float health); @Shadow public abstract float getYHeadRot(); - @Shadow protected abstract int getExperienceReward(net.minecraft.world.entity.player.Player player); @Shadow protected int lastHurtByPlayerTime; @Shadow protected abstract boolean shouldDropExperience(); @Shadow protected abstract boolean isAlwaysExperienceDropper(); @@ -157,7 +157,7 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt @Shadow @Nullable public LivingEntity lastHurtByMob; @Shadow public CombatTracker combatTracker; @Shadow public abstract ItemStack getOffhandItem(); - @Shadow public abstract Random getRandom(); + @Shadow public abstract RandomSource getRandom(); @Shadow public abstract Optional getSleepingPos(); @Shadow @Final private static EntityDataAccessor DATA_EFFECT_COLOR_ID; @Shadow @Final private static EntityDataAccessor DATA_EFFECT_AMBIENCE_ID; @@ -176,11 +176,15 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt @Shadow protected abstract void onEffectUpdated(MobEffectInstance p_147192_, boolean p_147193_, @org.jetbrains.annotations.Nullable Entity p_147194_); @Shadow protected abstract void onEffectAdded(MobEffectInstance p_147190_, @org.jetbrains.annotations.Nullable Entity p_147191_); @Shadow public abstract void knockback(double p_147241_, double p_147242_, double p_147243_); - @Shadow protected abstract void equipEventAndSound(ItemStack p_147219_); @Shadow public abstract boolean canAttack(LivingEntity p_21171_); @Shadow public abstract boolean hasLineOfSight(Entity p_147185_); @Shadow protected abstract void hurtHelmet(DamageSource p_147213_, float p_147214_); @Shadow public abstract void stopUsingItem(); + @Shadow protected abstract void playEquipSound(ItemStack p_217042_); + @Shadow protected abstract boolean doesEmitEquipEvent(EquipmentSlot p_217035_); + @Shadow protected abstract void verifyEquippedItem(ItemStack p_181123_); + @Shadow public abstract boolean wasExperienceConsumed(); + @Shadow public abstract int getExperienceReward(); // @formatter:on public int expToDrop; @@ -231,8 +235,8 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt @Overwrite protected void dropExperience() { // if (!this.world.isRemote && (this.isPlayer() || this.recentlyHit > 0 && this.canDropLoot() && this.world.getGameRules().getBoolean(GameRules.DO_MOB_LOOT))) { - if (true) { - int reward = ForgeEventFactory.getExperienceDrop((LivingEntity)(Object) this, this.lastHurtByPlayer, this.expToDrop); + if (!((Object) this instanceof EnderDragon)) { + int reward = ForgeEventFactory.getExperienceDrop((LivingEntity) (Object) this, this.lastHurtByPlayer, this.expToDrop); ExperienceOrb.award((ServerLevel) this.level, this.position(), reward); bridge$setExpToDrop(0); } @@ -257,7 +261,7 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt if (!effectinstance.tick((LivingEntity) (Object) this, () -> { onEffectUpdated(effectinstance, true, null); })) { - if (!this.level.isClientSide && !MinecraftForge.EVENT_BUS.post(new PotionEvent.PotionExpiryEvent((LivingEntity) (Object) this, effectinstance))) { + if (!this.level.isClientSide && !MinecraftForge.EVENT_BUS.post(new MobEffectEvent.Expired((LivingEntity) (Object) this, effectinstance))) { EntityPotionEffectEvent event = CraftEventFactory.callEntityPotionEffectChangeEvent((LivingEntity) (Object) this, effectinstance, null, EntityPotionEffectEvent.Cause.EXPIRATION); if (event.isCancelled()) { @@ -345,7 +349,7 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt return false; } - MinecraftForge.EVENT_BUS.post(new PotionEvent.PotionAddedEvent((LivingEntity) (Object) this, effectinstance, effectInstanceIn, entity)); + MinecraftForge.EVENT_BUS.post(new MobEffectEvent.Added((LivingEntity) (Object) this, effectinstance, effectInstanceIn, entity)); if (effectinstance == null) { this.activeEffects.put(effectInstanceIn.getEffect(), effectInstanceIn); this.onEffectAdded(effectInstanceIn, entity); @@ -398,8 +402,8 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt } public int getExpReward() { - if (!this.level.isClientSide && (this.lastHurtByPlayerTime > 0 || this.isAlwaysExperienceDropper()) && this.shouldDropExperience() && this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { - int exp = this.getExperienceReward(this.lastHurtByPlayer); + if (this.level instanceof ServerLevel && !this.wasExperienceConsumed() && (this.isAlwaysExperienceDropper() || this.lastHurtByPlayerTime > 0 && this.shouldDropExperience() && this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT))) { + int exp = this.getExperienceReward(); return ForgeEventFactory.getExperienceDrop((LivingEntity) (Object) this, this.lastHurtByPlayer, exp); } else { return 0; @@ -796,7 +800,7 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt if (!human) { this.setAbsorptionAmount(this.getAbsorptionAmount() - f); } - this.gameEvent(GameEvent.ENTITY_DAMAGED, damagesource.getEntity()); + this.gameEvent(GameEvent.ENTITY_DAMAGE, damagesource.getEntity()); return true; } else { @@ -1102,14 +1106,23 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt this.setItemSlot(slotIn, stack, silent); } - protected void equipEventAndSound(ItemStack stack, boolean silent) { - if (!silent) { - this.equipEventAndSound(stack); + protected void equipEventAndSound(EquipmentSlot slot, ItemStack oldItem, ItemStack newItem, boolean silent) { + boolean flag = oldItem.isEmpty() && newItem.isEmpty(); + + if (!flag && !ItemStack.isSameIgnoreDurability(oldItem, newItem) && !this.firstTick) { + if (slot.getType() == EquipmentSlot.Type.ARMOR && !silent) { + this.playEquipSound(newItem); + } + + if (this.doesEmitEquipEvent(slot)) { + this.gameEvent(GameEvent.EQUIP); + } + } } @Override - public void bridge$playEquipSound(ItemStack stack, boolean silent) { - this.equipEventAndSound(stack, silent); + public void bridge$playEquipSound(EquipmentSlot slot, ItemStack oldItem, ItemStack newItem, boolean silent) { + this.equipEventAndSound(slot, oldItem, newItem, silent); } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/MobMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/MobMixin.java index 60f4eea5..fe159380 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/MobMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/MobMixin.java @@ -227,7 +227,6 @@ public abstract class MobMixin extends LivingEntityMixin implements MobEntityBri } this.setItemSlotAndDropWhenKilled(equipmentslottype, stack); - this.equipEventAndSound(stack); return true; } else { return false; diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/ai/attributes/RangedAttributeMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/ai/attributes/RangedAttributeMixin.java deleted file mode 100644 index 505f9369..00000000 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/ai/attributes/RangedAttributeMixin.java +++ /dev/null @@ -1,29 +0,0 @@ -package io.izzel.arclight.common.mixin.core.world.entity.ai.attributes; - -import io.izzel.arclight.common.bridge.core.entity.ai.attributes.RangedAttributeBridge; -import net.minecraft.world.entity.ai.attributes.Attribute; -import net.minecraft.world.entity.ai.attributes.RangedAttribute; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(RangedAttribute.class) -public abstract class RangedAttributeMixin extends Attribute implements RangedAttributeBridge { - - // @formatter:off - @Override @Accessor("maxValue") public abstract void bridge$setMaximumValue(double maximumValue); - // @formatter:on - - protected RangedAttributeMixin(String attributeName, double defaultValue) { - super(attributeName, defaultValue); - } - - @Inject(method = "sanitizeValue", cancellable = true, at = @At("HEAD")) - private void arclight$notNan(double value, CallbackInfoReturnable cir) { - if (Double.isNaN(value)) { - cir.setReturnValue(this.getDefaultValue()); - } - } -} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/ai/behavior/AssignProfessionFromJobSiteMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/ai/behavior/AssignProfessionFromJobSiteMixin.java index 56be5e85..a3e61be9 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/ai/behavior/AssignProfessionFromJobSiteMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/ai/behavior/AssignProfessionFromJobSiteMixin.java @@ -36,7 +36,7 @@ public class AssignProfessionFromJobSiteMixin { return world.getPoiManager().getType(globalpos.pos()); }).flatMap((poiType) -> { return Registry.VILLAGER_PROFESSION.stream().filter((profession) -> { - return profession.getJobPoiType() == poiType; + return profession.heldJobSite().test(poiType); }).findFirst(); }).ifPresent((profession) -> { VillagerCareerChangeEvent event = CraftEventFactory.callVillagerCareerChangeEvent(entityIn, CraftVillager.nmsToBukkitProfession(profession), VillagerCareerChangeEvent.ChangeReason.EMPLOYED); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/ai/behavior/StartAttackingMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/ai/behavior/StartAttackingMixin.java index 9c879011..6ea8fdc7 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/ai/behavior/StartAttackingMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/ai/behavior/StartAttackingMixin.java @@ -19,7 +19,7 @@ public class StartAttackingMixin { * @reason */ @Overwrite - private void setAttackTarget(E mob, LivingEntity livingEntity) { + public static void setAttackTarget(E mob, LivingEntity livingEntity) { EntityTargetEvent event = CraftEventFactory.callEntityTargetLivingEvent(mob, livingEntity, (livingEntity instanceof ServerPlayer) ? EntityTargetEvent.TargetReason.CLOSEST_PLAYER : EntityTargetEvent.TargetReason.CLOSEST_ENTITY); if (event.isCancelled()) { return; diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/ai/brain/BrainUtilMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/ai/brain/BrainUtilMixin.java index 3a402fb5..9da259b8 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/ai/brain/BrainUtilMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/ai/brain/BrainUtilMixin.java @@ -18,14 +18,14 @@ import org.spongepowered.asm.mixin.injection.callback.LocalCapture; @Mixin(BehaviorUtils.class) public class BrainUtilMixin { - @Inject(method = "throwItem", cancellable = true, at = @At("HEAD")) - private static void arclight$noEmptyLoot(LivingEntity entity, ItemStack stack, Vec3 offset, CallbackInfo ci) { + @Inject(method = "throwItem(Lnet/minecraft/world/entity/LivingEntity;Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/phys/Vec3;Lnet/minecraft/world/phys/Vec3;F)V", cancellable = true, at = @At("HEAD")) + private static void arclight$noEmptyLoot(LivingEntity p_217134_, ItemStack stack, Vec3 p_217136_, Vec3 p_217137_, float p_217138_, CallbackInfo ci) { if (stack.isEmpty()) ci.cancel(); } - @Inject(method = "throwItem", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, + @Inject(method = "throwItem(Lnet/minecraft/world/entity/LivingEntity;Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/phys/Vec3;Lnet/minecraft/world/phys/Vec3;F)V", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;addFreshEntity(Lnet/minecraft/world/entity/Entity;)Z")) - private static void arclight$entityDropItem(LivingEntity entity, ItemStack stack, Vec3 offset, CallbackInfo ci, double d, ItemEntity itemEntity) { + private static void arclight$entityDropItem(LivingEntity entity, ItemStack p_217135_, Vec3 p_217136_, Vec3 p_217137_, float p_217138_, CallbackInfo ci, double d0, ItemEntity itemEntity) { EntityDropItemEvent event = new EntityDropItemEvent(((EntityBridge) entity).bridge$getBukkitEntity(), (Item) ((EntityBridge) itemEntity).bridge$getBukkitEntity()); Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) { diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/animal/BucketableMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/animal/BucketableMixin.java index e8d1c9e1..af2cda2e 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/animal/BucketableMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/animal/BucketableMixin.java @@ -1,7 +1,7 @@ package io.izzel.arclight.common.mixin.core.world.entity.animal; import net.minecraft.advancements.CriteriaTriggers; -import net.minecraft.network.protocol.game.ClientboundAddMobPacket; +import net.minecraft.network.protocol.game.ClientboundAddEntityPacket; import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.InteractionHand; @@ -41,7 +41,7 @@ public interface BucketableMixin { itemstack1 = CraftItemStack.asNMSCopy(event.getEntityBucket()); if (event.isCancelled()) { player.containerMenu.sendAllDataToRemote(); // We need to update inventory to resync client's bucket - ((ServerPlayer) player).connection.send(new ClientboundAddMobPacket(entity)); // We need to play out these packets as the client assumes the fish is gone + ((ServerPlayer) player).connection.send(new ClientboundAddEntityPacket(entity)); // We need to play out these packets as the client assumes the fish is gone ((ServerPlayer) player).connection.send(new ClientboundSetEntityDataPacket(entity.getId(), entity.getEntityData(), true)); // Need to send data such as the display name to client return Optional.of(InteractionResult.FAIL); } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/animal/Fox_EatBerriesGoalMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/animal/Fox_EatBerriesGoalMixin.java index d0adb5d7..eb433c45 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/animal/Fox_EatBerriesGoalMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/animal/Fox_EatBerriesGoalMixin.java @@ -24,7 +24,7 @@ public abstract class Fox_EatBerriesGoalMixin extends MoveToBlockGoal { super(creature, speedIn, length); } - @Inject(method = "pickSweetBerries", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", remap = false, target = "Ljava/util/Random;nextInt(I)I")) + @Inject(method = "pickSweetBerries", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/util/RandomSource;nextInt(I)I")) private void arclight$eatBerry(BlockState state, CallbackInfo ci) { if (CraftEventFactory.callEntityChangeBlockEvent(outerThis, this.blockPos, state.setValue(SweetBerryBushBlock.AGE, 1)).isCancelled()) { ci.cancel(); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/animal/frog/TadpoleMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/animal/frog/TadpoleMixin.java new file mode 100644 index 00000000..4c007b14 --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/animal/frog/TadpoleMixin.java @@ -0,0 +1,32 @@ +package io.izzel.arclight.common.mixin.core.world.entity.animal.frog; + +import io.izzel.arclight.common.bridge.core.world.server.ServerWorldBridge; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.animal.frog.Frog; +import net.minecraft.world.entity.animal.frog.Tadpole; +import org.bukkit.craftbukkit.v.event.CraftEventFactory; +import org.bukkit.event.entity.CreatureSpawnEvent; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; + +@Mixin(Tadpole.class) +public abstract class TadpoleMixin { + + // @formatter:off + @Shadow protected abstract void setAge(int p_218711_); + // @formatter:on + + @Inject(method = "ageUp()V", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/animal/frog/Tadpole;playSound(Lnet/minecraft/sounds/SoundEvent;FF)V")) + private void arclight$transform(CallbackInfo ci, ServerLevel serverLevel, Frog frog) { + if (CraftEventFactory.callEntityTransformEvent((Tadpole) (Object) this, frog, org.bukkit.event.entity.EntityTransformEvent.TransformReason.METAMORPHOSIS).isCancelled()) { + this.setAge(0); // Sets the age to 0 for avoid a loop if the event is canceled + ci.cancel(); + } else { + ((ServerWorldBridge) serverLevel).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.METAMORPHOSIS); + } + } +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/animal/goat/GoatMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/animal/goat/GoatMixin.java new file mode 100644 index 00000000..c467e686 --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/animal/goat/GoatMixin.java @@ -0,0 +1,31 @@ +package io.izzel.arclight.common.mixin.core.world.entity.animal.goat; + +import io.izzel.arclight.common.mixin.core.world.entity.animal.AnimalMixin; +import io.izzel.arclight.mixin.Eject; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.animal.goat.Goat; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.ItemUtils; +import net.minecraft.world.item.Items; +import org.bukkit.craftbukkit.v.event.CraftEventFactory; +import org.bukkit.craftbukkit.v.inventory.CraftItemStack; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(Goat.class) +public abstract class GoatMixin extends AnimalMixin { + + @Eject(method = "mobInteract", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/ItemUtils;createFilledResult(Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/world/item/ItemStack;)Lnet/minecraft/world/item/ItemStack;")) + private ItemStack arclight$bucketFill(ItemStack handItem, Player player, ItemStack p_41816_, CallbackInfoReturnable cir) { + org.bukkit.event.player.PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) player.level, player, this.blockPosition(), this.blockPosition(), null, handItem, Items.MILK_BUCKET); + + if (event.isCancelled()) { + cir.setReturnValue(InteractionResult.PASS); + return null; + } + return ItemUtils.createFilledResult(handItem, player, CraftItemStack.asNMSCopy(event.getItemStack())); + } +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/boss/enderdragon/EnderDragonMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/boss/enderdragon/EnderDragonMixin.java index 2822666b..5ce8d7a2 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/boss/enderdragon/EnderDragonMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/boss/enderdragon/EnderDragonMixin.java @@ -10,10 +10,11 @@ import net.minecraft.world.entity.boss.enderdragon.phases.DragonPhaseInstance; import net.minecraft.world.entity.boss.enderdragon.phases.EnderDragonPhase; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Explosion; +import net.minecraft.world.level.GameRules; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.material.Material; +import net.minecraft.world.level.dimension.end.EndDragonFight; import net.minecraft.world.level.storage.loot.LootContext; import net.minecraft.world.level.storage.loot.parameters.LootContextParams; import net.minecraft.world.phys.AABB; @@ -22,17 +23,22 @@ import org.bukkit.Bukkit; import org.bukkit.craftbukkit.v.block.CraftBlock; import org.bukkit.event.entity.EntityExplodeEvent; import org.bukkit.event.entity.EntityRegainHealthEvent; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; +import javax.annotation.Nullable; import java.util.ArrayList; import java.util.List; @Mixin(EnderDragon.class) public abstract class EnderDragonMixin extends MobMixin { + @Shadow @Final @Nullable private EndDragonFight dragonFight; + private Explosion explosionSource = new Explosion(null, (EnderDragon) (Object) this, null, null, Double.NaN, Double.NaN, Double.NaN, Float.NaN, true, Explosion.BlockInteraction.DESTROY); @Redirect(method = "aiStep", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/boss/enderdragon/phases/DragonPhaseInstance;getFlyTargetLocation()Lnet/minecraft/world/phys/Vec3;")) @@ -71,7 +77,7 @@ public abstract class EnderDragonMixin extends MobMixin { for (int i3 = k; i3 <= j2; ++i3) { final BlockPos blockposition = new BlockPos(k2, l2, i3); final BlockState iblockdata = this.level.getBlockState(blockposition); - if (!iblockdata.isAir() && iblockdata.getMaterial() != Material.FIRE) { + if (!iblockdata.isAir() && !iblockdata.is(BlockTags.DRAGON_TRANSPARENT)) { if (net.minecraftforge.common.ForgeHooks.canEntityDestroy(this.level, blockposition, (EnderDragon) (Object) this) && !iblockdata.is(BlockTags.DRAGON_IMMUNE)) { flag2 = true; destroyedBlocks.add(CraftBlock.at(this.level, blockposition)); @@ -106,11 +112,11 @@ public abstract class EnderDragonMixin extends MobMixin { final net.minecraft.world.level.block.Block nmsBlock = craftBlock.getNMS().getBlock(); if (nmsBlock.dropFromExplosion(this.explosionSource)) { BlockEntity tileentity = craftBlock.getNMS().hasBlockEntity() ? this.level.getBlockEntity(blockposition2) : null; - LootContext.Builder loottableinfo_builder = new LootContext.Builder((ServerLevel)this.level).withRandom(this.level.random).withParameter(LootContextParams.ORIGIN, Vec3.atCenterOf(blockposition2)).withParameter(LootContextParams.TOOL, ItemStack.EMPTY).withParameter(LootContextParams.EXPLOSION_RADIUS, 1.0f / event.getYield()).withOptionalParameter(LootContextParams.BLOCK_ENTITY, tileentity); + LootContext.Builder loottableinfo_builder = new LootContext.Builder((ServerLevel) this.level).withRandom(this.level.random).withParameter(LootContextParams.ORIGIN, Vec3.atCenterOf(blockposition2)).withParameter(LootContextParams.TOOL, ItemStack.EMPTY).withParameter(LootContextParams.EXPLOSION_RADIUS, 1.0f / event.getYield()).withOptionalParameter(LootContextParams.BLOCK_ENTITY, tileentity); for (ItemStack stack : craftBlock.getNMS().getDrops(loottableinfo_builder)) { Block.popResource(this.level, blockposition2, stack); } - craftBlock.getNMS().spawnAfterBreak((ServerLevel) this.level, blockposition2, ItemStack.EMPTY); + craftBlock.getNMS().spawnAfterBreak((ServerLevel) this.level, blockposition2, ItemStack.EMPTY, false); // net.minecraft.block.Block.spawnDrops(craftBlock.getNMS(), loottableinfo_builder); } nmsBlock.wasExploded(this.level, blockposition2, this.explosionSource); @@ -124,4 +130,17 @@ public abstract class EnderDragonMixin extends MobMixin { return flag; } + // TODO FIXME: exp patch for end dragon + @Override + public int getExpReward() { + // CraftBukkit - Moved from #tickDeath method + boolean flag = this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT); + short short0 = 500; + + if (this.dragonFight != null && !this.dragonFight.hasPreviouslyKilledDragon()) { + short0 = 12000; + } + + return flag ? short0 : 0; + } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/decoration/ArmorStandMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/decoration/ArmorStandMixin.java index 94613e87..8affe156 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/decoration/ArmorStandMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/decoration/ArmorStandMixin.java @@ -162,14 +162,8 @@ public abstract class ArmorStandMixin extends LivingEntityMixin { @Override public void setItemSlot(net.minecraft.world.entity.EquipmentSlot slotIn, ItemStack stack, boolean silent) { switch (slotIn.getType()) { - case HAND -> { - this.bridge$playEquipSound(stack, silent); - this.handItems.set(slotIn.getIndex(), stack); - } - case ARMOR -> { - this.bridge$playEquipSound(stack, silent); - this.armorItems.set(slotIn.getIndex(), stack); - } + case HAND -> this.bridge$playEquipSound(slotIn, this.handItems.set(slotIn.getIndex(), stack), stack, silent); + case ARMOR -> this.bridge$playEquipSound(slotIn, this.armorItems.set(slotIn.getIndex(), stack), stack, silent); } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/decoration/ItemFrameMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/decoration/ItemFrameMixin.java index 8d3de8ff..8752829b 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/decoration/ItemFrameMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/decoration/ItemFrameMixin.java @@ -22,7 +22,10 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(ItemFrame.class) public abstract class ItemFrameMixin extends HangingEntityMixin { + // @formatter:off @Shadow @Final private static EntityDataAccessor DATA_ITEM; + @Shadow protected abstract void onItemChanged(ItemStack p_218866_); + // @formatter:on @Inject(method = "hurt", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/decoration/ItemFrame;dropItem(Lnet/minecraft/world/entity/Entity;Z)V")) private void arclight$damageNonLiving(DamageSource source, float amount, CallbackInfoReturnable cir) { @@ -35,8 +38,8 @@ public abstract class ItemFrameMixin extends HangingEntityMixin { if (!itemstack.isEmpty()) { itemstack = itemstack.copy(); itemstack.setCount(1); - itemstack.setEntityRepresentation((ItemFrame) (Object) this); } + this.onItemChanged(itemstack); this.getEntityData().set(DATA_ITEM, itemstack); if (!itemstack.isEmpty() && playSound) { this.playSound(SoundEvents.ITEM_FRAME_ADD_ITEM, 1.0f, 1.0f); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/monster/ElderGuardianMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/monster/ElderGuardianMixin.java index b20df59a..b8db334e 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/monster/ElderGuardianMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/monster/ElderGuardianMixin.java @@ -1,22 +1,19 @@ package io.izzel.arclight.common.mixin.core.world.entity.monster; -import io.izzel.arclight.common.bridge.core.entity.player.ServerPlayerEntityBridge; import io.izzel.arclight.common.mixin.core.world.entity.PathfinderMobMixin; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.effect.MobEffectInstance; -import net.minecraft.world.entity.Entity; +import io.izzel.arclight.common.mod.util.ArclightCaptures; import net.minecraft.world.entity.monster.ElderGuardian; import org.bukkit.event.entity.EntityPotionEffectEvent; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(ElderGuardian.class) public abstract class ElderGuardianMixin extends PathfinderMobMixin { - @Redirect(method = "customServerAiStep", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerPlayer;addEffect(Lnet/minecraft/world/effect/MobEffectInstance;Lnet/minecraft/world/entity/Entity;)Z")) - private boolean arclight$potionReason(ServerPlayer playerEntity, MobEffectInstance effectInstanceIn, Entity entity) { - ((ServerPlayerEntityBridge) playerEntity).bridge$pushEffectCause(EntityPotionEffectEvent.Cause.ATTACK); - return playerEntity.addEffect(effectInstanceIn); + @Inject(method = "customServerAiStep", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/effect/MobEffectUtil;addEffectToPlayersAround(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/phys/Vec3;DLnet/minecraft/world/effect/MobEffectInstance;I)Ljava/util/List;")) + private void arclight$potionReason(CallbackInfo ci) { + ArclightCaptures.captureEffectCause(EntityPotionEffectEvent.Cause.ATTACK); } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/monster/EnderMan_EndermanLeaveBlockGoalMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/monster/EnderMan_EndermanLeaveBlockGoalMixin.java index 7b8d67fe..f50d808f 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/monster/EnderMan_EndermanLeaveBlockGoalMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/monster/EnderMan_EndermanLeaveBlockGoalMixin.java @@ -1,6 +1,7 @@ package io.izzel.arclight.common.mixin.core.world.entity.monster; import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; import net.minecraft.world.entity.monster.EnderMan; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.state.BlockState; @@ -13,8 +14,6 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; -import java.util.Random; - @Mixin(targets = "net.minecraft.world.entity.monster.EnderMan$EndermanLeaveBlockGoal") public class EnderMan_EndermanLeaveBlockGoalMixin { @@ -24,7 +23,7 @@ public class EnderMan_EndermanLeaveBlockGoalMixin { @Inject(method = "tick", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, 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 void arclight$entityChangeBlock(CallbackInfo ci, Random random, Level world, int i, int j, int k, BlockPos blockPos, BlockState blockState, BlockPos blockPos1, BlockState blockState1, BlockState blockState2) { + private void arclight$entityChangeBlock(CallbackInfo ci, RandomSource random, Level world, int i, int j, int k, BlockPos blockPos, BlockState blockState, BlockPos blockPos1, BlockState blockState1, BlockState blockState2) { if (CraftEventFactory.callEntityChangeBlockEvent(this.enderman, blockPos, blockState2).isCancelled()) { ci.cancel(); } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/monster/EnderMan_EndermanTakeBlockGoalMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/monster/EnderMan_EndermanTakeBlockGoalMixin.java index 0690533a..e62fdb43 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/monster/EnderMan_EndermanTakeBlockGoalMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/monster/EnderMan_EndermanTakeBlockGoalMixin.java @@ -1,6 +1,7 @@ package io.izzel.arclight.common.mixin.core.world.entity.monster; import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; import net.minecraft.world.entity.monster.EnderMan; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Blocks; @@ -13,8 +14,6 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; -import java.util.Random; - @Mixin(targets = "net.minecraft.world.entity.monster.EnderMan$EndermanTakeBlockGoal") public class EnderMan_EndermanTakeBlockGoalMixin { @@ -24,7 +23,7 @@ public class EnderMan_EndermanTakeBlockGoalMixin { @Inject(method = "tick", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/monster/EnderMan;setCarriedBlock(Lnet/minecraft/world/level/block/state/BlockState;)V")) - private void arclight$entityChangeBlock(CallbackInfo ci, Random random, Level world, int i, int j, int k, BlockPos blockPos) { + private void arclight$entityChangeBlock(CallbackInfo ci, RandomSource random, Level world, int i, int j, int k, BlockPos blockPos) { if (CraftEventFactory.callEntityChangeBlockEvent(this.enderman, blockPos, Blocks.AIR.defaultBlockState()).isCancelled()) { ci.cancel(); } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/monster/ShulkerMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/monster/ShulkerMixin.java index 8e3eac7b..1fba4f4b 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/monster/ShulkerMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/monster/ShulkerMixin.java @@ -7,7 +7,9 @@ import net.minecraft.core.Direction; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.sounds.SoundEvents; import net.minecraft.util.Mth; +import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.monster.Shulker; +import net.minecraft.world.level.gameevent.GameEvent; import net.minecraft.world.phys.AABB; import net.minecraftforge.event.ForgeEventFactory; import org.bukkit.Bukkit; @@ -64,6 +66,7 @@ public abstract class ShulkerMixin extends PathfinderMobMixin { this.setAttachFace(direction); this.playSound(SoundEvents.SHULKER_TELEPORT, 1.0F, 1.0F); this.setPos((double) blockpos1.getX() + 0.5D, blockpos1.getY(), (double) blockpos1.getZ() + 0.5D); + this.level.gameEvent(GameEvent.TELEPORT, blockpos, GameEvent.Context.of((Entity) (Object) this)); this.entityData.set(DATA_PEEK_ID, (byte) 0); this.setTarget(null); return true; diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/monster/Silverfish_WakeUpFriendsGoalMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/monster/Silverfish_WakeUpFriendsGoalMixin.java index f4f898b4..f3e024cb 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/monster/Silverfish_WakeUpFriendsGoalMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/monster/Silverfish_WakeUpFriendsGoalMixin.java @@ -2,6 +2,7 @@ package io.izzel.arclight.common.mixin.core.world.entity.monster; import io.izzel.arclight.api.ArclightVersion; import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; import net.minecraft.world.entity.ai.goal.Goal; import net.minecraft.world.entity.monster.Silverfish; import net.minecraft.world.level.Level; @@ -16,8 +17,6 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Shadow; -import java.util.Random; - @Mixin(targets = "net.minecraft.world.entity.monster.Silverfish$SilverfishWakeUpFriendsGoal") public abstract class Silverfish_WakeUpFriendsGoalMixin extends Goal { @@ -33,7 +32,7 @@ public abstract class Silverfish_WakeUpFriendsGoalMixin extends Goal { --this.lookForFriends; if (this.lookForFriends <= 0) { Level world = this.silverfish.level; - Random random = this.silverfish.getRandom(); + RandomSource random = this.silverfish.getRandom(); BlockPos blockpos = this.silverfish.blockPosition(); for (int i = 0; i <= 5 && i >= -5; i = (i <= 0 ? 1 : 0) - i) { diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/monster/StriderMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/monster/StriderMixin.java new file mode 100644 index 00000000..6cf1383c --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/monster/StriderMixin.java @@ -0,0 +1,20 @@ +package io.izzel.arclight.common.mixin.core.world.entity.monster; + +import net.minecraft.world.entity.monster.Strider; +import org.bukkit.craftbukkit.v.event.CraftEventFactory; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(Strider.class) +public class StriderMixin { + + @Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/monster/Strider;setSuffocating(Z)V")) + private void arclight$temperatureChange(Strider instance, boolean flag) { + if (flag ^ instance.isSuffocating()) { + if (CraftEventFactory.callStriderTemperatureChangeEvent(instance, flag)) { + instance.setSuffocating(flag); + } + } + } +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/monster/ZombieMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/monster/ZombieMixin.java index 3b33442a..5dc7ee9b 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/monster/ZombieMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/monster/ZombieMixin.java @@ -68,13 +68,13 @@ public abstract class ZombieMixin extends PathfinderMobMixin { } } - @Eject(method = "killed", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/npc/Villager;convertTo(Lnet/minecraft/world/entity/EntityType;Z)Lnet/minecraft/world/entity/Mob;")) - private T arclight$transform(Villager villagerEntity, EntityType entityType, boolean flag, CallbackInfo ci) { + @Eject(method = "wasKilled", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/npc/Villager;convertTo(Lnet/minecraft/world/entity/EntityType;Z)Lnet/minecraft/world/entity/Mob;")) + private T arclight$transform(Villager villagerEntity, EntityType entityType, boolean flag, CallbackInfoReturnable cir) { ((WorldBridge) villagerEntity.level).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.INFECTION); ((MobEntityBridge) villagerEntity).bridge$pushTransformReason(EntityTransformEvent.TransformReason.INFECTION); T t = villagerEntity.convertTo(entityType, flag); if (t == null) { - ci.cancel(); + cir.setReturnValue(false); } return t; } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/monster/warden/WardenMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/monster/warden/WardenMixin.java new file mode 100644 index 00000000..5dc86c49 --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/monster/warden/WardenMixin.java @@ -0,0 +1,21 @@ +package io.izzel.arclight.common.mixin.core.world.entity.monster.warden; + +import io.izzel.arclight.common.mod.util.ArclightCaptures; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.monster.warden.Warden; +import net.minecraft.world.phys.Vec3; +import org.bukkit.event.entity.EntityPotionEffectEvent; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(Warden.class) +public class WardenMixin { + + @Inject(method = "applyDarknessAround", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/effect/MobEffectUtil;addEffectToPlayersAround(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/phys/Vec3;DLnet/minecraft/world/effect/MobEffectInstance;I)Ljava/util/List;")) + private static void arclight$reason(ServerLevel p_219376_, Vec3 p_219377_, Entity p_219378_, int p_219379_, CallbackInfo ci) { + ArclightCaptures.captureEffectCause(EntityPotionEffectEvent.Cause.WARDEN); + } +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/npc/InventoryCarrierMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/npc/InventoryCarrierMixin.java new file mode 100644 index 00000000..ac9d8078 --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/npc/InventoryCarrierMixin.java @@ -0,0 +1,51 @@ +package io.izzel.arclight.common.mixin.core.world.entity.npc; + +import io.izzel.arclight.common.mod.server.ArclightContainer; +import net.minecraft.world.SimpleContainer; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.entity.npc.InventoryCarrier; +import net.minecraft.world.item.ItemStack; +import org.bukkit.craftbukkit.v.event.CraftEventFactory; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(InventoryCarrier.class) +public interface InventoryCarrierMixin { + + // @formatter:off + @Shadow SimpleContainer getInventory(); + // @formatter:on + + /** + * @author IzzelAliz + * @reason + */ + @Overwrite + static void pickUpItem(Mob mob, InventoryCarrier carrier, ItemEntity itemEntity) { + ItemStack itemstack = itemEntity.getItem(); + if (mob.wantsToPickUp(itemstack)) { + SimpleContainer simplecontainer = carrier.getInventory(); + boolean flag = simplecontainer.canAddItem(itemstack); + if (!flag) { + return; + } + + var remaining = ArclightContainer.copyOf(carrier.getInventory()).addItem(itemstack); + if (CraftEventFactory.callEntityPickupItemEvent(mob, itemEntity, remaining.getCount(), false).isCancelled()) { + return; + } + mob.onItemPickup(itemEntity); + int i = itemstack.getCount(); + ItemStack itemstack1 = simplecontainer.addItem(itemstack); + mob.take(itemEntity, i - itemstack1.getCount()); + if (itemstack1.isEmpty()) { + itemEntity.discard(); + } else { + itemstack.setCount(itemstack1.getCount()); + } + } + + } +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/npc/VillagerMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/npc/VillagerMixin.java index 4913b8d8..ff8daad9 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/npc/VillagerMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/npc/VillagerMixin.java @@ -4,7 +4,6 @@ import io.izzel.arclight.common.bridge.core.item.MerchantOfferBridge; import io.izzel.arclight.common.bridge.core.world.WorldBridge; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.LightningBolt; -import net.minecraft.world.entity.animal.IronGolem; import net.minecraft.world.entity.monster.Witch; import net.minecraft.world.item.trading.MerchantOffer; import org.bukkit.Bukkit; @@ -19,7 +18,6 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; @Mixin(net.minecraft.world.entity.npc.Villager.class) @@ -57,8 +55,13 @@ public abstract class VillagerMixin extends AbstractVillagerMixin { } } - @Inject(method = "trySpawnGolem", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;addFreshEntityWithPassengers(Lnet/minecraft/world/entity/Entity;)V")) - private void arclight$ironGolemReason(ServerLevel world, CallbackInfoReturnable cir) { + @Inject(method = "spawnGolemIfNeeded", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/SpawnUtil;trySpawnMob(Lnet/minecraft/world/entity/EntityType;Lnet/minecraft/world/entity/MobSpawnType;Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/core/BlockPos;IIILnet/minecraft/util/SpawnUtil$Strategy;)Ljava/util/Optional;")) + private void arclight$ironGolemReason(ServerLevel world, long p_35399_, int p_35400_, CallbackInfo ci) { ((WorldBridge) world).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.VILLAGE_DEFENSE); } + + @Inject(method = "spawnGolemIfNeeded", at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/util/SpawnUtil;trySpawnMob(Lnet/minecraft/world/entity/EntityType;Lnet/minecraft/world/entity/MobSpawnType;Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/core/BlockPos;IIILnet/minecraft/util/SpawnUtil$Strategy;)Ljava/util/Optional;")) + private void arclight$ironGolemReasonReset(ServerLevel world, long p_35399_, int p_35400_, CallbackInfo ci) { + ((WorldBridge) world).bridge$pushAddEntityReason(null); + } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/player/PlayerMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/player/PlayerMixin.java index fddfcce5..9846d54f 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/player/PlayerMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/player/PlayerMixin.java @@ -13,6 +13,7 @@ import io.izzel.arclight.common.bridge.core.world.WorldBridge; import io.izzel.arclight.common.bridge.core.world.server.ServerWorldBridge; import io.izzel.arclight.common.mixin.core.world.entity.LivingEntityMixin; import net.minecraft.core.BlockPos; +import net.minecraft.core.GlobalPos; import net.minecraft.core.particles.ParticleTypes; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; @@ -43,6 +44,7 @@ import net.minecraft.world.entity.decoration.ArmorStand; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.entity.player.Abilities; import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.ProfilePublicKey; import net.minecraft.world.food.FoodData; import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.inventory.InventoryMenu; @@ -87,6 +89,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; import java.util.List; +import java.util.Optional; @Mixin(net.minecraft.world.entity.player.Player.class) public abstract class PlayerMixin extends LivingEntityMixin implements PlayerEntityBridge, IForgePlayer { @@ -127,13 +130,15 @@ public abstract class PlayerMixin extends LivingEntityMixin implements PlayerEnt @Shadow public abstract GameProfile getGameProfile(); @Shadow public abstract Inventory getInventory(); @Shadow public abstract Abilities getAbilities(); + @Shadow public abstract void setLastDeathLocation(Optional p_219750_); + @Shadow public abstract Optional getLastDeathLocation(); // @formatter:on public boolean fauxSleeping; public int oldLevel; @Inject(method = "", at = @At("RETURN")) - private void arclight$init(Level p_i241920_1_, BlockPos p_i241920_2_, float p_i241920_3_, GameProfile p_i241920_4_, CallbackInfo ci) { + private void arclight$init(Level p_219727_, BlockPos p_219728_, float p_219729_, GameProfile p_219730_, ProfilePublicKey p_219731_, CallbackInfo ci) { oldLevel = -1; ((FoodStatsBridge) this.foodData).bridge$setEntityHuman((net.minecraft.world.entity.player.Player) (Object) this); ((IInventoryBridge) this.enderChestInventory).setOwner(this.getBukkitEntity()); @@ -418,7 +423,11 @@ public abstract class PlayerMixin extends LivingEntityMixin implements PlayerEnt public Either startSleepInBed(BlockPos at, boolean force) { this.arclight$forceSleep = force; - return this.startSleepInBed(at); + try { + return this.startSleepInBed(at); + } finally { + this.arclight$forceSleep = false; + } } @Override @@ -545,16 +554,14 @@ public abstract class PlayerMixin extends LivingEntityMixin implements PlayerEnt } @Override - public void setItemSlot(EquipmentSlot slotIn, ItemStack stack, boolean silent) { - if (slotIn == EquipmentSlot.MAINHAND) { - this.bridge$playEquipSound(stack, silent); - this.inventory.items.set(this.inventory.selected, stack); - } else if (slotIn == EquipmentSlot.OFFHAND) { - this.bridge$playEquipSound(stack, silent); - this.inventory.offhand.set(0, stack); - } else if (slotIn.getType() == EquipmentSlot.Type.ARMOR) { - this.bridge$playEquipSound(stack, silent); - this.inventory.armor.set(slotIn.getIndex(), stack); + public void setItemSlot(EquipmentSlot slot, ItemStack stack, boolean silent) { + this.verifyEquippedItem(stack); + if (slot == EquipmentSlot.MAINHAND) { + this.equipEventAndSound(slot, this.inventory.items.set(this.inventory.selected, stack), stack, silent); + } else if (slot == EquipmentSlot.OFFHAND) { + this.equipEventAndSound(slot, this.inventory.offhand.set(0, stack), stack, silent); + } else if (slot.getType() == EquipmentSlot.Type.ARMOR) { + this.equipEventAndSound(slot, this.inventory.armor.set(slot.getIndex(), stack), stack, silent); } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/player/ServerPlayerMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/player/ServerPlayerMixin.java index bb6d559e..3dc526ce 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/player/ServerPlayerMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/player/ServerPlayerMixin.java @@ -14,15 +14,15 @@ import io.izzel.arclight.common.mod.server.block.ChestBlockDoubleInventoryHacks; import io.izzel.arclight.common.mod.util.ArclightCaptures; import net.minecraft.BlockUtil; import net.minecraft.ChatFormatting; -import net.minecraft.Util; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; +import net.minecraft.core.GlobalPos; +import net.minecraft.core.PositionImpl; import net.minecraft.nbt.CompoundTag; -import net.minecraft.network.chat.ChatType; +import net.minecraft.network.PacketSendListener; +import net.minecraft.network.chat.CommonComponents; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.HoverEvent; -import net.minecraft.network.chat.TextComponent; -import net.minecraft.network.chat.TranslatableComponent; import net.minecraft.network.protocol.game.ClientboundChangeDifficultyPacket; import net.minecraft.network.protocol.game.ClientboundGameEventPacket; import net.minecraft.network.protocol.game.ClientboundHorseScreenOpenPacket; @@ -68,6 +68,7 @@ import net.minecraft.world.level.biome.BiomeManager; import net.minecraft.world.level.block.NetherPortalBlock; import net.minecraft.world.level.border.WorldBorder; import net.minecraft.world.level.dimension.LevelStem; +import net.minecraft.world.level.gameevent.GameEvent; import net.minecraft.world.level.portal.PortalInfo; import net.minecraft.world.level.storage.LevelData; import net.minecraft.world.phys.AABB; @@ -102,7 +103,6 @@ import org.bukkit.event.player.PlayerLocaleChangeEvent; import org.bukkit.event.player.PlayerPortalEvent; import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.inventory.MainHand; -import org.slf4j.Logger; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; @@ -121,7 +121,6 @@ import java.util.List; import java.util.Optional; import java.util.OptionalInt; import java.util.Random; -import java.util.UUID; import java.util.function.Consumer; @Mixin(ServerPlayer.class) @@ -154,12 +153,10 @@ public abstract class ServerPlayerMixin extends PlayerMixin implements ServerPla @Shadow public abstract float getRespawnAngle(); @Shadow protected abstract void tellNeutralMobsThatIDied(); @Shadow protected abstract void createEndPlatform(ServerLevel p_242110_1_, BlockPos p_242110_2_); - @Shadow @Final private static Logger LOGGER; @Shadow public abstract boolean isCreative(); @Shadow public abstract void setRespawnPosition(ResourceKey p_242111_1_, @org.jetbrains.annotations.Nullable BlockPos p_242111_2_, float p_242111_3_, boolean p_242111_4_, boolean p_242111_5_); @Shadow protected abstract boolean bedBlocked(BlockPos p_241156_1_, Direction p_241156_2_); @Shadow protected abstract boolean bedInRange(BlockPos p_241147_1_, Direction p_241147_2_); - @Shadow public abstract void sendMessage(Component component, UUID senderUUID); @Shadow public abstract void setLevel(ServerLevel p_143426_); @Shadow(remap = false) private boolean hasTabListName; @Shadow(remap = false) private Component tabListDisplayName; @@ -316,6 +313,7 @@ public abstract class ServerPlayerMixin extends PlayerMixin implements ServerPla */ @Overwrite public void die(DamageSource damagesource) { + this.gameEvent(GameEvent.ENTITY_DIE); if (net.minecraftforge.common.ForgeHooks.onLivingDeath((ServerPlayer) (Object) this, damagesource)) return; boolean flag = this.level.getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES); @@ -358,30 +356,26 @@ public abstract class ServerPlayerMixin extends PlayerMixin implements ServerPla } else { itextcomponent = CraftChatMessage.fromStringOrNull(deathMessage); } - this.connection.send(new ClientboundPlayerCombatKillPacket(this.getCombatTracker(), itextcomponent), (future) -> { - if (!future.isSuccess()) { - int i = 256; - String s = itextcomponent.getString(256); - Component itextcomponent1 = new TranslatableComponent("death.attack.message_too_long", (new TextComponent(s)).withStyle(ChatFormatting.YELLOW)); - Component itextcomponent2 = (new TranslatableComponent("death.attack.even_more_magic", this.getDisplayName())).withStyle((p_212357_1_) -> { - return p_212357_1_.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, itextcomponent1)); - }); - this.connection.send(new ClientboundPlayerCombatKillPacket(this.getCombatTracker(), itextcomponent2)); - } - - }); + this.connection.send(new ClientboundPlayerCombatKillPacket(this.getCombatTracker(), itextcomponent), PacketSendListener.exceptionallySend(() -> { + String s = itextcomponent.getString(256); + Component component1 = Component.translatable("death.attack.message_too_long", Component.literal(s).withStyle(ChatFormatting.YELLOW)); + Component component2 = Component.translatable("death.attack.even_more_magic", this.getDisplayName()).withStyle((p_143420_) -> { + return p_143420_.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, component1)); + }); + return new ClientboundPlayerCombatKillPacket(this.getCombatTracker(), component2); + })); Team scoreboardteambase = this.getTeam(); if (scoreboardteambase != null && scoreboardteambase.getDeathMessageVisibility() != Team.Visibility.ALWAYS) { if (scoreboardteambase.getDeathMessageVisibility() == Team.Visibility.HIDE_FOR_OTHER_TEAMS) { - this.server.getPlayerList().broadcastToTeam((ServerPlayer) (Object) this, itextcomponent); + this.server.getPlayerList().broadcastSystemToTeam((ServerPlayer) (Object) this, itextcomponent); } else if (scoreboardteambase.getDeathMessageVisibility() == Team.Visibility.HIDE_FOR_OWN_TEAM) { - this.server.getPlayerList().broadcastToAllExceptTeam((ServerPlayer) (Object) this, itextcomponent); + this.server.getPlayerList().broadcastSystemToAllExceptTeam((ServerPlayer) (Object) this, itextcomponent); } } else { - this.server.getPlayerList().broadcastMessage(itextcomponent, ChatType.SYSTEM, Util.NIL_UUID); + this.server.getPlayerList().broadcastSystemMessage(itextcomponent, false); } } else { - this.connection.send(new ClientboundPlayerCombatKillPacket(this.getCombatTracker(), TextComponent.EMPTY)); + this.connection.send(new ClientboundPlayerCombatKillPacket(this.getCombatTracker(), CommonComponents.EMPTY)); } this.removeEntitiesOnShoulder(); @@ -412,6 +406,7 @@ public abstract class ServerPlayerMixin extends PlayerMixin implements ServerPla this.setTicksFrozen(0); this.setSharedFlagOnFire(false); this.getCombatTracker().recheckStatus(); + this.setLastDeathLocation(Optional.of(GlobalPos.of(this.level.dimension(), this.blockPosition()))); } @Redirect(method = "awardKillScore", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/scores/Scoreboard;forAllObjectives(Lnet/minecraft/world/scores/criteria/ObjectiveCriteria;Ljava/lang/String;Ljava/util/function/Consumer;)V")) @@ -494,7 +489,7 @@ public abstract class ServerPlayerMixin extends PlayerMixin implements ServerPla } ServerLevel[] exitWorld = new ServerLevel[]{server}; LevelData iworldinfo = server.getLevelData(); - this.connection.send(new ClientboundRespawnPacket(server.dimensionTypeRegistration(), server.dimension(), BiomeManager.obfuscateSeed(server.getSeed()), this.gameMode.getGameModeForPlayer(), this.gameMode.getPreviousGameModeForPlayer(), server.isDebug(), server.isFlat(), true)); + this.connection.send(new ClientboundRespawnPacket(server.dimensionTypeId(), server.dimension(), BiomeManager.obfuscateSeed(server.getSeed()), this.gameMode.getGameModeForPlayer(), this.gameMode.getPreviousGameModeForPlayer(), server.isDebug(), server.isFlat(), true, this.getLastDeathLocation())); this.connection.send(new ClientboundChangeDifficultyPacket(iworldinfo.getDifficulty(), iworldinfo.isDifficultyLocked())); PlayerList playerlist = this.server.getPlayerList(); playerlist.sendPlayerPermissionLevel((ServerPlayer) (Object) this); @@ -528,7 +523,7 @@ public abstract class ServerPlayerMixin extends PlayerMixin implements ServerPla if (newWorld != exitWorld[0]) { exitWorld[0] = newWorld; LevelData newWorldInfo = exitWorld[0].getLevelData(); - this.connection.send(new ClientboundRespawnPacket(exitWorld[0].dimensionTypeRegistration(), exitWorld[0].dimension(), BiomeManager.obfuscateSeed(exitWorld[0].getSeed()), this.gameMode.getGameModeForPlayer(), this.gameMode.getPreviousGameModeForPlayer(), exitWorld[0].isDebug(), exitWorld[0].isFlat(), true)); + this.connection.send(new ClientboundRespawnPacket(exitWorld[0].dimensionTypeId(), exitWorld[0].dimension(), BiomeManager.obfuscateSeed(exitWorld[0].getSeed()), this.gameMode.getGameModeForPlayer(), this.gameMode.getPreviousGameModeForPlayer(), exitWorld[0].isDebug(), exitWorld[0].isFlat(), true, this.getLastDeathLocation())); this.connection.send(new ClientboundChangeDifficultyPacket(newWorldInfo.getDifficulty(), newWorldInfo.isDifficultyLocked())); } @@ -574,9 +569,9 @@ public abstract class ServerPlayerMixin extends PlayerMixin implements ServerPla } @Override - protected CraftPortalEvent callPortalEvent(Entity entity, ServerLevel exitWorldServer, BlockPos exitPosition, PlayerTeleportEvent.TeleportCause cause, int searchRadius, int creationRadius) { + protected CraftPortalEvent callPortalEvent(Entity entity, ServerLevel exitWorldServer, PositionImpl exitPosition, PlayerTeleportEvent.TeleportCause cause, int searchRadius, int creationRadius) { Location enter = this.getBukkitEntity().getLocation(); - Location exit = new Location(((WorldBridge) exitWorldServer).bridge$getWorld(), exitPosition.getX(), exitPosition.getY(), exitPosition.getZ(), this.getYRot(), this.getXRot()); + Location exit = new Location(((WorldBridge) exitWorldServer).bridge$getWorld(), exitPosition.x(), exitPosition.y(), exitPosition.z(), this.getYRot(), this.getXRot()); PlayerPortalEvent event = new PlayerPortalEvent(this.getBukkitEntity(), enter, exit, cause, 128, true, creationRadius); Bukkit.getServer().getPluginManager().callEvent(event); if (event.isCancelled() || event.getTo() == null || event.getTo().getWorld() == null) { @@ -750,22 +745,6 @@ public abstract class ServerPlayerMixin extends PlayerMixin implements ServerPla this.lastSentExp = -1; } - public void sendMessage(UUID uuid, Component[] components) { - for (final Component component : components) { - this.sendMessage(component, uuid == null ? Util.NIL_UUID : uuid); - } - } - - @Override - public void bridge$sendMessage(Component[] components, UUID uuid) { - sendMessage(uuid, components); - } - - @Override - public void bridge$sendMessage(Component component, UUID uuid) { - this.sendMessage(component, uuid == null ? Util.NIL_UUID : uuid); - } - @Inject(method = "updateOptions", at = @At("HEAD")) private void arclight$settingChange(ServerboundClientInformationPacket packetIn, CallbackInfo ci) { if (this.getMainArm() != packetIn.mainHand()) { diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/raid/RaidMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/raid/RaidMixin.java index e6776de3..e140f9b8 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/raid/RaidMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/raid/RaidMixin.java @@ -3,7 +3,7 @@ package io.izzel.arclight.common.mixin.core.world.entity.raid; import io.izzel.arclight.common.bridge.core.entity.player.ServerPlayerEntityBridge; import io.izzel.arclight.common.bridge.core.world.WorldBridge; import io.izzel.arclight.common.bridge.core.world.raid.RaidBridge; -import net.minecraft.advancements.critereon.LocationTrigger; +import net.minecraft.advancements.critereon.PlayerTrigger; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; @@ -84,8 +84,8 @@ public class RaidMixin implements RaidBridge { private transient List arclight$winners; - @Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/advancements/critereon/LocationTrigger;trigger(Lnet/minecraft/server/level/ServerPlayer;)V")) - public void arclight$addWinner(LocationTrigger trigger, ServerPlayer player) { + @Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/advancements/critereon/PlayerTrigger;trigger(Lnet/minecraft/server/level/ServerPlayer;)V")) + public void arclight$addWinner(PlayerTrigger trigger, ServerPlayer player) { trigger.trigger(player); if (arclight$winners == null) { arclight$winners = new ArrayList<>(); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/vehicle/AbstractMinecartMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/vehicle/AbstractMinecartMixin.java index 78b303db..2d26502b 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/vehicle/AbstractMinecartMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/vehicle/AbstractMinecartMixin.java @@ -18,6 +18,7 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.block.BaseRailBlock; import net.minecraft.world.level.block.PoweredRailBlock; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.gameevent.GameEvent; import net.minecraft.world.phys.Vec3; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -107,6 +108,7 @@ public abstract class AbstractMinecartMixin extends EntityMixin { this.setHurtTime(10); this.markHurt(); this.setDamage(this.getDamage() + amount * 10.0f); + this.gameEvent(GameEvent.ENTITY_DAMAGE, source.getEntity()); boolean flag = source.getEntity() instanceof Player && ((Player) source.getEntity()).getAbilities().instabuild; if (flag || this.getDamage() > 40.0f) { VehicleDestroyEvent destroyEvent = new VehicleDestroyEvent(vehicle, passenger); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/vehicle/ChestBoatMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/vehicle/ChestBoatMixin.java new file mode 100644 index 00000000..c7d74139 --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/vehicle/ChestBoatMixin.java @@ -0,0 +1,67 @@ +package io.izzel.arclight.common.mixin.core.world.entity.vehicle; + +import io.izzel.arclight.common.bridge.core.inventory.IInventoryBridge; +import net.minecraft.core.NonNullList; +import net.minecraft.world.Container; +import net.minecraft.world.entity.vehicle.ChestBoat; +import net.minecraft.world.item.ItemStack; +import org.bukkit.Location; +import org.bukkit.craftbukkit.v.entity.CraftHumanEntity; +import org.bukkit.entity.HumanEntity; +import org.bukkit.inventory.InventoryHolder; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +import java.util.ArrayList; +import java.util.List; + +@Mixin(ChestBoat.class) +public abstract class ChestBoatMixin extends BoatMixin implements IInventoryBridge, Container { + + @Shadow private NonNullList itemStacks; + + public List transaction = new ArrayList<>(); + private int maxStack = MAX_STACK; + + @Override + public List getContents() { + return this.itemStacks; + } + + @Override + public void onOpen(CraftHumanEntity who) { + transaction.add(who); + } + + @Override + public void onClose(CraftHumanEntity who) { + transaction.remove(who); + } + + @Override + public List getViewers() { + return transaction; + } + + @Override + public InventoryHolder getOwner() { + org.bukkit.entity.Entity entity = getBukkitEntity(); + if (entity instanceof InventoryHolder) return (InventoryHolder) entity; + return null; + } + + @Override + public int getMaxStackSize() { + return maxStack; + } + + @Override + public void setMaxStackSize(int size) { + maxStack = size; + } + + @Override + public Location getLocation() { + return getBukkitEntity().getLocation(); + } +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/gen/feature/structure/StructureFeatureManagerMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/gen/feature/structure/StructureFeatureManagerMixin.java deleted file mode 100644 index a14422cc..00000000 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/gen/feature/structure/StructureFeatureManagerMixin.java +++ /dev/null @@ -1,19 +0,0 @@ -package io.izzel.arclight.common.mixin.core.world.gen.feature.structure; - -import io.izzel.arclight.common.bridge.core.world.IWorldBridge; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.StructureFeatureManager; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -@Mixin(StructureFeatureManager.class) -public class StructureFeatureManagerMixin { - - @Shadow @Final private LevelAccessor level; - - public Level getWorld() { - return ((IWorldBridge) this.level).bridge$getMinecraftWorld(); - } -} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/gen/feature/structure/SwampHutPieceMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/gen/feature/structure/SwampHutPieceMixin.java index 13a92384..444abd78 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/gen/feature/structure/SwampHutPieceMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/gen/feature/structure/SwampHutPieceMixin.java @@ -2,26 +2,25 @@ package io.izzel.arclight.common.mixin.core.world.gen.feature.structure; import io.izzel.arclight.common.bridge.core.world.IWorldWriterBridge; import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.ServerLevelAccessor; -import net.minecraft.world.level.StructureFeatureManager; +import net.minecraft.world.level.StructureManager; import net.minecraft.world.level.WorldGenLevel; import net.minecraft.world.level.chunk.ChunkGenerator; import net.minecraft.world.level.levelgen.structure.BoundingBox; -import net.minecraft.world.level.levelgen.structure.SwamplandHutPiece; +import net.minecraft.world.level.levelgen.structure.structures.SwampHutPiece; import org.bukkit.event.entity.CreatureSpawnEvent; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.util.Random; - -@Mixin(SwamplandHutPiece.class) +@Mixin(SwampHutPiece.class) public class SwampHutPieceMixin { @Inject(method = "postProcess", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/WorldGenLevel;addFreshEntityWithPassengers(Lnet/minecraft/world/entity/Entity;)V")) - private void arclight$spawnReason1(WorldGenLevel level, StructureFeatureManager p_192667_, ChunkGenerator p_192668_, Random p_192669_, BoundingBox p_192670_, ChunkPos p_192671_, BlockPos p_192672_, CallbackInfo ci) { + private void arclight$spawnReason1(WorldGenLevel level, StructureManager p_229962_, ChunkGenerator p_229963_, RandomSource p_229964_, BoundingBox p_229965_, ChunkPos p_229966_, BlockPos p_229967_, CallbackInfo ci) { ((IWorldWriterBridge) level).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.CHUNK_GEN); } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/gen/feature/template/TemplateManagerMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/gen/feature/template/TemplateManagerMixin.java deleted file mode 100644 index e7107653..00000000 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/gen/feature/template/TemplateManagerMixin.java +++ /dev/null @@ -1,29 +0,0 @@ -package io.izzel.arclight.common.mixin.core.world.gen.feature.template; - -import com.mojang.datafixers.DataFixer; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Mutable; -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.CallbackInfo; - -import java.util.Collections; -import java.util.Map; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.packs.resources.ResourceManager; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; -import net.minecraft.world.level.storage.LevelStorageSource; - -@Mixin(StructureManager.class) -public class TemplateManagerMixin { - - @Shadow @Final @Mutable private Map structureRepository; - - @Inject(method = "", at = @At("RETURN")) - private void arclight$init(ResourceManager p_i232119_1_, LevelStorageSource.LevelStorageAccess p_i232119_2_, DataFixer fixer, CallbackInfo ci) { - this.structureRepository = Collections.synchronizedMap(this.structureRepository); - } -} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/inventory/AbstractContainerMenuMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/inventory/AbstractContainerMenuMixin.java index b030b433..15f3d99f 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/inventory/AbstractContainerMenuMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/inventory/AbstractContainerMenuMixin.java @@ -6,7 +6,6 @@ import io.izzel.arclight.common.bridge.core.inventory.container.SlotBridge; import io.izzel.arclight.common.mod.server.ArclightContainer; import net.minecraft.core.NonNullList; import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.TextComponent; import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.SlotAccess; @@ -19,6 +18,7 @@ import net.minecraft.world.inventory.ContainerSynchronizer; import net.minecraft.world.inventory.MenuType; import net.minecraft.world.inventory.Slot; import net.minecraft.world.item.ItemStack; +import net.minecraftforge.registries.ForgeRegistries; import org.bukkit.Bukkit; import org.bukkit.craftbukkit.v.entity.CraftHumanEntity; import org.bukkit.craftbukkit.v.inventory.CraftInventory; @@ -92,10 +92,11 @@ public abstract class AbstractContainerMenuMixin implements ContainerBridge { public Component getTitle() { if (this.title == null) { - if (this.menuType != null && this.menuType.getRegistryName() != null) { - return new TextComponent(this.menuType.getRegistryName().toString()); + if (this.menuType != null) { + var key = ForgeRegistries.MENU_TYPES.getKey(this.menuType); + return Component.translatable(key.toString()); } else { - return new TextComponent(this.toString()); + return Component.translatable(this.toString()); } } return this.title; @@ -261,8 +262,8 @@ public abstract class AbstractContainerMenuMixin implements ContainerBridge { int j3 = clickaction == ClickAction.PRIMARY ? itemstack11.getCount() : 1; this.setCarried(slot7.safeInsert(itemstack11, j3)); } else if (itemstack11.getCount() <= slot7.getMaxStackSize(itemstack11)) { - slot7.set(itemstack11); this.setCarried(itemstack10); + slot7.set(itemstack11); } } else if (ItemStack.isSameItemSameTags(itemstack10, itemstack11)) { Optional optional = slot7.tryRemove(itemstack10.getCount(), itemstack11.getMaxStackSize() - itemstack11.getCount(), player); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/inventory/EnchantmentContainerMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/inventory/EnchantmentContainerMixin.java index 33f0d124..abe0fde7 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/inventory/EnchantmentContainerMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/inventory/EnchantmentContainerMixin.java @@ -12,6 +12,7 @@ import net.minecraft.server.level.ServerPlayer; import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; import net.minecraft.stats.Stats; +import net.minecraft.util.RandomSource; import net.minecraft.world.Container; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.inventory.AbstractContainerMenu; @@ -23,7 +24,6 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import net.minecraft.world.item.enchantment.EnchantmentHelper; import net.minecraft.world.item.enchantment.EnchantmentInstance; -import net.minecraft.world.level.Level; import net.minecraft.world.level.block.EnchantmentTableBlock; import net.minecraftforge.event.ForgeEventFactory; import net.minecraftforge.registries.ForgeRegistries; @@ -49,7 +49,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.util.List; import java.util.Map; -import java.util.Random; @Mixin(EnchantmentMenu.class) public abstract class EnchantmentContainerMixin extends AbstractContainerMenuMixin implements PosContainerBridge { @@ -57,7 +56,7 @@ public abstract class EnchantmentContainerMixin extends AbstractContainerMenuMix // @formatter:off @Shadow @Final private Container enchantSlots; @Shadow @Final private ContainerLevelAccess access; - @Shadow @Final private Random random; + @Shadow @Final private RandomSource random; @Shadow @Final private DataSlot enchantmentSeed; @Shadow @Final public int[] costs; @Shadow @Final public int[] enchantClue; diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/inventory/PlayerContainerMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/inventory/PlayerContainerMixin.java index a8e34458..9da4e372 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/inventory/PlayerContainerMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/inventory/PlayerContainerMixin.java @@ -3,7 +3,7 @@ package io.izzel.arclight.common.mixin.core.world.inventory; import io.izzel.arclight.common.bridge.core.entity.player.PlayerEntityBridge; import io.izzel.arclight.common.bridge.core.inventory.CraftingInventoryBridge; import io.izzel.arclight.common.mod.util.ArclightCaptures; -import net.minecraft.network.chat.TranslatableComponent; +import net.minecraft.network.chat.Component; import net.minecraft.world.Container; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; @@ -36,7 +36,7 @@ public abstract class PlayerContainerMixin extends AbstractContainerMenuMixin { this.playerInventory = playerInventory; ((CraftingInventoryBridge) this.craftSlots).bridge$setOwner(playerInventory.player); ((CraftingInventoryBridge) this.craftSlots).bridge$setResultInventory(this.resultSlots); - this.setTitle(new TranslatableComponent("container.crafting")); + this.setTitle(Component.translatable("container.crafting")); } @Inject(method = "slotsChanged", at = @At("HEAD")) diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/inventory/RepairContainerMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/inventory/RepairContainerMixin.java index 95997fc3..74cba7a7 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/inventory/RepairContainerMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/inventory/RepairContainerMixin.java @@ -2,7 +2,7 @@ package io.izzel.arclight.common.mixin.core.world.inventory; import io.izzel.arclight.common.bridge.core.entity.player.PlayerEntityBridge; import io.izzel.arclight.common.bridge.core.util.IWorldPosCallableBridge; -import net.minecraft.network.chat.TextComponent; +import net.minecraft.network.chat.Component; import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.inventory.AnvilMenu; import net.minecraft.world.inventory.DataSlot; @@ -181,7 +181,7 @@ public abstract class RepairContainerMixin extends ItemCombinerMixin { } else if (!this.itemName.equals(itemstack.getHoverName().getString())) { k = 1; i += k; - itemstack1.setHoverName(new TextComponent(this.itemName)); + itemstack1.setHoverName(Component.literal(this.itemName)); } if (flag && !itemstack1.isBookEnchantable(itemstack2)) itemstack1 = ItemStack.EMPTY; 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 b857a935..0708a2e0 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 @@ -7,8 +7,8 @@ import net.minecraft.nbt.CompoundTag; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.InteractionResult; import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.PlaceOnWaterBlockItem; import net.minecraft.world.item.SolidBucketItem; -import net.minecraft.world.item.WaterLilyBlockItem; import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; @@ -43,7 +43,7 @@ public abstract class BlockItemMixin { @Inject(method = "place", locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/world/item/BlockItem;getPlacementState(Lnet/minecraft/world/item/context/BlockPlaceContext;)Lnet/minecraft/world/level/block/state/BlockState;")) private void arclight$prePlaceLilypad(BlockPlaceContext context, CallbackInfoReturnable cir, BlockPlaceContext context1) { - if ((Object) this instanceof WaterLilyBlockItem || (Object) this instanceof SolidBucketItem) { + if ((Object) this instanceof PlaceOnWaterBlockItem || (Object) this instanceof SolidBucketItem) { this.arclight$state = CraftBlockStates.getBlockState(context1.getLevel(), context1.getClickedPos()); } } 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 a4f9d88c..8f0ff0fe 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 @@ -30,11 +30,12 @@ import java.util.List; import java.util.function.Predicate; @Mixin(BoatItem.class) -public class BoatItemMixin extends Item { +public abstract class BoatItemMixin extends Item { // @formatter:off @Shadow @Final private static Predicate ENTITY_PREDICATE; @Shadow @Final private Boat.Type type; + @Shadow protected abstract Boat getBoat(Level p_220017_, HitResult p_220018_); // @formatter:on public BoatItemMixin(Properties properties) { @@ -75,7 +76,7 @@ public class BoatItemMixin extends Item { } } - Boat boatentity = new Boat(worldIn, result.getLocation().x, result.getLocation().y, result.getLocation().z); + Boat boatentity = this.getBoat(worldIn, result); boatentity.setType(this.type); boatentity.setYRot(playerIn.getYRot()); if (!worldIn.noCollision(boatentity, boatentity.getBoundingBox().inflate(-0.1D))) { 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 6838786d..3140baab 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 @@ -13,6 +13,9 @@ import net.minecraft.world.item.ChorusFruitItem; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; +import net.minecraft.world.level.gameevent.GameEvent; +import net.minecraft.world.phys.Vec3; +import net.minecraftforge.event.ForgeEventFactory; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.entity.Player; @@ -60,8 +63,11 @@ public class ChorusFruitItemMixin extends Item { if (entityLiving.isPassenger()) { entityLiving.stopRiding(); } - + Vec3 vec3d = entityLiving.position(); + var event = ForgeEventFactory.onChorusFruitTeleport(entityLiving, d3, d4, d5); + if (event.isCanceled()) return itemstack; if (entityLiving.randomTeleport(d3, d4, d5, true)) { + worldIn.gameEvent(GameEvent.TELEPORT, vec3d, GameEvent.Context.of(entityLiving)); SoundEvent soundevent = entityLiving instanceof Fox ? SoundEvents.FOX_TELEPORT : SoundEvents.CHORUS_FRUIT_TELEPORT; worldIn.playSound(null, d0, d1, d2, soundevent, SoundSource.PLAYERS, 1.0F, 1.0F); entityLiving.playSound(soundevent, 1.0F, 1.0F); 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 4315f561..d9689e99 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 @@ -16,6 +16,7 @@ import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.enchantment.EnchantmentHelper; import net.minecraft.world.level.Level; +import net.minecraft.world.level.gameevent.GameEvent; import org.bukkit.Bukkit; import org.bukkit.entity.FishHook; import org.bukkit.event.player.PlayerFishEvent; @@ -46,6 +47,7 @@ public class FishingRodItemMixin extends Item { playerIn.swing(handIn); worldIn.playSound(null, playerIn.getX(), playerIn.getY(), playerIn.getZ(), SoundEvents.FISHING_BOBBER_RETRIEVE, SoundSource.NEUTRAL, 1.0F, 0.4F / (worldIn.getRandom().nextFloat() * 0.4F + 0.8F)); + playerIn.gameEvent(GameEvent.ITEM_INTERACT_FINISH); } else { if (!worldIn.isClientSide) { int k = EnchantmentHelper.getFishingSpeedBonus(itemstack); @@ -67,6 +69,7 @@ public class FishingRodItemMixin extends Item { // playerIn.swingArm(handIn); playerIn.awardStat(Stats.ITEM_USED.get(this)); + playerIn.gameEvent(GameEvent.ITEM_INTERACT_START); } return InteractionResultHolder.sidedSuccess(itemstack, worldIn.isClientSide()); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/ItemStackMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/ItemStackMixin.java index dc846067..49430885 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/ItemStackMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/ItemStackMixin.java @@ -4,12 +4,13 @@ import io.izzel.arclight.common.bridge.core.entity.player.ServerPlayerEntityBrid import io.izzel.arclight.common.bridge.core.item.ItemStackBridge; import net.minecraft.nbt.CompoundTag; import net.minecraft.server.level.ServerPlayer; +import net.minecraft.util.RandomSource; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraftforge.common.capabilities.CapabilityProvider; -import net.minecraftforge.registries.IRegistryDelegate; +import net.minecraftforge.registries.ForgeRegistries; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.bukkit.craftbukkit.v.event.CraftEventFactory; @@ -26,7 +27,6 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.ModifyVariable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.util.Random; import java.util.function.Consumer; @Mixin(ItemStack.class) @@ -36,7 +36,7 @@ public abstract class ItemStackMixin extends CapabilityProvider imple @Shadow @Deprecated private Item item; @Shadow private int count; @Shadow(remap = false) private CompoundTag capNBT; - @Mutable @Shadow(remap = false) @Final private IRegistryDelegate delegate; + @Mutable @Shadow(remap = false) @Final private net.minecraft.core.Holder.Reference delegate; // @formatter:on protected ItemStackMixin(Class baseClass) { @@ -69,8 +69,8 @@ public abstract class ItemStackMixin extends CapabilityProvider imple this.convertStack(version); } - @ModifyVariable(method = "hurt", index = 1, name = "amount", at = @At(value = "JUMP", opcode = Opcodes.IFGT, ordinal = 0)) - private int arclight$itemDamage(int i, int amount, Random rand, ServerPlayer damager) { + @ModifyVariable(method = "hurt", index = 1, at = @At(value = "JUMP", opcode = Opcodes.IFGT, ordinal = 0)) + private int arclight$itemDamage(int i, int amount, RandomSource rand, ServerPlayer damager) { if (damager != null) { PlayerItemDamageEvent event = new PlayerItemDamageEvent(((ServerPlayerEntityBridge) damager).bridge$getBukkitEntity(), CraftItemStack.asCraftMirror((ItemStack) (Object) this), i); event.getPlayer().getServer().getPluginManager().callEvent(event); @@ -96,6 +96,6 @@ public abstract class ItemStackMixin extends CapabilityProvider imple @Deprecated public void setItem(Item item) { this.item = item; - this.delegate = item.delegate; + this.delegate = ForgeRegistries.ITEMS.getDelegateOrThrow(item); } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/crafting/RecipeManagerMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/crafting/RecipeManagerMixin.java index 1e2092a4..b15d27f1 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/crafting/RecipeManagerMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/crafting/RecipeManagerMixin.java @@ -35,7 +35,7 @@ public abstract class RecipeManagerMixin implements RecipeManagerBridge { // @formatter:off @Shadow public Map, Map>> recipes; - @Shadow protected abstract > Map> byType(RecipeType recipeTypeIn); + @Shadow protected abstract > Map byType(RecipeType p_44055_); @Shadow private boolean hasErrors; @Shadow @Final private static Logger LOGGER; @Shadow(remap = false) public static Recipe fromJson(ResourceLocation recipeId, JsonObject json, ICondition.IContext context) { return null; } @@ -65,7 +65,7 @@ public abstract class RecipeManagerMixin implements RecipeManagerBridge { try { if (entry.getValue().isJsonObject() && !CraftingHelper.processConditions(entry.getValue().getAsJsonObject(), "conditions", this.context)) { - LOGGER.info("Skipping loading recipe {} as it's conditions were not met", resourcelocation); + LOGGER.debug("Skipping loading recipe {} as it's conditions were not met", resourcelocation); continue; } Recipe irecipe = fromJson(resourcelocation, GsonHelper.convertToJsonObject(entry.getValue(), "top element"), this.context); @@ -92,8 +92,8 @@ public abstract class RecipeManagerMixin implements RecipeManagerBridge { */ @Overwrite public > Optional getRecipeFor(RecipeType recipeTypeIn, C inventoryIn, Level worldIn) { - Optional optional = this.byType(recipeTypeIn).values().stream().flatMap((p_44064_) -> { - return recipeTypeIn.tryMatch(p_44064_, worldIn, inventoryIn).stream(); + Optional optional = this.byType(recipeTypeIn).values().stream().filter((recipe) -> { + return recipe.matches(inventoryIn, worldIn); }).findFirst(); ((IInventoryBridge) inventoryIn).setCurrentRecipe(optional.orElse(null)); return optional; diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/LevelMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/LevelMixin.java index f54bae6a..fdbbe7b2 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/LevelMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/LevelMixin.java @@ -1,6 +1,5 @@ package io.izzel.arclight.common.mixin.core.world.level; -import io.izzel.arclight.common.bridge.core.entity.EntityBridge; import io.izzel.arclight.common.bridge.core.world.WorldBridge; import io.izzel.arclight.common.bridge.core.world.border.WorldBorderBridge; import io.izzel.arclight.common.bridge.core.world.level.levelgen.ChunkGeneratorBridge; @@ -22,19 +21,16 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.LevelWriter; import net.minecraft.world.level.biome.BiomeSource; -import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.border.WorldBorder; import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.dimension.DimensionType; import net.minecraft.world.level.dimension.LevelStem; -import net.minecraft.world.level.gameevent.GameEvent; import net.minecraft.world.level.storage.LevelData; import net.minecraft.world.level.storage.ServerLevelData; import net.minecraft.world.level.storage.WritableLevelData; import org.bukkit.Bukkit; -import org.bukkit.Location; import org.bukkit.craftbukkit.v.CraftServer; import org.bukkit.craftbukkit.v.CraftWorld; import org.bukkit.craftbukkit.v.block.CraftBlock; @@ -43,12 +39,10 @@ import org.bukkit.craftbukkit.v.event.CraftEventFactory; import org.bukkit.craftbukkit.v.generator.CraftWorldInfo; import org.bukkit.craftbukkit.v.generator.CustomChunkGenerator; import org.bukkit.craftbukkit.v.generator.CustomWorldChunkManager; -import org.bukkit.craftbukkit.v.util.CraftNamespacedKey; import org.bukkit.craftbukkit.v.util.CraftSpawnCategory; import org.bukkit.entity.SpawnCategory; import org.bukkit.event.block.BlockPhysicsEvent; import org.bukkit.event.entity.CreatureSpawnEvent; -import org.bukkit.event.world.GenericGameEvent; import org.bukkit.generator.ChunkGenerator; import org.spigotmc.SpigotWorldConfig; import org.spongepowered.asm.mixin.Final; @@ -59,7 +53,6 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; import javax.annotation.Nullable; import java.lang.reflect.Field; @@ -76,9 +69,10 @@ public abstract class LevelMixin implements WorldBridge, LevelWriter { @Shadow @Final private WorldBorder worldBorder; @Shadow public abstract long getDayTime(); @Shadow public abstract MinecraftServer shadow$getServer(); - @Shadow @Final private DimensionType dimensionType; @Shadow public abstract LevelData getLevelData(); @Shadow public abstract ResourceKey dimension(); + @Shadow(remap = false) public abstract void markAndNotifyBlock(BlockPos p_46605_,@org.jetbrains.annotations.Nullable LevelChunk levelchunk, BlockState blockstate, BlockState p_46606_, int p_46607_, int p_46608_); + @Shadow public abstract DimensionType dimensionType(); @Accessor("thread") public abstract Thread arclight$getMainThread(); // @formatter:on @@ -95,20 +89,20 @@ public abstract class LevelMixin implements WorldBridge, LevelWriter { private static BlockPos lastPhysicsProblem; // Spigot public boolean preventPoiUpdated = false; - public void arclight$constructor(WritableLevelData worldInfo, ResourceKey dimension, final Holder dimensionType, Supplier profiler, boolean isRemote, boolean isDebug, long seed) { + public void arclight$constructor(WritableLevelData worldInfo, ResourceKey dimension, final Holder dimensionType, Supplier profiler, boolean isRemote, boolean isDebug, long seed, int maxNeighborUpdate) { throw new RuntimeException(); } - public void arclight$constructor(WritableLevelData worldInfo, ResourceKey dimension, final Holder dimensionType, Supplier profiler, boolean isRemote, boolean isDebug, long seed, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env) { - arclight$constructor(worldInfo, dimension, dimensionType, profiler, isRemote, isDebug, seed); + public void arclight$constructor(WritableLevelData worldInfo, ResourceKey dimension, final Holder dimensionType, Supplier profiler, boolean isRemote, boolean isDebug, long seed, int maxNeighborUpdate, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env) { + arclight$constructor(worldInfo, dimension, dimensionType, profiler, isRemote, isDebug, seed, maxNeighborUpdate); this.generator = gen; this.environment = env; this.biomeProvider = biomeProvider; bridge$getWorld(); } - @Inject(method = "(Lnet/minecraft/world/level/storage/WritableLevelData;Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/core/Holder;Ljava/util/function/Supplier;ZZJ)V", at = @At("RETURN")) - private void arclight$init(WritableLevelData info, ResourceKey dimension, Holder dimType, Supplier profiler, boolean isRemote, boolean isDebug, long seed, CallbackInfo ci) { + @Inject(method = "", at = @At("RETURN")) + private void arclight$init(WritableLevelData info, ResourceKey dimension, Holder dimType, Supplier profiler, boolean isRemote, boolean isDebug, long seed, int maxNeighborUpdates, CallbackInfo ci) { ((WorldBorderBridge) this.worldBorder).bridge$setWorld((Level) (Object) this); for (SpawnCategory spawnCategory : SpawnCategory.values()) { if (CraftSpawnCategory.isValidForLimits(spawnCategory)) { @@ -117,6 +111,11 @@ public abstract class LevelMixin implements WorldBridge, LevelWriter { } } + @Override + public void bridge$setLastPhysicsProblem(BlockPos pos) { + lastPhysicsProblem = pos; + } + @Override public Object2LongOpenHashMap bridge$ticksPerSpawnCategory() { return this.ticksPerSpawnCategory; @@ -174,31 +173,8 @@ public abstract class LevelMixin implements WorldBridge, LevelWriter { } } - @Inject(method = "neighborChanged", cancellable = true, - at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/state/BlockState;neighborChanged(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/Block;Lnet/minecraft/core/BlockPos;Z)V"), - locals = LocalCapture.CAPTURE_FAILHARD) - private void arclight$callBlockPhysics2(BlockPos pos, Block blockIn, BlockPos fromPos, CallbackInfo ci, BlockState blockState) { - try { - if (this.world != null) { - LevelAccessor iWorld = (LevelAccessor) this; - BlockPhysicsEvent event = new BlockPhysicsEvent(CraftBlock.at(iWorld, pos), CraftBlockData.fromData(blockState), CraftBlock.at(iWorld, fromPos)); - Bukkit.getPluginManager().callEvent(event); - if (event.isCancelled()) { - ci.cancel(); - } - } - } catch (StackOverflowError e) { - lastPhysicsProblem = pos; - } - } - - @Inject(method = "postGameEventInRadius", cancellable = true, at = @At("HEAD")) - private void arclight$gameEventEvent(Entity entity, GameEvent gameEvent, BlockPos pos, int i, CallbackInfo ci) { - GenericGameEvent event = new GenericGameEvent(org.bukkit.GameEvent.getByKey(CraftNamespacedKey.fromMinecraft(Registry.GAME_EVENT.getKey(gameEvent))), new Location(this.getWorld(), pos.getX(), pos.getY(), pos.getZ()), (entity == null) ? null : ((EntityBridge) entity).bridge$getBukkitEntity(), i); - Bukkit.getPluginManager().callEvent(event); - if (event.isCancelled()) { - ci.cancel(); - } + public void notifyAndUpdatePhysics(BlockPos blockposition, LevelChunk chunk, BlockState oldBlock, BlockState newBlock, BlockState actualBlock, int i, int j) { + this.markAndNotifyBlock(blockposition, chunk, oldBlock, newBlock, i, j); } public CraftServer getCraftServer() { @@ -222,7 +198,7 @@ public abstract class LevelMixin implements WorldBridge, LevelWriter { generator = getCraftServer().getGenerator(((ServerLevelData) this.getLevelData()).getLevelName()); if (generator != null && (Object) this instanceof ServerLevel serverWorld) { org.bukkit.generator.WorldInfo worldInfo = new CraftWorldInfo((ServerLevelData) getLevelData(), - ((ServerWorldBridge) this).bridge$getConvertable(), environment, this.dimensionType); + ((ServerWorldBridge) this).bridge$getConvertable(), environment, this.dimensionType()); if (biomeProvider == null && generator != null) { biomeProvider = generator.getDefaultBiomeProvider(worldInfo); } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/BambooBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/BambooBlockMixin.java index 77477feb..3f460185 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/BambooBlockMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/BambooBlockMixin.java @@ -1,6 +1,7 @@ package io.izzel.arclight.common.mixin.core.world.level.block; import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.BambooBlock; import net.minecraft.world.level.block.Blocks; @@ -17,8 +18,6 @@ import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; -import java.util.Random; - @Mixin(BambooBlock.class) public abstract class BambooBlockMixin extends BlockMixin { @@ -40,7 +39,7 @@ public abstract class BambooBlockMixin extends BlockMixin { * @reason */ @Overwrite - protected void growBamboo(BlockState blockStateIn, Level worldIn, BlockPos posIn, Random rand, int height) { + protected void growBamboo(BlockState blockStateIn, Level worldIn, BlockPos posIn, RandomSource rand, int height) { BlockState blockstate = worldIn.getBlockState(posIn.below()); BlockPos blockpos = posIn.below(2); BlockState blockstate1 = worldIn.getBlockState(blockpos); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/BaseFireBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/BaseFireBlockMixin.java index 6571d5e1..a86e41e6 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/BaseFireBlockMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/BaseFireBlockMixin.java @@ -1,12 +1,18 @@ package io.izzel.arclight.common.mixin.core.world.level.block; +import io.izzel.arclight.common.bridge.core.entity.EntityBridge; import io.izzel.arclight.common.bridge.core.world.WorldBridge; import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.Entity; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.BaseFireBlock; import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.dimension.LevelStem; +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.v.block.CraftBlock; import org.bukkit.craftbukkit.v.event.CraftEventFactory; +import org.bukkit.event.entity.EntityCombustByBlockEvent; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.injection.At; @@ -15,6 +21,18 @@ import org.spongepowered.asm.mixin.injection.Redirect; @Mixin(BaseFireBlock.class) public class BaseFireBlockMixin { + // fireExtinguished implemented per class + + @Redirect(method = "entityInside", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;setSecondsOnFire(I)V")) + private void arclight$onFire(Entity instance, int seconds, BlockState state, Level level, BlockPos pos) { + var event = new EntityCombustByBlockEvent(CraftBlock.at(level, pos), ((EntityBridge) instance).bridge$getBukkitEntity(), seconds); + Bukkit.getPluginManager().callEvent(event); + + if (!event.isCancelled()) { + ((EntityBridge) instance).bridge$setOnFire(event.getDuration(), false); + } + } + @Redirect(method = "onPlace", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;removeBlock(Lnet/minecraft/core/BlockPos;Z)Z")) public boolean arclight$extinguish2(Level world, BlockPos pos, boolean isMoving) { if (!CraftEventFactory.callBlockFadeEvent(world, pos, Blocks.AIR.defaultBlockState()).isCancelled()) { diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/BedBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/BedBlockMixin.java index bbed1665..90d56c7b 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/BedBlockMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/BedBlockMixin.java @@ -1,9 +1,86 @@ package io.izzel.arclight.common.mixin.core.world.level.block; +import net.minecraft.core.BlockPos; +import net.minecraft.network.chat.Component; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Explosion; +import net.minecraft.world.level.Level; import net.minecraft.world.level.block.BedBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.BedPart; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.block.state.properties.EnumProperty; +import net.minecraft.world.phys.BlockHitResult; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; + +import static net.minecraft.world.level.block.HorizontalDirectionalBlock.FACING; -// todo 重新检查爆炸和 BedEvent 实现 @Mixin(BedBlock.class) -public class BedBlockMixin { +public abstract class BedBlockMixin { + + // @formatter:off + @Shadow @Final public static EnumProperty PART; + @Shadow @Final public static BooleanProperty OCCUPIED; + @Shadow protected abstract boolean kickVillagerOutOfBed(Level p_49491_, BlockPos p_49492_); + // @formatter:on + + /** + * @author IzzelAliz + * @reason + */ + @Overwrite + public InteractionResult use(BlockState p_49515_, Level level, BlockPos p_49517_, Player p_49518_, InteractionHand p_49519_, BlockHitResult p_49520_) { + if (level.isClientSide) { + return InteractionResult.CONSUME; + } else { + if (p_49515_.getValue(PART) != BedPart.HEAD) { + p_49517_ = p_49517_.relative(p_49515_.getValue(FACING)); + p_49515_ = level.getBlockState(p_49517_); + if (!p_49515_.is((BedBlock) (Object) this)) { + return InteractionResult.CONSUME; + } + } + + /* if (!canSetSpawn(level)) { + level.removeBlock(p_49517_, false); + BlockPos blockpos = p_49517_.relative(p_49515_.getValue(FACING).getOpposite()); + if (level.getBlockState(blockpos).is((BedBlock) (Object) this)) { + level.removeBlock(blockpos, false); + } + + level.explode((Entity) null, DamageSource.badRespawnPointExplosion(), (ExplosionDamageCalculator) null, (double) p_49517_.getX() + 0.5D, (double) p_49517_.getY() + 0.5D, (double) p_49517_.getZ() + 0.5D, 5.0F, true, Explosion.BlockInteraction.DESTROY); + return InteractionResult.SUCCESS; + } else */ + if (p_49515_.getValue(OCCUPIED)) { + if (!this.kickVillagerOutOfBed(level, p_49517_)) { + p_49518_.displayClientMessage(Component.translatable("block.minecraft.bed.occupied"), true); + } + + return InteractionResult.SUCCESS; + } else { + var pos = p_49517_; + var state = p_49515_; + p_49518_.startSleepInBed(pos).ifLeft((p_49477_) -> { + if (!level.dimensionType().bedWorks()) { + level.removeBlock(pos, false); + BlockPos blockpos = pos.relative(state.getValue(FACING).getOpposite()); + if (level.getBlockState(blockpos).is((BedBlock) (Object) this)) { + level.removeBlock(blockpos, false); + } + + level.explode(null, DamageSource.badRespawnPointExplosion(), null, (double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D, 5.0F, true, Explosion.BlockInteraction.DESTROY); + } else if (p_49477_.getMessage() != null) { + p_49518_.displayClientMessage(p_49477_.getMessage(), true); + } + }); + return InteractionResult.SUCCESS; + } + } + } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/BigDripleafBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/BigDripleafBlockMixin.java new file mode 100644 index 00000000..d8df6dcf --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/BigDripleafBlockMixin.java @@ -0,0 +1,57 @@ +package io.izzel.arclight.common.mixin.core.world.level.block; + +import io.izzel.arclight.common.bridge.core.entity.EntityBridge; +import io.izzel.arclight.common.mod.util.DistValidate; +import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.projectile.Projectile; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.BigDripleafBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.EnumProperty; +import net.minecraft.world.level.block.state.properties.Tilt; +import net.minecraft.world.phys.BlockHitResult; +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.v.block.CraftBlock; +import org.bukkit.craftbukkit.v.event.CraftEventFactory; +import org.bukkit.event.entity.EntityInteractEvent; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(BigDripleafBlock.class) +public class BigDripleafBlockMixin { + + @Shadow @Final private static EnumProperty TILT; + + @Inject(method = "onProjectileHit", cancellable = true, at = @At("HEAD")) + private void arclight$projectileHit(Level level, BlockState state, BlockHitResult hitResult, Projectile projectile, CallbackInfo ci) { + if (DistValidate.isValid(level) && CraftEventFactory.callEntityChangeBlockEvent(projectile, hitResult.getBlockPos(), state.setValue(TILT, Tilt.FULL)).isCancelled()) { + ci.cancel(); + } + } + + @Inject(method = "entityInside", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/BigDripleafBlock;setTiltAndScheduleTick(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/properties/Tilt;Lnet/minecraft/sounds/SoundEvent;)V")) + private void arclight$entityInteract(BlockState state, Level level, BlockPos pos, Entity entity, CallbackInfo ci) { + if (!DistValidate.isValid(level)) return; + org.bukkit.event.Cancellable cancellable; + if (entity instanceof Player) { + cancellable = CraftEventFactory.callPlayerInteractEvent((Player) entity, org.bukkit.event.block.Action.PHYSICAL, pos, null, null, null); + } else { + cancellable = new EntityInteractEvent(((EntityBridge) entity).bridge$getBukkitEntity(), CraftBlock.at(level, pos)); + Bukkit.getPluginManager().callEvent((EntityInteractEvent) cancellable); + } + + if (cancellable.isCancelled()) { + ci.cancel(); + return; + } + if (CraftEventFactory.callEntityChangeBlockEvent(entity, pos, state.setValue(TILT, Tilt.FULL)).isCancelled()) { + ci.cancel(); + } + } +} 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 9fea682f..b284c5b1 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 @@ -1,12 +1,14 @@ package io.izzel.arclight.common.mixin.core.world.level.block; import io.izzel.arclight.common.bridge.core.block.BlockBridge; +import io.izzel.arclight.common.bridge.core.entity.player.PlayerEntityBridge; 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; +import net.minecraft.util.valueproviders.IntProvider; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; @@ -23,6 +25,7 @@ import org.bukkit.craftbukkit.v.CraftWorld; import org.bukkit.craftbukkit.v.block.CraftBlock; import org.bukkit.craftbukkit.v.event.CraftEventFactory; import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.entity.EntityExhaustionEvent; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Shadow; @@ -63,15 +66,30 @@ public abstract class BlockMixin extends BlockBehaviourMixin implements BlockBri } } - public int getExpDrop(BlockState blockState, ServerLevel world, BlockPos blockPos, ItemStack itemStack) { - int silkTouch = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, itemStack); - int fortune = EnchantmentHelper.getItemEnchantmentLevel(Enchantments.BLOCK_FORTUNE, itemStack); - return ((IForgeBlock) this).getExpDrop(blockState, world, blockPos, fortune, silkTouch); + public int getExpDrop(BlockState blockState, ServerLevel world, BlockPos blockPos, ItemStack itemStack, boolean flag) { + int silkTouch = itemStack.getEnchantmentLevel(Enchantments.SILK_TOUCH); + int fortune = itemStack.getEnchantmentLevel(Enchantments.BLOCK_FORTUNE); + return ((IForgeBlock) this).getExpDrop(blockState, world, world.random, blockPos, fortune, silkTouch); + } + + protected int tryDropExperience(ServerLevel worldserver, BlockPos blockposition, ItemStack itemstack, IntProvider intprovider) { + if (EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, itemstack) == 0) { + int i = intprovider.sample(worldserver.random); + if (i > 0) { + return i; + } + } + return 0; } @Override public int bridge$getExpDrop(BlockState blockState, ServerLevel world, BlockPos blockPos, ItemStack itemStack) { - return getExpDrop(blockState, world, blockPos, itemStack); + return getExpDrop(blockState, world, blockPos, itemStack, true); + } + + @Inject(method = "playerDestroy", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Player;causeFoodExhaustion(F)V")) + private void arclight$reason(Level p_49827_, Player player, BlockPos p_49829_, BlockState p_49830_, BlockEntity p_49831_, ItemStack p_49832_, CallbackInfo ci) { + ((PlayerEntityBridge) player).bridge$pushExhaustReason(EntityExhaustionEvent.ExhaustionReason.BLOCK_MINED); } @Inject(method = "playerDestroy", at = @At("RETURN")) diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/BuddingAmethystBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/BuddingAmethystBlockMixin.java new file mode 100644 index 00000000..fce3f8b8 --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/BuddingAmethystBlockMixin.java @@ -0,0 +1,19 @@ +package io.izzel.arclight.common.mixin.core.world.level.block; + +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.block.BuddingAmethystBlock; +import net.minecraft.world.level.block.state.BlockState; +import org.bukkit.craftbukkit.v.event.CraftEventFactory; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(BuddingAmethystBlock.class) +public class BuddingAmethystBlockMixin { + + @Redirect(method = "randomTick", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;setBlockAndUpdate(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;)Z")) + private boolean arclight$blockSpread(ServerLevel instance, BlockPos pos, BlockState state, BlockState p_220898_, ServerLevel p_220899_, BlockPos oldPos) { + return CraftEventFactory.handleBlockSpreadEvent(instance, oldPos, pos, state); + } +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/ButtonBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/ButtonBlockMixin.java index 3a85e610..7534b88e 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/ButtonBlockMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/ButtonBlockMixin.java @@ -1,6 +1,17 @@ package io.izzel.arclight.common.mixin.core.world.level.block; import io.izzel.arclight.common.bridge.core.entity.EntityBridge; +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.ButtonBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.phys.BlockHitResult; import org.bukkit.Bukkit; import org.bukkit.block.Block; import org.bukkit.craftbukkit.v.block.CraftBlock; @@ -16,17 +27,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; import java.util.List; -import java.util.Random; -import net.minecraft.core.BlockPos; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.ButtonBlock; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.properties.BooleanProperty; -import net.minecraft.world.phys.BlockHitResult; @Mixin(ButtonBlock.class) public class ButtonBlockMixin { @@ -96,7 +96,7 @@ public class ButtonBlockMixin { } @Inject(method = "tick", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;setBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;I)Z")) - private void arclight$blockRedstone2(BlockState state, ServerLevel worldIn, BlockPos pos, Random rand, CallbackInfo ci) { + private void arclight$blockRedstone2(BlockState state, ServerLevel worldIn, BlockPos pos, RandomSource rand, CallbackInfo ci) { Block block = CraftBlock.at(worldIn, pos); BlockRedstoneEvent event = new BlockRedstoneEvent(block, 15, 0); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/ChangeOverTimeBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/ChangeOverTimeBlockMixin.java new file mode 100644 index 00000000..f80cd3e7 --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/ChangeOverTimeBlockMixin.java @@ -0,0 +1,71 @@ +package io.izzel.arclight.common.mixin.core.world.level.block; + +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.ChangeOverTimeBlock; +import net.minecraft.world.level.block.state.BlockState; +import org.bukkit.craftbukkit.v.event.CraftEventFactory; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; + +import java.util.Optional; + +@Mixin(ChangeOverTimeBlock.class) +public interface ChangeOverTimeBlockMixin> { + + // @formatter:off + @Shadow T getAge(); + @Shadow float getChanceModifier(); + @Shadow Optional getNext(BlockState p_153040_); + // @formatter:on + + /** + * @author IzzelAliz + * @reason + */ + @Overwrite + default void applyChangeOverTime(BlockState p_220953_, ServerLevel level, BlockPos pos, RandomSource p_220956_) { + int i = this.getAge().ordinal(); + int j = 0; + int k = 0; + + for (BlockPos blockpos : BlockPos.withinManhattan(pos, 4, 4, 4)) { + int l = blockpos.distManhattan(pos); + if (l > 4) { + break; + } + + if (!blockpos.equals(pos)) { + BlockState blockstate = level.getBlockState(blockpos); + Block block = blockstate.getBlock(); + if (block instanceof ChangeOverTimeBlock) { + Enum oenum = ((ChangeOverTimeBlock) block).getAge(); + if (this.getAge().getClass() == oenum.getClass()) { + int i1 = oenum.ordinal(); + if (i1 < i) { + return; + } + + if (i1 > i) { + ++k; + } else { + ++j; + } + } + } + } + } + + float f = (float) (k + 1) / (float) (k + j + 1); + float f1 = f * f * this.getChanceModifier(); + if (p_220956_.nextFloat() < f1) { + this.getNext(p_220953_).ifPresent((newState) -> { + // level.setBlockAndUpdate(pos, newState); + CraftEventFactory.handleBlockFormEvent(level, pos, newState); + }); + } + } +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/ChorusFlowerBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/ChorusFlowerBlockMixin.java index 52c67464..1408f7ef 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/ChorusFlowerBlockMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/ChorusFlowerBlockMixin.java @@ -3,6 +3,7 @@ package io.izzel.arclight.common.mixin.core.world.level.block; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; import net.minecraft.world.entity.projectile.Projectile; import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelReader; @@ -23,7 +24,6 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import javax.annotation.Nullable; -import java.util.Random; @Mixin(ChorusFlowerBlock.class) public abstract class ChorusFlowerBlockMixin extends BlockMixin { @@ -41,7 +41,7 @@ public abstract class ChorusFlowerBlockMixin extends BlockMixin { * @reason */ @Overwrite - public void randomTick(BlockState state, ServerLevel worldIn, BlockPos pos, Random random) { + public void randomTick(BlockState state, ServerLevel worldIn, BlockPos pos, RandomSource random) { BlockPos blockpos = pos.above(); if (worldIn.isEmptyBlock(blockpos) && blockpos.getY() < 256) { int i = state.getValue(AGE); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/CoralBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/CoralBlockMixin.java index 54a3f29c..df74b296 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/CoralBlockMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/CoralBlockMixin.java @@ -2,6 +2,7 @@ package io.izzel.arclight.common.mixin.core.world.level.block; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.CoralBlock; import net.minecraft.world.level.block.state.BlockState; @@ -13,8 +14,6 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.util.Random; - @Mixin(CoralBlock.class) public class CoralBlockMixin { @@ -23,7 +22,7 @@ public class CoralBlockMixin { // @formatter:on @Inject(method = "tick", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;setBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;I)Z")) - public void arclight$blockFade(BlockState state, ServerLevel worldIn, BlockPos pos, Random random, CallbackInfo ci) { + public void arclight$blockFade(BlockState state, ServerLevel worldIn, BlockPos pos, RandomSource random, CallbackInfo ci) { if (CraftEventFactory.callBlockFadeEvent(worldIn, pos, this.deadBlock.defaultBlockState()).isCancelled()) { ci.cancel(); } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/CoralFanBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/CoralFanBlockMixin.java index bdd8c1d9..f936b326 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/CoralFanBlockMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/CoralFanBlockMixin.java @@ -2,6 +2,7 @@ package io.izzel.arclight.common.mixin.core.world.level.block; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; import net.minecraft.world.level.block.BaseCoralPlantTypeBlock; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.CoralFanBlock; @@ -14,8 +15,6 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.util.Random; - @Mixin(CoralFanBlock.class) public class CoralFanBlockMixin { @@ -24,7 +23,7 @@ public class CoralFanBlockMixin { // @formatter:on @Inject(method = "tick", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;setBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;I)Z")) - public void arclight$blockFade(BlockState state, ServerLevel worldIn, BlockPos pos, Random random, CallbackInfo ci) { + public void arclight$blockFade(BlockState state, ServerLevel worldIn, BlockPos pos, RandomSource random, CallbackInfo ci) { if (CraftEventFactory.callBlockFadeEvent(worldIn, pos, this.deadBlock.defaultBlockState().setValue(BaseCoralPlantTypeBlock.WATERLOGGED, false)).isCancelled()) { ci.cancel(); } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/CoralPlantBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/CoralPlantBlockMixin.java index 7f1d4718..bc89d4f8 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/CoralPlantBlockMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/CoralPlantBlockMixin.java @@ -2,6 +2,7 @@ package io.izzel.arclight.common.mixin.core.world.level.block; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; import net.minecraft.world.level.block.BaseCoralPlantTypeBlock; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.CoralPlantBlock; @@ -14,8 +15,6 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.util.Random; - @Mixin(CoralPlantBlock.class) public class CoralPlantBlockMixin { @@ -24,7 +23,7 @@ public class CoralPlantBlockMixin { // @formatter:on @Inject(method = "tick", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;setBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;I)Z")) - public void arclight$blockFade(BlockState state, ServerLevel worldIn, BlockPos pos, Random random, CallbackInfo ci) { + public void arclight$blockFade(BlockState state, ServerLevel worldIn, BlockPos pos, RandomSource random, CallbackInfo ci) { if (CraftEventFactory.callBlockFadeEvent(worldIn, pos, this.deadBlock.defaultBlockState().setValue(BaseCoralPlantTypeBlock.WATERLOGGED, false)).isCancelled()) { ci.cancel(); } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/CoralWallFanBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/CoralWallFanBlockMixin.java index 1839a10a..e5c8f59a 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/CoralWallFanBlockMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/CoralWallFanBlockMixin.java @@ -2,6 +2,7 @@ package io.izzel.arclight.common.mixin.core.world.level.block; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; import net.minecraft.world.level.block.BaseCoralPlantTypeBlock; import net.minecraft.world.level.block.BaseCoralWallFanBlock; import net.minecraft.world.level.block.Block; @@ -15,8 +16,6 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.util.Random; - @Mixin(CoralWallFanBlock.class) public class CoralWallFanBlockMixin { @@ -25,7 +24,7 @@ public class CoralWallFanBlockMixin { // @formatter:on @Inject(method = "tick", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;setBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;I)Z")) - public void arclight$blockFade(BlockState state, ServerLevel worldIn, BlockPos pos, Random random, CallbackInfo ci) { + public void arclight$blockFade(BlockState state, ServerLevel worldIn, BlockPos pos, RandomSource random, CallbackInfo ci) { if (CraftEventFactory.callBlockFadeEvent(worldIn, pos, this.deadBlock.defaultBlockState() .setValue(BaseCoralPlantTypeBlock.WATERLOGGED, Boolean.FALSE) .setValue(BaseCoralWallFanBlock.FACING, state.getValue(BaseCoralWallFanBlock.FACING))).isCancelled()) { diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/DiodeBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/DiodeBlockMixin.java index 2c5c5ae1..38936243 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/DiodeBlockMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/DiodeBlockMixin.java @@ -2,6 +2,7 @@ package io.izzel.arclight.common.mixin.core.world.level.block; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; import net.minecraft.world.level.block.DiodeBlock; import net.minecraft.world.level.block.state.BlockState; import org.bukkit.craftbukkit.v.event.CraftEventFactory; @@ -10,20 +11,18 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.util.Random; - @Mixin(DiodeBlock.class) public class DiodeBlockMixin { @Inject(method = "tick", cancellable = true, at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/server/level/ServerLevel;setBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;I)Z")) - public void arclight$turnOff(BlockState state, ServerLevel worldIn, BlockPos pos, Random random, CallbackInfo ci) { + public void arclight$turnOff(BlockState state, ServerLevel worldIn, BlockPos pos, RandomSource random, CallbackInfo ci) { if (CraftEventFactory.callRedstoneChange(worldIn, pos, 15, 0).getNewCurrent() != 0) { ci.cancel(); } } @Inject(method = "tick", cancellable = true, at = @At(value = "INVOKE", ordinal = 1, target = "Lnet/minecraft/server/level/ServerLevel;setBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;I)Z")) - public void arclight$turnOn(BlockState state, ServerLevel worldIn, BlockPos pos, Random random, CallbackInfo ci) { + public void arclight$turnOn(BlockState state, ServerLevel worldIn, BlockPos pos, RandomSource random, CallbackInfo ci) { if (CraftEventFactory.callRedstoneChange(worldIn, pos, 0, 15).getNewCurrent() != 15) { ci.cancel(); } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/DirtPathBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/DirtPathBlockMixin.java new file mode 100644 index 00000000..260750da --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/DirtPathBlockMixin.java @@ -0,0 +1,22 @@ +package io.izzel.arclight.common.mixin.core.world.level.block; + +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.block.DirtPathBlock; +import net.minecraft.world.level.block.state.BlockState; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(DirtPathBlock.class) +public class DirtPathBlockMixin { + + @Inject(method = "tick", cancellable = true, at = @At("HEAD")) + private void arclight$checkValid(BlockState state, ServerLevel level, BlockPos pos, RandomSource p_221073_, CallbackInfo ci) { + if (!state.canSurvive(level, pos)) { + ci.cancel(); + } + } +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/DropperBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/DropperBlockMixin.java index 2bd6a36e..f6b69e34 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/DropperBlockMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/DropperBlockMixin.java @@ -36,7 +36,7 @@ public class DropperBlockMixin { public void dispenseFrom(ServerLevel worldIn, BlockPos pos) { BlockSourceImpl proxyblocksource = new BlockSourceImpl(worldIn, pos); DispenserBlockEntity dispensertileentity = proxyblocksource.getEntity(); - int i = dispensertileentity.getRandomSlot(); + int i = dispensertileentity.getRandomSlot(worldIn.getRandom()); if (i < 0) { worldIn.levelEvent(1001, pos, 0); } else { diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/FireBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/FireBlockMixin.java index 521783b4..4414d9f1 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/FireBlockMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/FireBlockMixin.java @@ -5,6 +5,7 @@ import it.unimi.dsi.fastutil.objects.Object2IntMap; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelAccessor; @@ -27,8 +28,6 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.util.Random; - @Mixin(FireBlock.class) public abstract class FireBlockMixin extends BaseFireBlockMixin implements FireBlockBridge { @@ -57,7 +56,7 @@ public abstract class FireBlockMixin extends BaseFireBlockMixin implements FireB } @Inject(method = "tryCatchFire", cancellable = true, at = @At(value = "INVOKE", ordinal = 1, target = "Lnet/minecraft/world/level/Level;getBlockState(Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/level/block/state/BlockState;")) - public void arclight$blockBurn(Level worldIn, BlockPos pos, int chance, Random random, int age, Direction face, CallbackInfo ci) { + public void arclight$blockBurn(Level worldIn, BlockPos pos, int chance, RandomSource random, int age, Direction face, CallbackInfo ci) { Block theBlock = CraftBlock.at(worldIn, pos); Block sourceBlock = CraftBlock.at(worldIn, pos.relative(face)); BlockBurnEvent event = new BlockBurnEvent(theBlock, sourceBlock); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/FungusBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/FungusBlockMixin.java index e589fae3..2175631a 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/FungusBlockMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/FungusBlockMixin.java @@ -3,6 +3,7 @@ package io.izzel.arclight.common.mixin.core.world.level.block; import io.izzel.arclight.common.mod.util.ArclightCaptures; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.FungusBlock; import net.minecraft.world.level.block.state.BlockState; @@ -12,14 +13,12 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.util.Random; - @Mixin(FungusBlock.class) public class FungusBlockMixin { @SuppressWarnings("ConstantConditions") @Inject(method = "performBonemeal", at = @At("HEAD")) - private void arclight$captureTree(ServerLevel worldIn, Random rand, BlockPos pos, BlockState state, CallbackInfo ci) { + private void arclight$captureTree(ServerLevel worldIn, RandomSource rand, BlockPos pos, BlockState state, CallbackInfo ci) { if ((Object) this == Blocks.WARPED_FUNGUS) { ArclightCaptures.captureTreeType(TreeType.WARPED_FUNGUS); } else if ((Object) this == Blocks.CRIMSON_FUNGUS) { diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/GrowingPlantHeadBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/GrowingPlantHeadBlockMixin.java index f016c3c1..5c3f9308 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/GrowingPlantHeadBlockMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/GrowingPlantHeadBlockMixin.java @@ -2,6 +2,7 @@ package io.izzel.arclight.common.mixin.core.world.level.block; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; import net.minecraft.world.level.block.GrowingPlantHeadBlock; import net.minecraft.world.level.block.state.BlockState; import org.bukkit.craftbukkit.v.event.CraftEventFactory; @@ -9,13 +10,11 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; -import java.util.Random; - @Mixin(GrowingPlantHeadBlock.class) public class GrowingPlantHeadBlockMixin { @Redirect(method = "randomTick", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;setBlockAndUpdate(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;)Z")) - private boolean arclight$blockGrow(ServerLevel world, BlockPos to, BlockState state, BlockState state1, ServerLevel worldIn, BlockPos from, Random random) { + private boolean arclight$blockGrow(ServerLevel world, BlockPos to, BlockState state, BlockState state1, ServerLevel worldIn, BlockPos from, RandomSource random) { return CraftEventFactory.handleBlockSpreadEvent(world, from, to, state); } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/LeavesBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/LeavesBlockMixin.java index ba8100c4..e5e55c44 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/LeavesBlockMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/LeavesBlockMixin.java @@ -2,6 +2,7 @@ package io.izzel.arclight.common.mixin.core.world.level.block; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; import net.minecraft.world.level.block.LeavesBlock; import net.minecraft.world.level.block.state.BlockState; import org.bukkit.Bukkit; @@ -12,13 +13,11 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.util.Random; - @Mixin(LeavesBlock.class) public class LeavesBlockMixin { @Inject(method = "randomTick", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/LeavesBlock;dropResources(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;)V")) - public void arclight$leavesDecay(BlockState state, ServerLevel worldIn, BlockPos pos, Random random, CallbackInfo ci) { + public void arclight$leavesDecay(BlockState state, ServerLevel worldIn, BlockPos pos, RandomSource random, CallbackInfo ci) { LeavesDecayEvent event = new LeavesDecayEvent(CraftBlock.at(worldIn, pos)); Bukkit.getPluginManager().callEvent(event); if (event.isCancelled() || worldIn.getBlockState(pos).getBlock() != (Object) this) { diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/LightningRodBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/LightningRodBlockMixin.java new file mode 100644 index 00000000..a6b1d0cb --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/LightningRodBlockMixin.java @@ -0,0 +1,44 @@ +package io.izzel.arclight.common.mixin.core.world.level.block; + +import io.izzel.arclight.common.bridge.core.world.server.ServerWorldBridge; +import io.izzel.arclight.common.mod.util.DistValidate; +import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LightningBolt; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.LightningRodBlock; +import net.minecraft.world.level.block.state.BlockState; +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.v.block.CraftBlock; +import org.bukkit.event.block.BlockRedstoneEvent; +import org.bukkit.event.weather.LightningStrikeEvent; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(LightningRodBlock.class) +public class LightningRodBlockMixin { + + @Inject(method = "onLightningStrike", cancellable = true, at = @At("HEAD")) + private void arclight$redstoneChange(BlockState state, Level level, BlockPos pos, CallbackInfo ci) { + boolean powered = state.getValue(LightningRodBlock.POWERED); + int old = (powered) ? 15 : 0; + int current = (!powered) ? 15 : 0; + + BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(CraftBlock.at(level, pos), old, current); + Bukkit.getPluginManager().callEvent(eventRedstone); + + if (eventRedstone.getNewCurrent() <= 0) { + ci.cancel(); + } + } + + @Redirect(method = "onProjectileHit", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;addFreshEntity(Lnet/minecraft/world/entity/Entity;)Z")) + private boolean arclight$strikeReason(Level level, Entity entity) { + if (!DistValidate.isValid(level)) return level.addFreshEntity(entity); + ((ServerWorldBridge) level).bridge$strikeLightning((LightningBolt) entity, LightningStrikeEvent.Cause.TRIDENT); + return true; + } +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/MultifaceSpreaderMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/MultifaceSpreaderMixin.java new file mode 100644 index 00000000..e851ddf9 --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/MultifaceSpreaderMixin.java @@ -0,0 +1,31 @@ +package io.izzel.arclight.common.mixin.core.world.level.block; + +import io.izzel.arclight.common.mod.util.ArclightCaptures; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.MultifaceSpreader; +import net.minecraft.world.level.block.state.BlockState; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.Optional; + +@Mixin(MultifaceSpreader.class) +public class MultifaceSpreaderMixin { + + @Inject(method = "getSpreadFromFaceTowardDirection", at = @At("RETURN")) + private void arclight$captureSource(BlockState p_221613_, BlockGetter p_221614_, BlockPos pos, Direction p_221616_, Direction p_221617_, MultifaceSpreader.SpreadPredicate p_221618_, CallbackInfoReturnable> cir) { + if (cir.getReturnValue().isPresent()) { + ArclightCaptures.captureSpreadSource(pos); + } + } + + @Inject(method = "spreadToFace", at = @At("RETURN")) + private void arclight$resetSource(LevelAccessor p_221594_, MultifaceSpreader.SpreadPos p_221595_, boolean p_221596_, CallbackInfoReturnable> cir) { + ArclightCaptures.resetSpreadSource(); + } +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/MultifaceSpreader_SpreadConfigMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/MultifaceSpreader_SpreadConfigMixin.java new file mode 100644 index 00000000..49f2ca29 --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/MultifaceSpreader_SpreadConfigMixin.java @@ -0,0 +1,41 @@ +package io.izzel.arclight.common.mixin.core.world.level.block; + +import io.izzel.arclight.common.mod.util.ArclightCaptures; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.MultifaceSpreader; +import net.minecraft.world.level.block.state.BlockState; +import org.bukkit.craftbukkit.v.event.CraftEventFactory; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; + +import javax.annotation.Nullable; + +@Mixin(MultifaceSpreader.SpreadConfig.class) +public interface MultifaceSpreader_SpreadConfigMixin { + + // @formatter:off + @Shadow @Nullable BlockState getStateForPlacement(BlockState p_221707_, BlockGetter p_221708_, BlockPos p_221709_, Direction p_221710_); + // @formatter:on + + /** + * @author IzzelAliz + * @reason + */ + @Overwrite + default boolean placeBlock(LevelAccessor level, MultifaceSpreader.SpreadPos spreadPos, BlockState state, boolean p_221705_) { + BlockState blockstate = this.getStateForPlacement(state, level, spreadPos.pos(), spreadPos.face()); + if (blockstate != null) { + if (p_221705_) { + level.getChunk(spreadPos.pos()).markPosForPostprocessing(spreadPos.pos()); + } + + return CraftEventFactory.handleBlockSpreadEvent(level, ArclightCaptures.getSpreadPos(), spreadPos.pos(), blockstate, 2); + } else { + return false; + } + } +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/MushroomBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/MushroomBlockMixin.java index 3850acad..d7d719d2 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/MushroomBlockMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/MushroomBlockMixin.java @@ -3,6 +3,7 @@ package io.izzel.arclight.common.mixin.core.world.level.block; import io.izzel.arclight.common.mod.util.ArclightCaptures; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.MushroomBlock; import net.minecraft.world.level.block.state.BlockState; @@ -14,8 +15,6 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import java.util.Random; - @Mixin(MushroomBlock.class) public class MushroomBlockMixin { @@ -25,8 +24,8 @@ public class MushroomBlockMixin { } @SuppressWarnings("ConstantConditions") - @Inject(method = "growMushroom(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Ljava/util/Random;)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/levelgen/feature/ConfiguredFeature;place(Lnet/minecraft/world/level/WorldGenLevel;Lnet/minecraft/world/level/chunk/ChunkGenerator;Ljava/util/Random;Lnet/minecraft/core/BlockPos;)Z")) - private void arclight$captureTree(ServerLevel world, BlockPos pos, BlockState state, Random rand, CallbackInfoReturnable cir) { + @Inject(method = "growMushroom", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/levelgen/feature/ConfiguredFeature;place(Lnet/minecraft/world/level/WorldGenLevel;Lnet/minecraft/world/level/chunk/ChunkGenerator;Lnet/minecraft/util/RandomSource;Lnet/minecraft/core/BlockPos;)Z")) + private void arclight$captureTree(ServerLevel world, BlockPos pos, BlockState state, RandomSource rand, CallbackInfoReturnable cir) { if ((Object) this == Blocks.BROWN_MUSHROOM) { ArclightCaptures.captureTreeType(TreeType.BROWN_MUSHROOM); } else if ((Object) this == Blocks.RED_MUSHROOM) { diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/NoteBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/NoteBlockMixin.java index 14be3af3..f5b72757 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/NoteBlockMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/NoteBlockMixin.java @@ -1,7 +1,7 @@ package io.izzel.arclight.common.mixin.core.world.level.block; -import io.izzel.arclight.common.bridge.core.block.NoteBlockBridge; import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.Entity; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.NoteBlock; import net.minecraft.world.level.block.state.BlockState; @@ -15,42 +15,37 @@ import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(NoteBlock.class) -public abstract class NoteBlockMixin implements NoteBlockBridge { +public abstract class NoteBlockMixin { // @formatter:off - @Shadow protected abstract void playNote(Level worldIn, BlockPos pos); + @Shadow protected abstract void playNote(Entity entity, Level worldIn, BlockPos pos); // @formatter:on - @Redirect(method = "use", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/NoteBlock;playNote(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;)V")) - public void arclight$callNote2(NoteBlock noteBlock, Level worldIn, BlockPos pos, BlockState blockState) { - this.bridge$play(worldIn, pos, blockState); + @Redirect(method = "use", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/NoteBlock;playNote(Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;)V")) + public void arclight$callNote2(NoteBlock noteBlock, Entity entity, Level worldIn, BlockPos pos, BlockState blockState) { + this.playNote(entity, worldIn, pos, blockState); } - @Redirect(method = "neighborChanged", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/NoteBlock;playNote(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;)V")) - public void arclight$callNote1(NoteBlock noteBlock, Level worldIn, BlockPos pos, BlockState blockState) { - this.play(worldIn, pos, blockState); + @Redirect(method = "neighborChanged", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/NoteBlock;playNote(Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;)V")) + public void arclight$callNote1(NoteBlock noteBlock, Entity entity, Level worldIn, BlockPos pos, BlockState blockState) { + this.playNote(entity, worldIn, pos, blockState); } - @Redirect(method = "attack", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/NoteBlock;playNote(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;)V")) - public void arclight$callNote3(NoteBlock noteBlock, Level worldIn, BlockPos pos, BlockState blockState) { - this.play(worldIn, pos, blockState); + @Redirect(method = "attack", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/NoteBlock;playNote(Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;)V")) + public void arclight$callNote3(NoteBlock noteBlock, Entity entity, Level worldIn, BlockPos pos, BlockState blockState) { + this.playNote(entity, worldIn, pos, blockState); } private transient BlockState arclight$state; - private void play(Level worldIn, BlockPos pos, BlockState state) { + private void playNote(Entity entity, Level worldIn, BlockPos pos, BlockState state) { arclight$state = state; - this.playNote(worldIn, pos); + this.playNote(entity, worldIn, pos); arclight$state = null; } - @Override - public void bridge$play(Level worldIn, BlockPos pos, BlockState state) { - this.play(worldIn, pos, state); - } - @Inject(method = "playNote", cancellable = true, require = 0, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;blockEvent(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/Block;II)V")) - private void arclight$notePlay(Level worldIn, BlockPos pos, CallbackInfo ci) { + private void arclight$notePlay(Entity entity, Level worldIn, BlockPos pos, CallbackInfo ci) { NotePlayEvent event = CraftEventFactory.callNotePlayEvent(worldIn, pos, arclight$state.getValue(NoteBlock.INSTRUMENT), arclight$state.getValue(NoteBlock.NOTE)); if (event.isCancelled()) { ci.cancel(); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/NyliumBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/NyliumBlockMixin.java new file mode 100644 index 00000000..9921993a --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/NyliumBlockMixin.java @@ -0,0 +1,24 @@ +package io.izzel.arclight.common.mixin.core.world.level.block; + +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.NyliumBlock; +import net.minecraft.world.level.block.state.BlockState; +import org.bukkit.craftbukkit.v.event.CraftEventFactory; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(NyliumBlock.class) +public class NyliumBlockMixin { + + @Inject(method = "randomTick", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;setBlockAndUpdate(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;)Z")) + private void arclight$blockFade(BlockState p_221835_, ServerLevel level, BlockPos pos, RandomSource p_221838_, CallbackInfo ci) { + if (CraftEventFactory.callBlockFadeEvent(level, pos, Blocks.NETHERRACK.defaultBlockState()).isCancelled()) { + ci.cancel(); + } + } +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/ObserverBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/ObserverBlockMixin.java index 34c183a5..2f03f483 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/ObserverBlockMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/ObserverBlockMixin.java @@ -2,6 +2,7 @@ package io.izzel.arclight.common.mixin.core.world.level.block; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; import net.minecraft.world.level.block.ObserverBlock; import net.minecraft.world.level.block.state.BlockState; import org.bukkit.craftbukkit.v.event.CraftEventFactory; @@ -10,20 +11,18 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.util.Random; - @Mixin(ObserverBlock.class) public class ObserverBlockMixin { @Inject(method = "tick", cancellable = true, at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/server/level/ServerLevel;setBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;I)Z")) - public void arclight$redstoneChange1(BlockState state, ServerLevel worldIn, BlockPos pos, Random random, CallbackInfo ci) { + public void arclight$redstoneChange1(BlockState state, ServerLevel worldIn, BlockPos pos, RandomSource random, CallbackInfo ci) { if (CraftEventFactory.callRedstoneChange(worldIn, pos, 15, 0).getNewCurrent() != 0) { ci.cancel(); } } @Inject(method = "tick", cancellable = true, at = @At(value = "INVOKE", ordinal = 1, target = "Lnet/minecraft/server/level/ServerLevel;setBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;I)Z")) - public void arclight$redstoneChange2(BlockState state, ServerLevel worldIn, BlockPos pos, Random random, CallbackInfo ci) { + public void arclight$redstoneChange2(BlockState state, ServerLevel worldIn, BlockPos pos, RandomSource random, CallbackInfo ci) { if (CraftEventFactory.callRedstoneChange(worldIn, pos, 0, 15).getNewCurrent() != 15) { ci.cancel(); } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/PointedDripstoneBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/PointedDripstoneBlockMixin.java index a40f4269..d391a5e8 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/PointedDripstoneBlockMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/PointedDripstoneBlockMixin.java @@ -3,16 +3,23 @@ package io.izzel.arclight.common.mixin.core.world.level.block; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.projectile.Projectile; +import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.PointedDripstoneBlock; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.DripstoneThickness; import net.minecraft.world.level.material.Fluids; +import net.minecraft.world.phys.BlockHitResult; +import org.bukkit.craftbukkit.v.block.CraftBlock; import org.bukkit.craftbukkit.v.event.CraftEventFactory; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import static net.minecraft.world.level.block.PointedDripstoneBlock.THICKNESS; import static net.minecraft.world.level.block.PointedDripstoneBlock.TIP_DIRECTION; @@ -21,6 +28,23 @@ import static net.minecraft.world.level.block.PointedDripstoneBlock.WATERLOGGED; @Mixin(PointedDripstoneBlock.class) public class PointedDripstoneBlockMixin { + @Inject(method = "onProjectileHit", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;destroyBlock(Lnet/minecraft/core/BlockPos;Z)Z")) + private void arclight$projectile(Level p_154042_, BlockState p_154043_, BlockHitResult hitResult, Projectile projectile, CallbackInfo ci) { + if (CraftEventFactory.callEntityChangeBlockEvent(projectile, hitResult.getBlockPos(), Blocks.AIR.defaultBlockState()).isCancelled()) { + ci.cancel(); + } + } + + @Inject(method = "fallOn", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;causeFallDamage(FFLnet/minecraft/world/damagesource/DamageSource;)Z")) + private void arclight$blockDamage(Level level, BlockState p_154048_, BlockPos pos, Entity p_154050_, float p_154051_, CallbackInfo ci) { + CraftEventFactory.blockDamage = CraftBlock.at(level, pos); + } + + @Inject(method = "fallOn", at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/world/entity/Entity;causeFallDamage(FFLnet/minecraft/world/damagesource/DamageSource;)Z")) + private void arclight$blockDamageReset(Level level, BlockState p_154048_, BlockPos pos, Entity p_154050_, float p_154051_, CallbackInfo ci) { + CraftEventFactory.blockDamage = CraftBlock.at(level, pos); + } + @Redirect(method = "createMergedTips", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/PointedDripstoneBlock;createDripstone(Lnet/minecraft/world/level/LevelAccessor;Lnet/minecraft/core/BlockPos;Lnet/minecraft/core/Direction;Lnet/minecraft/world/level/block/state/properties/DripstoneThickness;)V")) private static void arclight$changeBlock1(LevelAccessor level, BlockPos pos, Direction direction, DripstoneThickness thickness, BlockState p_154231_, LevelAccessor p_154232_, BlockPos source) { diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/PowderSnowBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/PowderSnowBlockMixin.java new file mode 100644 index 00000000..99ef49f9 --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/PowderSnowBlockMixin.java @@ -0,0 +1,24 @@ +package io.izzel.arclight.common.mixin.core.world.level.block; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.PowderSnowBlock; +import net.minecraft.world.level.block.state.BlockState; +import org.bukkit.craftbukkit.v.event.CraftEventFactory; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(PowderSnowBlock.class) +public class PowderSnowBlockMixin { + + @Inject(method = "entityInside", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;destroyBlock(Lnet/minecraft/core/BlockPos;Z)Z")) + private void arclight$entityChangeBlock(BlockState p_154263_, Level p_154264_, BlockPos pos, Entity entity, CallbackInfo ci) { + if (CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.AIR.defaultBlockState()).isCancelled()) { + ci.cancel(); + } + } +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/RedstoneLampBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/RedstoneLampBlockMixin.java index 4e2ed69c..bd8c3e69 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/RedstoneLampBlockMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/RedstoneLampBlockMixin.java @@ -2,6 +2,7 @@ package io.izzel.arclight.common.mixin.core.world.level.block; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.RedstoneLampBlock; @@ -12,13 +13,11 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.util.Random; - @Mixin(RedstoneLampBlock.class) public class RedstoneLampBlockMixin { @Inject(method = "tick", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;setBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;I)Z")) - private void arclight$redstoneChange(BlockState state, ServerLevel worldIn, BlockPos pos, Random rand, CallbackInfo ci) { + private void arclight$redstoneChange(BlockState state, ServerLevel worldIn, BlockPos pos, RandomSource rand, CallbackInfo ci) { if (CraftEventFactory.callRedstoneChange(worldIn, pos, 15, 0).getNewCurrent() != 0) { ci.cancel(); } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/RedstoneOreBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/RedstoneOreBlockMixin.java index 2ce0a271..7e23e69c 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/RedstoneOreBlockMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/RedstoneOreBlockMixin.java @@ -3,6 +3,7 @@ package io.izzel.arclight.common.mixin.core.world.level.block; import io.izzel.arclight.common.bridge.core.entity.EntityBridge; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; @@ -23,8 +24,6 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import java.util.Random; - @Mixin(RedStoneOreBlock.class) public abstract class RedstoneOreBlockMixin { @@ -64,7 +63,7 @@ public abstract class RedstoneOreBlockMixin { } @Inject(method = "randomTick", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;setBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;I)Z")) - private void arclight$blockFade(BlockState state, ServerLevel worldIn, BlockPos pos, Random random, CallbackInfo ci) { + private void arclight$blockFade(BlockState state, ServerLevel worldIn, BlockPos pos, RandomSource random, CallbackInfo ci) { if (CraftEventFactory.callBlockFadeEvent(worldIn, pos, state.setValue(RedStoneOreBlock.LIT, false)).isCancelled()) { ci.cancel(); } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/RedstoneTorchBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/RedstoneTorchBlockMixin.java index 588a39c5..f4b9649a 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/RedstoneTorchBlockMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/RedstoneTorchBlockMixin.java @@ -2,6 +2,7 @@ package io.izzel.arclight.common.mixin.core.world.level.block; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; import net.minecraft.world.level.block.RedstoneTorchBlock; import net.minecraft.world.level.block.state.BlockState; import org.bukkit.Bukkit; @@ -12,13 +13,11 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.util.Random; - @Mixin(RedstoneTorchBlock.class) public class RedstoneTorchBlockMixin { @Inject(method = "tick", cancellable = true, at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/server/level/ServerLevel;setBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;I)Z")) - private void arclight$blockRedstone1(BlockState state, ServerLevel worldIn, BlockPos pos, Random rand, CallbackInfo ci) { + private void arclight$blockRedstone1(BlockState state, ServerLevel worldIn, BlockPos pos, RandomSource rand, CallbackInfo ci) { int oldCurrent = state.getValue(RedstoneTorchBlock.LIT) ? 15 : 0; if (oldCurrent != 0) { CraftBlock block = CraftBlock.at(worldIn, pos); @@ -31,7 +30,7 @@ public class RedstoneTorchBlockMixin { } @Inject(method = "tick", cancellable = true, at = @At(value = "INVOKE", ordinal = 1, target = "Lnet/minecraft/server/level/ServerLevel;setBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;I)Z")) - private void arclight$blockRedstone2(BlockState state, ServerLevel worldIn, BlockPos pos, Random rand, CallbackInfo ci) { + private void arclight$blockRedstone2(BlockState state, ServerLevel worldIn, BlockPos pos, RandomSource rand, CallbackInfo ci) { int oldCurrent = state.getValue(RedstoneTorchBlock.LIT) ? 15 : 0; if (oldCurrent != 15) { CraftBlock block = CraftBlock.at(worldIn, pos); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/RootedDirtBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/RootedDirtBlockMixin.java new file mode 100644 index 00000000..06a3202b --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/RootedDirtBlockMixin.java @@ -0,0 +1,19 @@ +package io.izzel.arclight.common.mixin.core.world.level.block; + +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.block.RootedDirtBlock; +import net.minecraft.world.level.block.state.BlockState; +import org.bukkit.craftbukkit.v.event.CraftEventFactory; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(RootedDirtBlock.class) +public class RootedDirtBlockMixin { + + @Redirect(method = "performBonemeal", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;setBlockAndUpdate(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;)Z")) + private boolean arclight$blockSpread(ServerLevel instance, BlockPos pos, BlockState state) { + return CraftEventFactory.handleBlockSpreadEvent(instance, pos.above(), pos, state); + } +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/ScaffoldingBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/ScaffoldingBlockMixin.java index c870ac68..6285c74f 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/ScaffoldingBlockMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/ScaffoldingBlockMixin.java @@ -2,6 +2,7 @@ package io.izzel.arclight.common.mixin.core.world.level.block; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.ScaffoldingBlock; import net.minecraft.world.level.block.state.BlockState; @@ -11,13 +12,11 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; -import java.util.Random; - @Mixin(ScaffoldingBlock.class) public class ScaffoldingBlockMixin { @Redirect(method = "tick", at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/world/level/block/state/BlockState;getValue(Lnet/minecraft/world/level/block/state/properties/Property;)Ljava/lang/Comparable;")) - public Comparable arclight$blockFade(BlockState state, Property property, BlockState blockState, ServerLevel worldIn, BlockPos pos, Random random) { + public Comparable arclight$blockFade(BlockState state, Property property, BlockState blockState, ServerLevel worldIn, BlockPos pos, RandomSource random) { Integer integer = state.getValue(property); if (integer == 7) { if (CraftEventFactory.callBlockFadeEvent(worldIn, pos, Blocks.AIR.defaultBlockState()).isCancelled()) { diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/SculkBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/SculkBlockMixin.java new file mode 100644 index 00000000..b083f58c --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/SculkBlockMixin.java @@ -0,0 +1,21 @@ +package io.izzel.arclight.common.mixin.core.world.level.block; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.SculkBlock; +import net.minecraft.world.level.block.SculkSpreader; +import net.minecraft.world.level.block.state.BlockState; +import org.bukkit.craftbukkit.v.event.CraftEventFactory; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(SculkBlock.class) +public class SculkBlockMixin { + + @Redirect(method = "attemptUseCharge", 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$blockSpread(LevelAccessor level, BlockPos pos, BlockState state, int i, + SculkSpreader.ChargeCursor p_222073_, LevelAccessor p_222074_, BlockPos source) { + return CraftEventFactory.handleBlockSpreadEvent(level, source, pos, state, i); + } +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/SculkSensorBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/SculkSensorBlockMixin.java new file mode 100644 index 00000000..d2285324 --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/SculkSensorBlockMixin.java @@ -0,0 +1,65 @@ +package io.izzel.arclight.common.mixin.core.world.level.block; + +import io.izzel.arclight.common.bridge.core.entity.EntityBridge; +import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.SculkSensorBlock; +import net.minecraft.world.level.block.state.BlockState; +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.v.block.CraftBlock; +import org.bukkit.craftbukkit.v.event.CraftEventFactory; +import org.bukkit.event.block.BlockRedstoneEvent; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyVariable; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(SculkSensorBlock.class) +public class SculkSensorBlockMixin { + + @Inject(method = "stepOn", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;getBlockEntity(Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/level/block/entity/BlockEntity;")) + private void arclight$stepOn(Level level, BlockPos pos, BlockState p_222134_, Entity entity, CallbackInfo ci) { + org.bukkit.event.Cancellable cancellable; + if (entity instanceof Player) { + cancellable = CraftEventFactory.callPlayerInteractEvent((Player) entity, org.bukkit.event.block.Action.PHYSICAL, pos, null, null, null); + } else { + cancellable = new org.bukkit.event.entity.EntityInteractEvent(((EntityBridge) entity).bridge$getBukkitEntity(), CraftBlock.at(level, pos)); + Bukkit.getPluginManager().callEvent((org.bukkit.event.entity.EntityInteractEvent) cancellable); + } + if (cancellable.isCancelled()) { + ci.cancel(); + } + } + + @Inject(method = "deactivate", cancellable = true, at = @At("HEAD")) + private static void arclight$deactivate(Level level, BlockPos pos, BlockState state, CallbackInfo ci) { + BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(CraftBlock.at(level, pos), state.getValue(SculkSensorBlock.POWER), 0); + Bukkit.getPluginManager().callEvent(eventRedstone); + + if (eventRedstone.getNewCurrent() > 0) { + level.setBlock(pos, state.setValue(SculkSensorBlock.POWER, eventRedstone.getNewCurrent()), 3); + ci.cancel(); + } + } + + @Unique private static int newCurrent; + + @Inject(method = "activate", cancellable = true, at = @At("HEAD")) + private static void arclight$activate(Entity p_222126_, Level level, BlockPos pos, BlockState state, int i, CallbackInfo ci) { + BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(CraftBlock.at(level, pos), state.getValue(SculkSensorBlock.POWER), i); + Bukkit.getPluginManager().callEvent(eventRedstone); + if (eventRedstone.getNewCurrent() <= 0) { + ci.cancel(); + } + newCurrent = eventRedstone.getNewCurrent(); + } + + @ModifyVariable(method = "activate", ordinal = 0, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;setBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;I)Z"), argsOnly = true) + private static int arclight$updateCurrent(int old) { + return newCurrent; + } +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/SculkShriekerBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/SculkShriekerBlockMixin.java new file mode 100644 index 00000000..9bafa513 --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/SculkShriekerBlockMixin.java @@ -0,0 +1,27 @@ +package io.izzel.arclight.common.mixin.core.world.level.block; + +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.SculkShriekerBlock; +import net.minecraft.world.level.block.state.BlockState; +import org.bukkit.craftbukkit.v.event.CraftEventFactory; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; + +@Mixin(SculkShriekerBlock.class) +public class SculkShriekerBlockMixin { + + @Inject(method = "stepOn", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;getBlockEntity(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/entity/BlockEntityType;)Ljava/util/Optional;")) + private void arclight$interact(Level p_222177_, BlockPos pos, BlockState p_222179_, Entity p_222180_, CallbackInfo ci, + ServerLevel level, ServerPlayer player) { + if (CraftEventFactory.callPlayerInteractEvent(player, org.bukkit.event.block.Action.PHYSICAL, pos, null, null, null).isCancelled()) { + ci.cancel(); + } + } +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/SculkVeinBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/SculkVeinBlockMixin.java new file mode 100644 index 00000000..e329dee6 --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/SculkVeinBlockMixin.java @@ -0,0 +1,38 @@ +package io.izzel.arclight.common.mixin.core.world.level.block; + +import io.izzel.arclight.common.mod.util.ArclightCaptures; +import io.izzel.arclight.mixin.Eject; +import net.minecraft.core.BlockPos; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.SculkSpreader; +import net.minecraft.world.level.block.SculkVeinBlock; +import net.minecraft.world.level.block.state.BlockState; +import org.bukkit.craftbukkit.v.event.CraftEventFactory; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(SculkVeinBlock.class) +public class SculkVeinBlockMixin { + + @Inject(method = "attemptUseCharge", at = @At("HEAD")) + private void arclight$captureSource(SculkSpreader.ChargeCursor p_222369_, LevelAccessor p_222370_, BlockPos source, RandomSource p_222372_, SculkSpreader p_222373_, boolean p_222374_, CallbackInfoReturnable cir) { + ArclightCaptures.captureSpreadSource(source); + } + + @Inject(method = "attemptUseCharge", at = @At("RETURN")) + private void arclight$resetSource(SculkSpreader.ChargeCursor p_222369_, LevelAccessor p_222370_, BlockPos source, RandomSource p_222372_, SculkSpreader p_222373_, boolean p_222374_, CallbackInfoReturnable cir) { + ArclightCaptures.resetSpreadSource(); + } + + @Eject(method = "attemptPlaceSculk", 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$blockSpread(LevelAccessor level, BlockPos pos, BlockState state, int i, CallbackInfoReturnable cir) { + if (!CraftEventFactory.handleBlockSpreadEvent(level, ArclightCaptures.getSpreadPos(), pos, state, i)) { + cir.setReturnValue(false); + return false; + } + return true; + } +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/SnowBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/SnowBlockMixin.java index c1f01d97..79e240e2 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/SnowBlockMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/SnowBlockMixin.java @@ -2,6 +2,7 @@ package io.izzel.arclight.common.mixin.core.world.level.block; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.SnowLayerBlock; import net.minecraft.world.level.block.state.BlockState; @@ -11,13 +12,11 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.util.Random; - @Mixin(SnowLayerBlock.class) public class SnowBlockMixin { @Inject(method = "randomTick", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/SnowLayerBlock;dropResources(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;)V")) - public void arclight$blockFade(BlockState state, ServerLevel worldIn, BlockPos pos, Random random, CallbackInfo ci) { + public void arclight$blockFade(BlockState state, ServerLevel worldIn, BlockPos pos, RandomSource random, CallbackInfo ci) { if (CraftEventFactory.callBlockFadeEvent(worldIn, pos, Blocks.AIR.defaultBlockState()).isCancelled()) { ci.cancel(); } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/SnowLayerBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/SnowLayerBlockMixin.java new file mode 100644 index 00000000..e7be2ea2 --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/SnowLayerBlockMixin.java @@ -0,0 +1,24 @@ +package io.izzel.arclight.common.mixin.core.world.level.block; + +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.SnowLayerBlock; +import net.minecraft.world.level.block.state.BlockState; +import org.bukkit.craftbukkit.v.event.CraftEventFactory; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(SnowLayerBlock.class) +public class SnowLayerBlockMixin { + + @Inject(method = "randomTick", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/SnowLayerBlock;dropResources(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;)V")) + private void arclight$blockFade(BlockState p_222448_, ServerLevel level, BlockPos pos, RandomSource p_222451_, CallbackInfo ci) { + if (CraftEventFactory.callBlockFadeEvent(level, pos, Blocks.AIR.defaultBlockState()).isCancelled()) { + ci.cancel(); + } + } +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/SpreadableSnowyDirtBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/SpreadableSnowyDirtBlockMixin.java index bcc07f0a..52909236 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/SpreadableSnowyDirtBlockMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/SpreadableSnowyDirtBlockMixin.java @@ -2,6 +2,7 @@ package io.izzel.arclight.common.mixin.core.world.level.block; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.SpreadingSnowyDirtBlock; import net.minecraft.world.level.block.state.BlockState; @@ -12,13 +13,11 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.util.Random; - @Mixin(SpreadingSnowyDirtBlock.class) public class SpreadableSnowyDirtBlockMixin { @Inject(method = "randomTick", cancellable = true, at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/server/level/ServerLevel;setBlockAndUpdate(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;)Z")) - public void arclight$blockFade(BlockState state, ServerLevel worldIn, BlockPos pos, Random random, CallbackInfo ci) { + public void arclight$blockFade(BlockState state, ServerLevel worldIn, BlockPos pos, RandomSource random, CallbackInfo ci) { if (CraftEventFactory.callBlockFadeEvent(worldIn, pos, Blocks.DIRT.defaultBlockState()).isCancelled()) { ci.cancel(); } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/StemBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/StemBlockMixin.java index e032d2ea..58797ece 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/StemBlockMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/StemBlockMixin.java @@ -1,5 +1,6 @@ package io.izzel.arclight.common.mixin.core.world.level.block; +import io.izzel.arclight.mixin.Eject; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.block.StemBlock; @@ -7,33 +8,23 @@ import net.minecraft.world.level.block.state.BlockState; import org.bukkit.craftbukkit.v.event.CraftEventFactory; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.util.Random; - @Mixin(StemBlock.class) public class StemBlockMixin { - private transient boolean arclight$success = false; - @Redirect(method = "randomTick", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;setBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;I)Z")) public boolean arclight$cropGrow1(ServerLevel world, BlockPos pos, BlockState newState, int flags) { return CraftEventFactory.handleBlockGrowEvent(world, pos, newState, flags); } - @Inject(method = "randomTick", cancellable = true, at = @At(value = "INVOKE", ordinal = 1, target = "Lnet/minecraft/server/level/ServerLevel;setBlockAndUpdate(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;)Z")) - public void arclight$returnIfFail(BlockState state, ServerLevel worldIn, BlockPos pos, Random random, CallbackInfo ci) { - if (!arclight$success) { + @Eject(method = "randomTick", at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/server/level/ServerLevel;setBlockAndUpdate(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;)Z")) + public boolean arclight$cropGrow2(ServerLevel world, BlockPos pos, BlockState state, CallbackInfo ci) { + if (!CraftEventFactory.handleBlockGrowEvent(world, pos, state)) { ci.cancel(); } - arclight$success = false; - } - - @Redirect(method = "randomTick", at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/server/level/ServerLevel;setBlockAndUpdate(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;)Z")) - public boolean arclight$cropGrow2(ServerLevel world, BlockPos pos, BlockState state) { - return arclight$success = CraftEventFactory.handleBlockGrowEvent(world, pos, state); + return true; } @Redirect(method = "performBonemeal", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;setBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;I)Z")) diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/SweetBerryBushBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/SweetBerryBushBlockMixin.java index c8cb0df4..19e80102 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/SweetBerryBushBlockMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/SweetBerryBushBlockMixin.java @@ -1,8 +1,8 @@ package io.izzel.arclight.common.mixin.core.world.level.block; +import io.izzel.arclight.mixin.Eject; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; @@ -11,7 +11,6 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.SweetBerryBushBlock; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.phys.BlockHitResult; import org.bukkit.craftbukkit.v.block.CraftBlock; import org.bukkit.craftbukkit.v.event.CraftEventFactory; import org.bukkit.craftbukkit.v.inventory.CraftItemStack; @@ -19,7 +18,6 @@ import org.bukkit.event.player.PlayerHarvestBlockEvent; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @@ -28,9 +26,12 @@ import java.util.Collections; @Mixin(SweetBerryBushBlock.class) public class SweetBerryBushBlockMixin { - @Redirect(method = "randomTick", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;setBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;I)Z")) - public boolean arclight$cropGrow(ServerLevel world, BlockPos pos, BlockState newState, int flags) { - return CraftEventFactory.handleBlockGrowEvent(world, pos, newState, flags); + @Eject(method = "randomTick", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;setBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;I)Z")) + private boolean arclight$cropGrow(ServerLevel world, BlockPos pos, BlockState newState, int flags, CallbackInfo ci) { + if (!CraftEventFactory.handleBlockGrowEvent(world, pos, newState, flags)) { + ci.cancel(); + } + return true; } @Inject(method = "entityInside", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;hurt(Lnet/minecraft/world/damagesource/DamageSource;F)Z")) @@ -43,22 +44,15 @@ public class SweetBerryBushBlockMixin { CraftEventFactory.blockDamage = null; } - @Redirect(method = "use", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/SweetBerryBushBlock;popResource(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/item/ItemStack;)V")) - private void arclight$playerHarvest(Level worldIn, BlockPos pos, ItemStack stack, BlockState state, Level worldIn1, BlockPos pos1, Player player) { + @Eject(method = "use", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/SweetBerryBushBlock;popResource(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/item/ItemStack;)V")) + private void arclight$playerHarvest(Level worldIn, BlockPos pos, ItemStack stack, CallbackInfoReturnable cir, + BlockState state, Level worldIn1, BlockPos pos1, Player player) { PlayerHarvestBlockEvent event = CraftEventFactory.callPlayerHarvestBlockEvent(worldIn, pos, player, Collections.singletonList(stack)); - arclight$ret = event.isCancelled(); if (!event.isCancelled()) { for (org.bukkit.inventory.ItemStack itemStack : event.getItemsHarvested()) { Block.popResource(worldIn, pos, CraftItemStack.asNMSCopy(itemStack)); } - } - } - - private transient boolean arclight$ret; - - @Inject(method = "use", cancellable = true, at = @At(value = "INVOKE", 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")) - private void arclight$returnIfFail(BlockState state, Level worldIn, BlockPos pos, Player player, InteractionHand handIn, BlockHitResult hit, CallbackInfoReturnable cir) { - if (arclight$ret) { + } else { cir.setReturnValue(InteractionResult.SUCCESS); } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/TntBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/TntBlockMixin.java index 37df3798..bfd70067 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/TntBlockMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/TntBlockMixin.java @@ -15,7 +15,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(TntBlock.class) public class TntBlockMixin { - @Inject(method = "onProjectileHit", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/TntBlock;onCaughtFire(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/core/Direction;Lnet/minecraft/world/entity/LivingEntity;)V")) + @Inject(method = "onProjectileHit", cancellable = true, at = @At(value = "INVOKE", remap = false, target = "Lnet/minecraft/world/level/block/TntBlock;onCaughtFire(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/core/Direction;Lnet/minecraft/world/entity/LivingEntity;)V")) public void arclight$entityChangeBlock(Level worldIn, BlockState state, BlockHitResult hit, Projectile projectile, CallbackInfo ci) { if (CraftEventFactory.callEntityChangeBlockEvent(projectile, hit.getBlockPos(), Blocks.AIR.defaultBlockState()).isCancelled()) { ci.cancel(); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/TripWireHookBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/TripWireHookBlockMixin.java index b2461764..a32e9ba0 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/TripWireHookBlockMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/TripWireHookBlockMixin.java @@ -15,7 +15,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(TripWireHookBlock.class) public class TripWireHookBlockMixin { - @Inject(method = "calculateState", cancellable = true, at = @At(value = "INVOKE", ordinal = 1, target = "Lnet/minecraft/world/level/block/TripWireHookBlock;playSound(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;ZZZZ)V")) + @Inject(method = "calculateState", cancellable = true, at = @At(value = "INVOKE", ordinal = 1, target = "Lnet/minecraft/world/level/block/TripWireHookBlock;emitState(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;ZZZZ)V")) public void arclight$blockRedstone(Level worldIn, BlockPos pos, BlockState hookState, boolean attaching, boolean shouldNotifyNeighbours, int searchRange, BlockState state, CallbackInfo ci) { BlockRedstoneEvent event = new BlockRedstoneEvent(CraftBlock.at(worldIn, pos), 15, 0); Bukkit.getPluginManager().callEvent(event); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/TurtleEggBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/TurtleEggBlockMixin.java index 05c501cd..b5563b81 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/TurtleEggBlockMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/TurtleEggBlockMixin.java @@ -4,6 +4,7 @@ import io.izzel.arclight.common.bridge.core.entity.EntityBridge; import io.izzel.arclight.common.bridge.core.world.WorldBridge; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; @@ -27,8 +28,6 @@ import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; -import java.util.Random; - @Mixin(TurtleEggBlock.class) public class TurtleEggBlockMixin { @@ -36,7 +35,7 @@ public class TurtleEggBlockMixin { @Inject(method = "randomTick", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/server/level/ServerLevel;playSound(Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/core/BlockPos;Lnet/minecraft/sounds/SoundEvent;Lnet/minecraft/sounds/SoundSource;FF)V")) - private void arclight$hatch(BlockState state, ServerLevel worldIn, BlockPos pos, Random random, CallbackInfo ci, int i) { + private void arclight$hatch(BlockState state, ServerLevel worldIn, BlockPos pos, RandomSource random, CallbackInfo ci, int i) { if (!CraftEventFactory.handleBlockGrowEvent(worldIn, pos, state.setValue(HATCH, i + 1), 2)) { ci.cancel(); } @@ -48,7 +47,7 @@ public class TurtleEggBlockMixin { } @Inject(method = "randomTick", cancellable = true, at = @At(value = "INVOKE", ordinal = 1, target = "Lnet/minecraft/server/level/ServerLevel;playSound(Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/core/BlockPos;Lnet/minecraft/sounds/SoundEvent;Lnet/minecraft/sounds/SoundSource;FF)V")) - private void arclight$born(BlockState state, ServerLevel worldIn, BlockPos pos, Random random, CallbackInfo ci) { + private void arclight$born(BlockState state, ServerLevel worldIn, BlockPos pos, RandomSource random, CallbackInfo ci) { if (CraftEventFactory.callBlockFadeEvent(worldIn, pos, Blocks.AIR.defaultBlockState()).isCancelled()) { ci.cancel(); } else { diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/VineBlockMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/VineBlockMixin.java index 730a4e3e..71dec062 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/VineBlockMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/VineBlockMixin.java @@ -3,6 +3,7 @@ package io.izzel.arclight.common.mixin.core.world.level.block; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.VineBlock; @@ -14,8 +15,6 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Shadow; -import java.util.Random; - @Mixin(VineBlock.class) public abstract class VineBlockMixin extends BlockMixin { @@ -26,7 +25,7 @@ public abstract class VineBlockMixin extends BlockMixin { @Shadow @Final public static BooleanProperty UP; @Shadow protected abstract boolean canSupportAtFace(BlockGetter blockReader, BlockPos pos, Direction direction); @Shadow protected abstract boolean hasHorizontalConnection(BlockState state); - @Shadow protected abstract BlockState copyRandomFaces(BlockState state, BlockState state2, Random rand); + @Shadow protected abstract BlockState copyRandomFaces(BlockState state, BlockState state2, RandomSource rand); // @formatter:on /** @@ -35,7 +34,7 @@ public abstract class VineBlockMixin extends BlockMixin { */ @SuppressWarnings("ConstantConditions") @Overwrite - public void randomTick(BlockState state, ServerLevel worldIn, BlockPos pos, Random random) { + public void randomTick(BlockState state, ServerLevel worldIn, BlockPos pos, RandomSource random) { if (worldIn.random.nextInt(4) == 0 && worldIn.isAreaLoaded(pos, 4)) { // Forge: check area to prevent loading unloaded chunks Direction direction = Direction.getRandom(random); BlockPos blockpos = pos.above(); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/entity/AbstractFurnaceBlockEntityMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/entity/AbstractFurnaceBlockEntityMixin.java index af274e60..2b9392d7 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/entity/AbstractFurnaceBlockEntityMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/entity/AbstractFurnaceBlockEntityMixin.java @@ -65,7 +65,7 @@ public abstract class AbstractFurnaceBlockEntityMixin extends LockableBlockEntit @Eject(method = "serverTick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity;isLit()Z"), slice = @Slice(from = @At(value = "FIELD", target = "Lnet/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity;litDuration:I"), - to = @At(value = "INVOKE", remap = false, target = "Lnet/minecraft/world/item/ItemStack;hasContainerItem()Z"))) + to = @At(value = "INVOKE", remap = false, target = "Lnet/minecraft/world/item/ItemStack;hasCraftingRemainingItem()Z"))) private static boolean arclight$setBurnTime(AbstractFurnaceBlockEntity furnace, CallbackInfo ci) { ItemStack itemStack = furnace.getItem(1); CraftItemStack fuel = CraftItemStack.asCraftMirror(itemStack); @@ -81,7 +81,7 @@ public abstract class AbstractFurnaceBlockEntityMixin extends LockableBlockEntit @Inject(method = "serverTick", locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "FIELD", ordinal = 0, target = "Lnet/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity;cookingProgress:I")) private static void arclight$startSmelt(Level level, BlockPos pos, BlockState state, AbstractFurnaceBlockEntity furnace, CallbackInfo ci, - boolean flag, boolean flag1, ItemStack stack, Recipe recipe) { + boolean flag, boolean flag1, ItemStack stack, boolean flag2, boolean flag3, Recipe recipe) { if (recipe != null && furnace.cookingProgress == 0) { CraftItemStack source = CraftItemStack.asCraftMirror(furnace.getItem(0)); if (((IRecipeBridge) recipe).bridge$toBukkitRecipe() instanceof CookingRecipe cookingRecipe) { diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/entity/BrewingStandBlockEntityMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/entity/BrewingStandBlockEntityMixin.java index b0dafcf3..72fbe973 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/entity/BrewingStandBlockEntityMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/entity/BrewingStandBlockEntityMixin.java @@ -90,8 +90,8 @@ public abstract class BrewingStandBlockEntityMixin extends LockableBlockEntityMi // BrewingRecipeRegistry.brewPotions(stacks, ing, SLOTS_FOR_SIDES); ForgeEventFactory.onPotionBrewed(stacks); - if (ing.hasContainerItem()) { - ItemStack containerItem = ing.getContainerItem(); + if (ing.hasCraftingRemainingItem()) { + ItemStack containerItem = ing.getCraftingRemainingItem(); ing.shrink(1); if (ing.isEmpty()) { ing = containerItem; diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/entity/CampfireTileEntityMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/entity/CampfireTileEntityMixin.java index 7c4417bd..7a5670fe 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/entity/CampfireTileEntityMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/entity/CampfireTileEntityMixin.java @@ -5,20 +5,26 @@ import net.minecraft.world.Container; import net.minecraft.world.Containers; import net.minecraft.world.SimpleContainer; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.crafting.RecipeType; +import net.minecraft.world.item.crafting.CampfireCookingRecipe; +import net.minecraft.world.item.crafting.RecipeManager; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.CampfireBlockEntity; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.gameevent.GameEvent; import org.bukkit.Bukkit; import org.bukkit.craftbukkit.v.block.CraftBlock; import org.bukkit.craftbukkit.v.inventory.CraftItemStack; import org.bukkit.event.block.BlockCookEvent; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; @Mixin(CampfireBlockEntity.class) public abstract class CampfireTileEntityMixin extends BlockEntityMixin { + @Shadow @Final private RecipeManager.CachedCheck quickCheck; + /** * @author IzzelAliz * @reason @@ -34,7 +40,7 @@ public abstract class CampfireTileEntityMixin extends BlockEntityMixin { entity.cookingProgress[i]++; if (entity.cookingProgress[i] >= entity.cookingTime[i]) { Container container = new SimpleContainer(itemstack); - ItemStack itemstack1 = level.getRecipeManager().getRecipeFor(RecipeType.CAMPFIRE_COOKING, container, level).map((p_155305_) -> { + ItemStack itemstack1 = ((CampfireTileEntityMixin) (Object) entity).quickCheck.getRecipeFor(container, level).map((p_155305_) -> { return p_155305_.assemble(container); }).orElse(itemstack); CraftItemStack source = CraftItemStack.asCraftMirror(itemstack); @@ -53,6 +59,7 @@ public abstract class CampfireTileEntityMixin extends BlockEntityMixin { Containers.dropItemStack(level, pos.getX(), pos.getY(), pos.getZ(), itemstack1); entity.getItems().set(i, ItemStack.EMPTY); level.sendBlockUpdated(pos, state, state, 3); + level.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(state)); } } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/entity/ChestBlockEntityMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/entity/ChestBlockEntityMixin.java index 0e478c52..336789fd 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/entity/ChestBlockEntityMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/entity/ChestBlockEntityMixin.java @@ -4,6 +4,7 @@ import io.izzel.arclight.common.bridge.core.inventory.IInventoryBridge; import net.minecraft.core.NonNullList; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.entity.ChestBlockEntity; +import net.minecraftforge.registries.ForgeRegistries; import org.bukkit.craftbukkit.v.entity.CraftHumanEntity; import org.bukkit.entity.HumanEntity; import org.bukkit.inventory.InventoryHolder; @@ -60,6 +61,6 @@ public abstract class ChestBlockEntityMixin extends LockableBlockEntityMixin { @Override public boolean onlyOpCanSetNbt() { - return this.getType().getRegistryName().getNamespace().equals("minecraft"); + return ForgeRegistries.BLOCK_ENTITY_TYPES.getKey(this.getType()).getNamespace().equals("minecraft"); } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/entity/CommandBlockLogicMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/entity/CommandBlockLogicMixin.java index 49be1433..f63eb2ab 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/entity/CommandBlockLogicMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/entity/CommandBlockLogicMixin.java @@ -5,7 +5,6 @@ import io.izzel.arclight.common.bridge.core.command.CommandSourceBridge; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.Commands; import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.TextComponent; import net.minecraft.world.level.BaseCommandBlock; import org.bukkit.Bukkit; import org.bukkit.craftbukkit.v.CraftServer; @@ -24,7 +23,7 @@ public class CommandBlockLogicMixin { @Shadow private Component name; // @formatter:on - @Redirect(method = "performCommand", at = @At(value = "INVOKE", target = "Lnet/minecraft/commands/Commands;performCommand(Lnet/minecraft/commands/CommandSourceStack;Ljava/lang/String;)I")) + @Redirect(method = "performCommand", at = @At(value = "INVOKE", target = "Lnet/minecraft/commands/Commands;performPrefixedCommand(Lnet/minecraft/commands/CommandSourceStack;Ljava/lang/String;)I")) private int arclight$serverCommand(Commands commands, CommandSourceStack sender, String command) { Joiner joiner = Joiner.on(" "); if (command.startsWith("/")) { @@ -54,13 +53,13 @@ public class CommandBlockLogicMixin { args[0] = "minecraft:" + args[0]; } - return commands.performCommand(sender, joiner.join(args)); + return commands.performPrefixedCommand(sender, joiner.join(args)); } @Inject(method = "setName", at = @At("RETURN")) public void arclight$setName(Component nameIn, CallbackInfo ci) { if (this.name == null) { - this.name = new TextComponent("@"); + this.name = Component.literal("@"); } } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/entity/ContainerOpenersCounterMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/entity/ContainerOpenersCounterMixin.java new file mode 100644 index 00000000..a5f346ff --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/entity/ContainerOpenersCounterMixin.java @@ -0,0 +1,68 @@ +package io.izzel.arclight.common.mixin.core.world.level.block.entity; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.ContainerOpenersCounter; +import net.minecraft.world.level.block.state.BlockState; +import org.bukkit.craftbukkit.v.event.CraftEventFactory; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyVariable; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ContainerOpenersCounter.class) +public abstract class ContainerOpenersCounterMixin { + + // @formatter:off + @Shadow private int openCount; + @Shadow protected abstract void onOpen(Level p_155460_, BlockPos p_155461_, BlockState p_155462_); + @Shadow protected abstract void onClose(Level p_155473_, BlockPos p_155474_, BlockState p_155475_); + @Shadow protected abstract void openerCountChanged(Level p_155463_, BlockPos p_155464_, BlockState p_155465_, int p_155466_, int p_155467_); + // @formatter:on + + public boolean opened; + + public void onAPIOpen(Level world, BlockPos blockposition, BlockState iblockdata) { + onOpen(world, blockposition, iblockdata); + } + + public void onAPIClose(Level world, BlockPos blockposition, BlockState iblockdata) { + onClose(world, blockposition, iblockdata); + } + + public void openerAPICountChanged(Level world, BlockPos blockposition, BlockState iblockdata, int i, int j) { + openerCountChanged(world, blockposition, iblockdata, i, j); + } + + @Inject(method = "incrementOpeners", at = @At("HEAD")) + private void arclight$increase(Player p_155453_, Level level, BlockPos pos, BlockState p_155456_, CallbackInfo ci) { + int oldPower = Math.max(0, Math.min(15, this.openCount++)); + if (level.getBlockState(pos).is(net.minecraft.world.level.block.Blocks.TRAPPED_CHEST)) { + int newPower = Math.max(0, Math.min(15, this.openCount)); + if (oldPower != newPower) { + CraftEventFactory.callRedstoneChange(level, pos, oldPower, newPower); + } + } + this.openCount--; + } + + @Inject(method = "decrementOpeners", at = @At("HEAD")) + private void arclight$decrease(Player p_155453_, Level level, BlockPos pos, BlockState p_155456_, CallbackInfo ci) { + int oldPower = Math.max(0, Math.min(15, this.openCount--)); + if (level.getBlockState(pos).is(net.minecraft.world.level.block.Blocks.TRAPPED_CHEST)) { + int newPower = Math.max(0, Math.min(15, this.openCount)); + if (oldPower != newPower) { + CraftEventFactory.callRedstoneChange(level, pos, oldPower, newPower); + } + } + this.openCount++; + } + + @ModifyVariable(method = "recheckOpeners", ordinal = 0, at = @At(value = "FIELD", ordinal = 0, target = "Lnet/minecraft/world/level/block/entity/ContainerOpenersCounter;openCount:I")) + private int arclight$addOpens(int power) { + return opened ? power + 1 : power; + } +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/entity/LecternBlockEntityMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/entity/LecternBlockEntityMixin.java index 47dd16da..92203a03 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/entity/LecternBlockEntityMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/entity/LecternBlockEntityMixin.java @@ -30,7 +30,6 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; import javax.annotation.Nullable; -import java.util.UUID; @Mixin(LecternBlockEntity.class) public abstract class LecternBlockEntityMixin extends BlockEntityMixin implements CommandSource, ICommandSourceBridge { @@ -57,7 +56,7 @@ public abstract class LecternBlockEntityMixin extends BlockEntityMixin implement } @Override - public void sendMessage(@NotNull Component component, @NotNull UUID uuid) { + public void sendSystemMessage(@NotNull Component component) { } @Override diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/entity/SculkCatalystBlockEntityMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/entity/SculkCatalystBlockEntityMixin.java new file mode 100644 index 00000000..71048f02 --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/entity/SculkCatalystBlockEntityMixin.java @@ -0,0 +1,25 @@ +package io.izzel.arclight.common.mixin.core.world.level.block.entity; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.SculkCatalystBlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import org.bukkit.craftbukkit.v.event.CraftEventFactory; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(SculkCatalystBlockEntity.class) +public class SculkCatalystBlockEntityMixin { + + @Inject(method = "serverTick", at = @At("HEAD")) + private static void arclight$overrideSource(Level p_222780_, BlockPos p_222781_, BlockState p_222782_, SculkCatalystBlockEntity blockEntity, CallbackInfo ci) { + CraftEventFactory.sourceBlockOverride = blockEntity.getBlockPos(); + } + + @Inject(method = "serverTick", at = @At("RETURN")) + private static void arclight$resetSource(Level p_222780_, BlockPos p_222781_, BlockState p_222782_, SculkCatalystBlockEntity blockEntity, CallbackInfo ci) { + CraftEventFactory.sourceBlockOverride = null; + } +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/entity/SignBlockEntityMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/entity/SignBlockEntityMixin.java index 3fe1f0af..983b529b 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/entity/SignBlockEntityMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/entity/SignBlockEntityMixin.java @@ -24,7 +24,6 @@ import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import javax.annotation.Nullable; -import java.util.UUID; @Mixin(SignBlockEntity.class) public abstract class SignBlockEntityMixin extends BlockEntityMixin implements SignTileEntityBridge, CommandSource, ICommandSourceBridge { @@ -46,7 +45,7 @@ public abstract class SignBlockEntityMixin extends BlockEntityMixin implements S } @Override - public void sendMessage(@NotNull Component component, @NotNull UUID uuid) { + public void sendSystemMessage(@NotNull Component component) { } @Override diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/state/properties/IntegerPropertyMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/state/properties/IntegerPropertyMixin.java deleted file mode 100644 index 9a894202..00000000 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/block/state/properties/IntegerPropertyMixin.java +++ /dev/null @@ -1,20 +0,0 @@ -package io.izzel.arclight.common.mixin.core.world.level.block.state.properties; - -import net.minecraft.world.level.block.state.properties.IntegerProperty; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(IntegerProperty.class) -public class IntegerPropertyMixin { - - public int min; - public int max; - - @Inject(method = "", at = @At("RETURN")) - public void arclight$setValue(String name, int min, int max, CallbackInfo ci) { - this.max = max; - this.min = min; - } -} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/chunk/ChunkAccessMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/chunk/ChunkAccessMixin.java index 3e918af0..7a4afa49 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/chunk/ChunkAccessMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/chunk/ChunkAccessMixin.java @@ -17,7 +17,6 @@ import net.minecraft.world.level.LevelHeightAccessor; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.BiomeManager; import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.chunk.FeatureAccess; import net.minecraft.world.level.chunk.LevelChunkSection; import net.minecraft.world.level.chunk.UpgradeData; import net.minecraft.world.level.levelgen.blending.BlendingData; @@ -35,7 +34,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.util.Map; @Mixin(ChunkAccess.class) -public abstract class ChunkAccessMixin implements BlockGetter, BiomeManager.NoiseBiomeSource, FeatureAccess, ChunkAccessBridge { +public abstract class ChunkAccessMixin implements BlockGetter, BiomeManager.NoiseBiomeSource, ChunkAccessBridge { // @formatter:off @Shadow public abstract void setUnsaved(boolean p_62094_); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/levelgen/ChunkGeneratorMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/chunk/ChunkGeneratorMixin.java similarity index 81% rename from arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/levelgen/ChunkGeneratorMixin.java rename to arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/chunk/ChunkGeneratorMixin.java index d8f20952..c3cac367 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/levelgen/ChunkGeneratorMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/chunk/ChunkGeneratorMixin.java @@ -1,9 +1,9 @@ -package io.izzel.arclight.common.mixin.core.world.level.levelgen; +package io.izzel.arclight.common.mixin.core.world.level.chunk; import io.izzel.arclight.common.bridge.core.world.IWorldBridge; import io.izzel.arclight.common.bridge.core.world.WorldBridge; import io.izzel.arclight.common.bridge.core.world.level.levelgen.ChunkGeneratorBridge; -import net.minecraft.world.level.StructureFeatureManager; +import net.minecraft.world.level.StructureManager; import net.minecraft.world.level.WorldGenLevel; import net.minecraft.world.level.biome.BiomeSource; import net.minecraft.world.level.chunk.ChunkAccess; @@ -11,6 +11,7 @@ import net.minecraft.world.level.chunk.ChunkGenerator; import net.minecraft.world.level.levelgen.LegacyRandomSource; import net.minecraft.world.level.levelgen.WorldgenRandom; import org.bukkit.craftbukkit.v.generator.CraftLimitedRegion; +import org.bukkit.craftbukkit.v.util.RandomSourceWrapper; import org.bukkit.generator.BlockPopulator; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -24,17 +25,16 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; public abstract class ChunkGeneratorMixin implements ChunkGeneratorBridge { // @formatter:off - @Shadow public abstract void applyBiomeDecoration(WorldGenLevel p_187712_, ChunkAccess p_187713_, StructureFeatureManager p_187714_); + @Shadow public abstract void applyBiomeDecoration(WorldGenLevel p_187712_, ChunkAccess p_187713_, StructureManager p_187714_); @Shadow @Final @Mutable protected BiomeSource biomeSource; - @Shadow @Final @Mutable protected BiomeSource runtimeBiomeSource; // @formatter:on @Inject(method = "applyBiomeDecoration", at = @At("RETURN")) - private void arclight$addBukkitDecoration(WorldGenLevel level, ChunkAccess chunkAccess, StructureFeatureManager manager, CallbackInfo ci) { + private void arclight$addBukkitDecoration(WorldGenLevel level, ChunkAccess chunkAccess, StructureManager manager, CallbackInfo ci) { this.addDecorations(level, chunkAccess, manager); } - public void applyBiomeDecoration(WorldGenLevel level, ChunkAccess chunkAccess, StructureFeatureManager structureFeatureManager, boolean vanilla) { + public void applyBiomeDecoration(WorldGenLevel level, ChunkAccess chunkAccess, StructureManager structureFeatureManager, boolean vanilla) { if (vanilla) { this.applyBiomeDecoration(level, chunkAccess, structureFeatureManager); } else { @@ -42,7 +42,7 @@ public abstract class ChunkGeneratorMixin implements ChunkGeneratorBridge { } } - private void addDecorations(WorldGenLevel region, ChunkAccess chunk, StructureFeatureManager structureManager) { + private void addDecorations(WorldGenLevel region, ChunkAccess chunk, StructureManager structureManager) { org.bukkit.World world = ((WorldBridge) ((IWorldBridge) region).bridge$getMinecraftWorld()).bridge$getWorld(); // only call when a populator is present (prevents unnecessary entity conversion) if (!world.getPopulators().isEmpty()) { @@ -52,7 +52,7 @@ public abstract class ChunkGeneratorMixin implements ChunkGeneratorBridge { for (BlockPopulator populator : world.getPopulators()) { WorldgenRandom random = new WorldgenRandom(new LegacyRandomSource(region.getSeed())); random.setDecorationSeed(region.getSeed(), x, z); - populator.populate(world, random, x, z, limitedRegion); + populator.populate(world, new RandomSourceWrapper.RandomWrapper(random), x, z, limitedRegion); } limitedRegion.saveEntities(); limitedRegion.breakLink(); @@ -61,6 +61,6 @@ public abstract class ChunkGeneratorMixin implements ChunkGeneratorBridge { @Override public void bridge$setBiomeSource(BiomeSource biomeSource) { - this.biomeSource = this.runtimeBiomeSource = biomeSource; + this.biomeSource = biomeSource; } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/chunk/LevelChunkSectionMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/chunk/LevelChunkSectionMixin.java index 68c2161a..6d99c7e0 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/chunk/LevelChunkSectionMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/chunk/LevelChunkSectionMixin.java @@ -1,26 +1,21 @@ package io.izzel.arclight.common.mixin.core.world.level.chunk; import io.izzel.arclight.common.bridge.core.world.chunk.LevelChunkSectionBridge; -import io.izzel.arclight.common.mod.util.ResourceLocationUtil; import net.minecraft.core.Holder; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.chunk.LevelChunkSection; import net.minecraft.world.level.chunk.PalettedContainer; -import org.bukkit.Bukkit; -import net.minecraft.core.Registry; -import org.bukkit.craftbukkit.v.CraftServer; -import org.bukkit.craftbukkit.v.block.CraftBlock; -import org.spongepowered.asm.mixin.Final; +import net.minecraft.world.level.chunk.PalettedContainerRO; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @Mixin(LevelChunkSection.class) public class LevelChunkSectionMixin implements LevelChunkSectionBridge { - @Shadow @Final private PalettedContainer> biomes; + @Shadow private PalettedContainerRO> biomes; public void setBiome(int i, int j, int k, Holder biome) { - this.biomes.set(i, j, k, biome); + ((PalettedContainer>) this.biomes).set(i, j, k, biome); } @Override diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/chunk/storage/ChunkLoaderMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/chunk/storage/ChunkLoaderMixin.java index f9aff9a3..1bd3a589 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/chunk/storage/ChunkLoaderMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/chunk/storage/ChunkLoaderMixin.java @@ -17,7 +17,7 @@ import java.util.List; @Mixin(ChunkStorage.class) public abstract class ChunkLoaderMixin { - @Redirect(method = "upgradeChunkTag", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/levelgen/structure/LegacyStructureDataHandler;getLegacyStructureHandler(Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/world/level/storage/DimensionDataStorage;)Lnet/minecraft/world/level/levelgen/structure/LegacyStructureDataHandler;")) + @Redirect(method = "getLegacyStructureHandler", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/levelgen/structure/LegacyStructureDataHandler;getLegacyStructureHandler(Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/world/level/storage/DimensionDataStorage;)Lnet/minecraft/world/level/levelgen/structure/LegacyStructureDataHandler;")) private LegacyStructureDataHandler arclight$legacyData(ResourceKey p_236992_0_, DimensionDataStorage p_236992_1_) { return legacyDataOf(p_236992_0_, p_236992_1_); } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/gameevent/vibrations/VibrationListenerMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/gameevent/vibrations/VibrationListenerMixin.java index 8cc2567f..986b42e5 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/gameevent/vibrations/VibrationListenerMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/gameevent/vibrations/VibrationListenerMixin.java @@ -3,11 +3,13 @@ package io.izzel.arclight.common.mixin.core.world.level.gameevent.vibrations; import io.izzel.arclight.common.bridge.core.entity.EntityBridge; import net.minecraft.core.BlockPos; import net.minecraft.core.Registry; +import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.Entity; import net.minecraft.world.level.Level; import net.minecraft.world.level.gameevent.GameEvent; import net.minecraft.world.level.gameevent.PositionSource; import net.minecraft.world.level.gameevent.vibrations.VibrationListener; +import net.minecraft.world.phys.Vec3; import org.bukkit.Bukkit; import org.bukkit.craftbukkit.v.block.CraftBlock; import org.bukkit.craftbukkit.v.util.CraftNamespacedKey; @@ -24,11 +26,11 @@ import java.util.Optional; public abstract class VibrationListenerMixin { // @formatter:off - @Shadow protected abstract boolean isValidVibration(GameEvent p_157917_, @org.jetbrains.annotations.Nullable Entity p_157918_); - @Shadow @Final protected PositionSource listenerSource; + @Shadow @Nullable protected VibrationListener.ReceivingEvent receivingEvent; @Shadow @Final protected VibrationListener.VibrationListenerConfig config; - @Shadow protected abstract boolean isOccluded(Level p_157911_, BlockPos p_157912_, BlockPos p_157913_); - @Shadow protected abstract void sendSignal(Level p_157906_, GameEvent p_157907_, BlockPos p_157908_, BlockPos p_157909_); + @Shadow @Final protected PositionSource listenerSource; + @Shadow private static boolean isOccluded(Level p_223776_, Vec3 p_223777_, Vec3 p_223778_) { return false; } + @Shadow protected abstract void scheduleSignal(ServerLevel p_223770_, GameEvent p_223771_, GameEvent.Context p_223772_, Vec3 p_223773_, Vec3 p_223774_); // @formatter:on /** @@ -36,27 +38,34 @@ public abstract class VibrationListenerMixin { * @reason */ @Overwrite - public boolean handleGameEvent(Level level, GameEvent gameEvent, @Nullable Entity entity, BlockPos pos) { - if (!this.isValidVibration(gameEvent, entity)) { + public boolean handleGameEvent(ServerLevel level, GameEvent.Message p_223768_) { + if (this.receivingEvent != null) { return false; } else { - Optional optional = this.listenerSource.getPosition(level); - if (!optional.isPresent()) { + GameEvent gameevent = p_223768_.gameEvent(); + GameEvent.Context gameevent$context = p_223768_.context(); + if (!this.config.isValidVibration(gameevent, gameevent$context)) { return false; } else { - BlockPos blockpos = optional.get(); - var cancelled = !this.config.shouldListen(level, (VibrationListener) (Object) this, pos, gameEvent, entity); - BlockReceiveGameEvent event = new BlockReceiveGameEvent(org.bukkit.GameEvent.getByKey(CraftNamespacedKey.fromMinecraft(Registry.GAME_EVENT.getKey(gameEvent))), - CraftBlock.at(level, blockpos), (entity == null) ? null : ((EntityBridge) entity).bridge$getBukkitEntity()); - event.setCancelled(cancelled); - Bukkit.getPluginManager().callEvent(event); - if (cancelled) { - return false; - } else if (this.isOccluded(level, pos, blockpos)) { + Optional optional = this.listenerSource.getPosition(level); + if (optional.isEmpty()) { return false; } else { - this.sendSignal(level, gameEvent, pos, blockpos); - return true; + Vec3 vec3 = p_223768_.source(); + Vec3 vec31 = optional.get(); + boolean cancelled = !this.config.shouldListen(level, (VibrationListener) (Object) this, new BlockPos(vec3), gameevent, gameevent$context); + Entity entity = gameevent$context.sourceEntity(); + var event = new BlockReceiveGameEvent(org.bukkit.GameEvent.getByKey(CraftNamespacedKey.fromMinecraft(Registry.GAME_EVENT.getKey(gameevent))), CraftBlock.at(level, new BlockPos(vec31)), (entity == null) ? null : ((EntityBridge) entity).bridge$getBukkitEntity()); + event.setCancelled(cancelled); + Bukkit.getPluginManager().callEvent(event); + if (event.isCancelled()) { + return false; + } else if (isOccluded(level, vec3, vec31)) { + return false; + } else { + this.scheduleSignal(level, gameevent, gameevent$context, vec3, vec31); + return true; + } } } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/redstone/NeighborUpdaterMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/redstone/NeighborUpdaterMixin.java new file mode 100644 index 00000000..7a3c0ab4 --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/redstone/NeighborUpdaterMixin.java @@ -0,0 +1,59 @@ +package io.izzel.arclight.common.mixin.core.world.level.redstone; + +import io.izzel.arclight.common.bridge.core.world.WorldBridge; +import net.minecraft.CrashReport; +import net.minecraft.CrashReportCategory; +import net.minecraft.ReportedException; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Registry; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.redstone.NeighborUpdater; +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.v.block.CraftBlock; +import org.bukkit.craftbukkit.v.block.data.CraftBlockData; +import org.bukkit.event.block.BlockPhysicsEvent; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; + +import java.util.Locale; + +@Mixin(NeighborUpdater.class) +public interface NeighborUpdaterMixin { + + /** + * @author IzzelAliz + * @reason + */ + @Overwrite + static void executeUpdate(Level level, BlockState state, BlockPos pos, Block block, BlockPos source, boolean p_230769_) { + try { + var cworld = ((WorldBridge) level).bridge$getWorld(); + if (cworld != null) { + BlockPhysicsEvent event = new BlockPhysicsEvent(CraftBlock.at(level, pos), CraftBlockData.fromData(state), CraftBlock.at(level, source)); + Bukkit.getPluginManager().callEvent(event); + + if (event.isCancelled()) { + return; + } + } + state.neighborChanged(level, pos, block, source, p_230769_); + } catch (StackOverflowError ex) { + ((WorldBridge) level).bridge$setLastPhysicsProblem(pos.immutable()); + // Spigot End + } catch (Throwable throwable) { + CrashReport crashreport = CrashReport.forThrowable(throwable, "Exception while updating neighbours"); + CrashReportCategory crashreportcategory = crashreport.addCategory("Block being updated"); + crashreportcategory.setDetail("Source block type", () -> { + try { + return String.format(Locale.ROOT, "ID #%s (%s // %s)", Registry.BLOCK.getKey(block), block.getDescriptionId(), block.getClass().getCanonicalName()); + } catch (Throwable throwable1) { + return "ID #" + Registry.BLOCK.getKey(block); + } + }); + CrashReportCategory.populateBlockDetails(crashreportcategory, level, pos, state); + throw new ReportedException(crashreport); + } + } +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/storage/loot/LootTableMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/storage/loot/LootTableMixin.java index c1ae3d09..c756224a 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/storage/loot/LootTableMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/storage/loot/LootTableMixin.java @@ -2,15 +2,17 @@ package io.izzel.arclight.common.mixin.core.world.level.storage.loot; import io.izzel.arclight.common.bridge.core.world.storage.loot.LootTableBridge; import io.izzel.arclight.mixin.Eject; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import net.minecraft.util.RandomSource; import net.minecraft.world.Container; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.storage.loot.LootContext; import net.minecraft.world.level.storage.loot.LootTable; import net.minecraft.world.level.storage.loot.parameters.LootContextParams; -import org.slf4j.Logger; import org.bukkit.craftbukkit.v.event.CraftEventFactory; import org.bukkit.craftbukkit.v.inventory.CraftItemStack; import org.bukkit.event.world.LootGenerateEvent; +import org.slf4j.Logger; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -18,22 +20,20 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.util.List; -import java.util.Random; -import java.util.stream.Collectors; @Mixin(LootTable.class) public abstract class LootTableMixin implements LootTableBridge { // @formatter:off - @Shadow @Final private static Logger LOGGER; - @Shadow public abstract List getRandomItems(LootContext context); - @Shadow protected abstract List getAvailableSlots(Container inventory, Random rand); - @Shadow protected abstract void shuffleAndSplitItems(List stacks, int emptySlotsCount, Random rand); + @Shadow @Final static Logger LOGGER; + @Shadow public abstract ObjectArrayList getRandomItems(LootContext p_230923_); + @Shadow protected abstract List getAvailableSlots(Container p_230920_, RandomSource p_230921_); + @Shadow protected abstract void shuffleAndSplitItems(ObjectArrayList p_230925_, int p_230926_, RandomSource p_230927_); // @formatter:on - @Eject(method = "fill", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/storage/loot/LootTable;getRandomItems(Lnet/minecraft/world/level/storage/loot/LootContext;)Ljava/util/List;")) - private List arclight$nonPluginEvent(LootTable lootTable, LootContext context, CallbackInfo ci, Container inv) { - List list = lootTable.getRandomItems(context); + @Eject(method = "fill", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/storage/loot/LootTable;getRandomItems(Lnet/minecraft/world/level/storage/loot/LootContext;)Lit/unimi/dsi/fastutil/objects/ObjectArrayList;")) + private ObjectArrayList arclight$nonPluginEvent(LootTable lootTable, LootContext context, CallbackInfo ci, Container inv) { + ObjectArrayList list = lootTable.getRandomItems(context); if (!context.hasParam(LootContextParams.ORIGIN) && !context.hasParam(LootContextParams.THIS_ENTITY)) { return list; } @@ -42,31 +42,32 @@ public abstract class LootTableMixin implements LootTableBridge { ci.cancel(); return null; } else { - return event.getLoot().stream().map(CraftItemStack::asNMSCopy).collect(Collectors.toList()); + return event.getLoot().stream().map(CraftItemStack::asNMSCopy).collect(ObjectArrayList.toList()); } } public void fillInventory(Container inv, LootContext context, boolean plugin) { - List list = this.getRandomItems(context); - Random random = context.getRandom(); - LootGenerateEvent event = CraftEventFactory.callLootGenerateEvent(inv, (LootTable) (Object) this, context, list, plugin); + ObjectArrayList objectarraylist = this.getRandomItems(context); + RandomSource randomsource = context.getRandom(); + LootGenerateEvent event = CraftEventFactory.callLootGenerateEvent(inv, (LootTable) (Object) this, context, objectarraylist, plugin); if (event.isCancelled()) { return; } - list = event.getLoot().stream().map(CraftItemStack::asNMSCopy).collect(Collectors.toList()); - List list1 = this.getAvailableSlots(inv, random); - this.shuffleAndSplitItems(list, list1.size(), random); + objectarraylist = event.getLoot().stream().map(CraftItemStack::asNMSCopy).collect(ObjectArrayList.toList()); - for (ItemStack itemstack : list) { - if (list1.isEmpty()) { + List list = this.getAvailableSlots(inv, randomsource); + this.shuffleAndSplitItems(objectarraylist, list.size(), randomsource); + + for (ItemStack itemstack : objectarraylist) { + if (list.isEmpty()) { LOGGER.warn("Tried to over-fill a container"); return; } if (itemstack.isEmpty()) { - inv.setItem(list1.remove(list1.size() - 1), ItemStack.EMPTY); + inv.setItem(list.remove(list.size() - 1), ItemStack.EMPTY); } else { - inv.setItem(list1.remove(list1.size() - 1), itemstack); + inv.setItem(list.remove(list.size() - 1), itemstack); } } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/storage/loot/predicates/SurvivesExplosionMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/storage/loot/predicates/SurvivesExplosionMixin.java index d855b8b8..cc5c5f5b 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/storage/loot/predicates/SurvivesExplosionMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/storage/loot/predicates/SurvivesExplosionMixin.java @@ -1,13 +1,12 @@ package io.izzel.arclight.common.mixin.core.world.level.storage.loot.predicates; +import net.minecraft.util.RandomSource; import net.minecraft.world.level.storage.loot.LootContext; import net.minecraft.world.level.storage.loot.parameters.LootContextParams; import net.minecraft.world.level.storage.loot.predicates.ExplosionCondition; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; -import java.util.Random; - @Mixin(ExplosionCondition.class) public class SurvivesExplosionMixin { @@ -19,7 +18,7 @@ public class SurvivesExplosionMixin { public boolean test(LootContext context) { Float f = context.getParamOrNull(LootContextParams.EXPLOSION_RADIUS); if (f != null) { - Random random = context.getRandom(); + RandomSource random = context.getRandom(); float f1 = 1.0F / f; return random.nextFloat() < f1; } else { diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/spawner/BaseSpawnerMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/spawner/BaseSpawnerMixin.java index ee9a8184..02694f53 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/spawner/BaseSpawnerMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/spawner/BaseSpawnerMixin.java @@ -19,6 +19,7 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.LightLayer; import net.minecraft.world.level.SpawnData; +import net.minecraft.world.level.gameevent.GameEvent; import net.minecraft.world.phys.AABB; import net.minecraftforge.event.ForgeEventFactory; import org.bukkit.craftbukkit.v.event.CraftEventFactory; @@ -145,6 +146,7 @@ public abstract class BaseSpawnerMixin { } level.levelEvent(2004, pos, 0); + level.gameEvent(entity, GameEvent.ENTITY_PLACE, blockpos); if (entity instanceof Mob) { ((Mob) entity).spawnAnim(); } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/spawner/WorldEntitySpawnerMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/spawner/NaturalSpawnerMixin.java similarity index 97% rename from arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/spawner/WorldEntitySpawnerMixin.java rename to arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/spawner/NaturalSpawnerMixin.java index 6f010583..ec2bc057 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/spawner/WorldEntitySpawnerMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/spawner/NaturalSpawnerMixin.java @@ -6,6 +6,7 @@ import io.izzel.arclight.common.bridge.core.world.spawner.WorldEntitySpawnerBrid import net.minecraft.core.BlockPos; import net.minecraft.core.Holder; import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.MobCategory; import net.minecraft.world.level.ChunkPos; @@ -27,10 +28,8 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.util.Random; - @Mixin(NaturalSpawner.class) -public abstract class WorldEntitySpawnerMixin { +public abstract class NaturalSpawnerMixin { // @formatter:off @Shadow @Final private static MobCategory[] SPAWNING_CATEGORIES; @@ -81,7 +80,7 @@ public abstract class WorldEntitySpawnerMixin { } @Inject(method = "spawnMobsForChunkGeneration", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/ServerLevelAccessor;addFreshEntityWithPassengers(Lnet/minecraft/world/entity/Entity;)V")) - private static void arclight$worldGenSpawn(ServerLevelAccessor accessor, Holder p_151618_, ChunkPos p_151619_, Random p_151620_, CallbackInfo ci) { + private static void arclight$worldGenSpawn(ServerLevelAccessor accessor, Holder p_151618_, ChunkPos p_151619_, RandomSource p_151620_, CallbackInfo ci) { ((IWorldWriterBridge) accessor).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.CHUNK_GEN); } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/spawner/PatrolSpawnerMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/spawner/PatrolSpawnerMixin.java index 9b3202af..e90b0617 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/spawner/PatrolSpawnerMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/spawner/PatrolSpawnerMixin.java @@ -1,22 +1,21 @@ package io.izzel.arclight.common.mixin.core.world.spawner; import io.izzel.arclight.common.bridge.core.world.WorldBridge; +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.levelgen.PatrolSpawner; import org.bukkit.event.entity.CreatureSpawnEvent; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import java.util.Random; -import net.minecraft.core.BlockPos; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.level.levelgen.PatrolSpawner; - @Mixin(PatrolSpawner.class) public class PatrolSpawnerMixin { @Inject(method = "spawnPatrolMember", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;addFreshEntityWithPassengers(Lnet/minecraft/world/entity/Entity;)V")) - public void arclight$spawnReason(ServerLevel worldIn, BlockPos p_222695_2_, Random random, boolean p_222695_4_, CallbackInfoReturnable cir) { + public void arclight$spawnReason(ServerLevel worldIn, BlockPos p_222695_2_, RandomSource random, boolean p_222695_4_, CallbackInfoReturnable cir) { ((WorldBridge) worldIn).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.PATROL); } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/storage/LevelStorageSourceMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/storage/LevelStorageSourceMixin.java index 3e4c8e8a..583c9bab 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/storage/LevelStorageSourceMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/storage/LevelStorageSourceMixin.java @@ -12,6 +12,8 @@ import java.io.IOException; @Mixin(LevelStorageSource.class) public abstract class LevelStorageSourceMixin implements LevelStorageSourceBridge { + // pdc implemented as WorldSavedData + // @formatter:off @Shadow public abstract LevelStorageSource.LevelStorageAccess createAccess(String saveName) throws IOException; // @formatter:on diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/storage/LevelStorageSource_LevelStorageAccessMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/storage/LevelStorageSource_LevelStorageAccessMixin.java index 76fb6be3..645bde66 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/storage/LevelStorageSource_LevelStorageAccessMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/storage/LevelStorageSource_LevelStorageAccessMixin.java @@ -17,7 +17,7 @@ import java.nio.file.Path; @Mixin(LevelStorageSource.LevelStorageAccess.class) public class LevelStorageSource_LevelStorageAccessMixin implements LevelStorageSourceBridge.LevelStorageAccessBridge { - @Shadow @Final public Path levelPath; + @Shadow @Final LevelStorageSource.LevelDirectory levelDirectory; public ResourceKey dimensionType; @@ -43,11 +43,11 @@ public class LevelStorageSource_LevelStorageAccessMixin implements LevelStorageS @Inject(method = "getDimensionPath", cancellable = true, at = @At("HEAD")) private void arclight$useActualType(ResourceKey dimensionKey, CallbackInfoReturnable cir) { if (dimensionType == LevelStem.OVERWORLD) { - cir.setReturnValue(this.levelPath); + cir.setReturnValue(this.levelDirectory.path()); } else if (dimensionType == LevelStem.NETHER) { - cir.setReturnValue(this.levelPath.resolve("DIM-1")); + cir.setReturnValue(this.levelDirectory.path().resolve("DIM-1")); } else if (dimensionType == LevelStem.END) { - cir.setReturnValue(this.levelPath.resolve("DIM1")); + cir.setReturnValue(this.levelDirectory.path().resolve("DIM1")); } } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/storage/ServerWorldInfoMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/storage/PrimaryLevelDataMixin.java similarity index 97% rename from arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/storage/ServerWorldInfoMixin.java rename to arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/storage/PrimaryLevelDataMixin.java index c1d3dc45..6d01bbd3 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/storage/ServerWorldInfoMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/storage/PrimaryLevelDataMixin.java @@ -21,7 +21,7 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(PrimaryLevelData.class) -public abstract class ServerWorldInfoMixin implements WorldInfoBridge { +public abstract class PrimaryLevelDataMixin implements WorldInfoBridge { // @formatter:off @Shadow public abstract String getLevelName(); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/forge/NetworkHooksMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/forge/NetworkHooksMixin.java index e523c997..078c9184 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/forge/NetworkHooksMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/forge/NetworkHooksMixin.java @@ -24,7 +24,7 @@ import java.util.function.Consumer; @Mixin(NetworkHooks.class) public class NetworkHooksMixin { - @Inject(method = "openGui(Lnet/minecraft/server/level/ServerPlayer;Lnet/minecraft/world/MenuProvider;Ljava/util/function/Consumer;)V", + @Inject(method = "openScreen(Lnet/minecraft/server/level/ServerPlayer;Lnet/minecraft/world/MenuProvider;Ljava/util/function/Consumer;)V", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/inventory/AbstractContainerMenu;getType()Lnet/minecraft/world/inventory/MenuType;")) private static void arclight$openContainer(ServerPlayer player, MenuProvider containerSupplier, Consumer extraDataWriter, CallbackInfo ci, int currentId, FriendlyByteBuf extraData, FriendlyByteBuf output, AbstractContainerMenu container) { diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/optimization/dfu/BlockEntityTypeMixin_DFU.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/optimization/dfu/BlockEntityTypeMixin_DFU.java deleted file mode 100644 index 31a73c93..00000000 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/optimization/dfu/BlockEntityTypeMixin_DFU.java +++ /dev/null @@ -1,17 +0,0 @@ -package io.izzel.arclight.common.mixin.optimization.dfu; - -import com.mojang.datafixers.DSL; -import com.mojang.datafixers.types.Type; -import net.minecraft.world.level.block.entity.BlockEntityType; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -@Mixin(BlockEntityType.class) -public class BlockEntityTypeMixin_DFU { - - @Redirect(method = "register", at = @At(value = "INVOKE", target = "Lnet/minecraft/Util;fetchChoiceType(Lcom/mojang/datafixers/DSL$TypeReference;Ljava/lang/String;)Lcom/mojang/datafixers/types/Type;")) - private static Type arclight$noDfu(DSL.TypeReference p_137457_, String p_137458_) { - return null; - } -} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/optimization/dfu/CraftMagicNumbersMixin_DFU.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/optimization/dfu/CraftMagicNumbersMixin_DFU.java deleted file mode 100644 index 35608c72..00000000 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/optimization/dfu/CraftMagicNumbersMixin_DFU.java +++ /dev/null @@ -1,21 +0,0 @@ -package io.izzel.arclight.common.mixin.optimization.dfu; - -import io.izzel.arclight.i18n.ArclightLocale; -import org.bukkit.craftbukkit.v.util.CraftMagicNumbers; -import org.bukkit.plugin.InvalidPluginException; -import org.bukkit.plugin.PluginDescriptionFile; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(value = CraftMagicNumbers.class, remap = false) -public class CraftMagicNumbersMixin_DFU { - - @Inject(method = "checkSupported", at = @At("HEAD")) - private void arclight$dfuDisabled(PluginDescriptionFile pdf, CallbackInfo ci) throws InvalidPluginException { - if (pdf.getAPIVersion() == null) { - throw new InvalidPluginException(ArclightLocale.getInstance().get("dfu-disable.legacy-plugin")); - } - } -} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/optimization/dfu/DataFixesManagerMixin_DFU.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/optimization/dfu/DataFixesManagerMixin_DFU.java deleted file mode 100644 index 3119717c..00000000 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/optimization/dfu/DataFixesManagerMixin_DFU.java +++ /dev/null @@ -1,19 +0,0 @@ -package io.izzel.arclight.common.mixin.optimization.dfu; - -import com.mojang.datafixers.DataFixer; -import com.mojang.datafixers.DataFixerBuilder; -import net.minecraft.SharedConstants; -import net.minecraft.util.datafix.DataFixers; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(DataFixers.class) -public class DataFixesManagerMixin_DFU { - - @Inject(method = "createFixerUpper", cancellable = true, at = @At("HEAD")) - private static void arclight$disableDfu(CallbackInfoReturnable cir) { - cir.setReturnValue(new DataFixerBuilder(SharedConstants.getCurrentVersion().getWorldVersion()).build(r -> {})); - } -} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/optimization/dfu/EntityType_BuilderMixin_DFU.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/optimization/dfu/EntityType_BuilderMixin_DFU.java deleted file mode 100644 index e90f835f..00000000 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/optimization/dfu/EntityType_BuilderMixin_DFU.java +++ /dev/null @@ -1,15 +0,0 @@ -package io.izzel.arclight.common.mixin.optimization.dfu; - -import net.minecraft.world.entity.EntityType; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -@Mixin(EntityType.Builder.class) -public class EntityType_BuilderMixin_DFU { - - @Redirect(method = "build", at = @At(value = "FIELD", target = "Lnet/minecraft/world/entity/EntityType$Builder;serialize:Z")) - private boolean arclight$noDfu(EntityType.Builder builder) { - return false; - } -} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/optimization/dfu/MainMixin_DFU.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/optimization/dfu/MainMixin_DFU.java deleted file mode 100644 index 53cd0d67..00000000 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/optimization/dfu/MainMixin_DFU.java +++ /dev/null @@ -1,22 +0,0 @@ -package io.izzel.arclight.common.mixin.optimization.dfu; - -import com.mojang.datafixers.DataFixer; -import io.izzel.arclight.i18n.ArclightLocale; -import net.minecraft.server.Main; -import net.minecraft.world.level.levelgen.WorldGenSettings; -import net.minecraft.world.level.storage.LevelStorageSource; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import java.util.function.BooleanSupplier; - -@Mixin(Main.class) -public abstract class MainMixin_DFU { - - @Inject(method = "forceUpgrade", at = @At("HEAD")) - private static void arclight$skipConvert(LevelStorageSource.LevelStorageAccess levelSave, DataFixer dataFixer, boolean flag, BooleanSupplier b, WorldGenSettings settings, CallbackInfo ci) { - throw new RuntimeException(ArclightLocale.getInstance().get("dfu-disable.map-convert")); - } -} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/optimization/general/network/ChunkMapMixin_Optimize.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/optimization/general/network/ChunkMapMixin_Optimize.java index 0c3bc257..9e6075da 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/optimization/general/network/ChunkMapMixin_Optimize.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/optimization/general/network/ChunkMapMixin_Optimize.java @@ -80,7 +80,7 @@ public class ChunkMapMixin_Optimize { @Mixin(ChunkMap.TrackedEntity.class) public static class TrackedEntityMixin { - @Redirect(method = "", at = @At(value = "INVOKE", target = "Lcom/google/common/collect/Sets;newIdentityHashSet()Ljava/util/Set;")) + @Redirect(method = "", at = @At(value = "INVOKE", remap = false, target = "Lcom/google/common/collect/Sets;newIdentityHashSet()Ljava/util/Set;")) private Set arclight$useFastUtilSet() { return new ReferenceOpenHashSet<>(); } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/ArclightConnector.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/ArclightConnector.java index 6951a608..ad81d5b5 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/ArclightConnector.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/ArclightConnector.java @@ -1,7 +1,6 @@ package io.izzel.arclight.common.mod; import io.izzel.arclight.common.mod.util.log.ArclightI18nLogger; -import io.izzel.arclight.i18n.ArclightConfig; import io.izzel.arclight.mixin.injector.EjectorInfo; import org.apache.logging.log4j.Logger; import org.spongepowered.asm.mixin.Mixins; @@ -20,9 +19,6 @@ public class ArclightConnector implements IMixinConnector { Mixins.addConfiguration("mixins.arclight.forge.json"); LOGGER.info("mixin-load.core"); Mixins.addConfiguration("mixins.arclight.impl.forge.optimization.json"); - if (ArclightConfig.spec().getOptimization().isDisableDFU()) { - Mixins.addConfiguration("mixins.arclight.impl.forge.optimization.dfu.json"); - } LOGGER.info("mixin-load.optimization"); } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/ArclightMixinPlugin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/ArclightMixinPlugin.java index 10a353c0..5d4dca90 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/ArclightMixinPlugin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/ArclightMixinPlugin.java @@ -244,7 +244,7 @@ public class ArclightMixinPlugin implements IMixinConfigPlugin { insnList.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, "java/lang/Object", "", "()V", false)); methodNode.instructions.insert(insnList); } else { - throw new ClassFormatError("No super constructor call present."); + throw new ClassFormatError("No super constructor call present: " + classNode.name); } } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/ArclightContainer.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/ArclightContainer.java index 74cc9c92..0c844740 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/ArclightContainer.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/ArclightContainer.java @@ -5,6 +5,7 @@ import io.izzel.arclight.common.bridge.core.inventory.IInventoryBridge; import io.izzel.arclight.common.bridge.core.inventory.container.PosContainerBridge; import io.izzel.arclight.common.mod.util.ArclightCaptures; import net.minecraft.world.Container; +import net.minecraft.world.SimpleContainer; import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.inventory.Slot; @@ -38,6 +39,14 @@ public class ArclightContainer { return new CraftInventory(new ContainerInvWrapper(container, containerOwner)); } + public static SimpleContainer copyOf(SimpleContainer container) { + var copy = new SimpleContainer(container.getContainerSize()); + for (int slot = 0; slot < container.getContainerSize(); slot++) { + copy.items.set(slot, container.items.get(slot).copy()); + } + return copy; + } + private static class ContainerInvWrapper implements Container, IInventoryBridge { private final AbstractContainerMenu container; diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/ArclightServer.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/ArclightServer.java index 407db8c9..7258b666 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/ArclightServer.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/ArclightServer.java @@ -1,5 +1,6 @@ package io.izzel.arclight.common.mod.server; +import com.google.common.util.concurrent.ThreadFactoryBuilder; import io.izzel.arclight.api.Arclight; import io.izzel.arclight.common.bridge.bukkit.CraftServerBridge; import io.izzel.arclight.common.bridge.core.server.MinecraftServerBridge; @@ -18,11 +19,28 @@ import org.bukkit.craftbukkit.v.command.ColouredConsoleSender; import java.io.File; import java.util.Objects; import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; import java.util.concurrent.locks.LockSupport; public class ArclightServer { private static final Executor mainThreadExecutor = ArclightServer::executeOnMainThread; + private static final ExecutorService chatExecutor = Executors.newCachedThreadPool( + new ThreadFactoryBuilder().setDaemon(true).setNameFormat("Async Chat Thread - #%d") + .setThreadFactory(chatFactory()).build()); + + private static ThreadFactory chatFactory() { + var group = Thread.currentThread().getThreadGroup(); + var classLoader = Thread.currentThread().getContextClassLoader(); + return r -> { + var thread = new Thread(group, r); + thread.setContextClassLoader(classLoader); + return thread; + }; + } + private static CraftServer server; @SuppressWarnings("ConstantConditions") @@ -80,6 +98,10 @@ public class ArclightServer { return mainThreadExecutor; } + public static ExecutorService getChatExecutor() { + return chatExecutor; + } + public static World.Environment getEnvironment(ResourceKey key) { return BukkitRegistry.DIM_MAP.getOrDefault(key, World.Environment.CUSTOM); } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/BukkitRegistry.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/BukkitRegistry.java index e81c03cc..11629682 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/BukkitRegistry.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/BukkitRegistry.java @@ -25,7 +25,6 @@ import net.minecraft.world.effect.MobEffect; import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.entity.MobCategory; import net.minecraft.world.entity.boss.enderdragon.phases.EnderDragonPhase; -import net.minecraft.world.entity.decoration.Motive; import net.minecraft.world.entity.npc.VillagerProfession; import net.minecraft.world.item.CreativeModeTab; import net.minecraft.world.item.Item; @@ -168,9 +167,10 @@ public class BukkitRegistry { long keyOffset = Unsafe.objectFieldOffset(key); for (StatType statType : ForgeRegistries.STAT_TYPES) { if (statType == Stats.CUSTOM) continue; - Statistic statistic = STATS.get(statType.getRegistryName()); + var location = ForgeRegistries.STAT_TYPES.getKey(statType); + Statistic statistic = STATS.get(location); if (statistic == null) { - String standardName = ResourceLocationUtil.standardize(statType.getRegistryName()); + String standardName = ResourceLocationUtil.standardize(location); Statistic.Type type; if (statType.getRegistry() == Registry.ENTITY_TYPE) { type = Statistic.Type.ENTITY; @@ -182,10 +182,10 @@ public class BukkitRegistry { type = Statistic.Type.UNTYPED; } statistic = EnumHelper.makeEnum(Statistic.class, standardName, i, ImmutableList.of(Statistic.Type.class), ImmutableList.of(type)); - Unsafe.putObject(statistic, keyOffset, statType.getRegistryName()); + Unsafe.putObject(statistic, keyOffset, location); newTypes.add(statistic); - STATS.put(statType.getRegistryName(), statistic); - ArclightMod.LOGGER.debug("Registered {} as stats {}", statType.getRegistryName(), statistic); + STATS.put(location, statistic); + ArclightMod.LOGGER.debug("Registered {} as stats {}", location, statistic); i++; } } @@ -210,17 +210,18 @@ public class BukkitRegistry { List newTypes = new ArrayList<>(); Field key = Arrays.stream(Art.class.getDeclaredFields()).filter(it -> it.getName().equals("key")).findAny().orElse(null); long keyOffset = Unsafe.objectFieldOffset(key); - for (Motive paintingType : ForgeRegistries.PAINTING_TYPES) { - String lookupName = paintingType.getRegistryName().getPath().toLowerCase(Locale.ROOT); + for (var paintingType : ForgeRegistries.PAINTING_VARIANTS) { + var location = ForgeRegistries.PAINTING_VARIANTS.getKey(paintingType); + String lookupName = location.getPath().toLowerCase(Locale.ROOT); Art bukkit = Art.getByName(lookupName); if (bukkit == null) { - String standardName = ResourceLocationUtil.standardize(paintingType.getRegistryName()); + String standardName = ResourceLocationUtil.standardize(location); bukkit = EnumHelper.makeEnum(Art.class, standardName, i, ImmutableList.of(int.class, int.class, int.class), ImmutableList.of(i, paintingType.getWidth(), paintingType.getHeight())); newTypes.add(bukkit); - Unsafe.putObject(bukkit, keyOffset, CraftNamespacedKey.fromMinecraft(paintingType.getRegistryName())); + Unsafe.putObject(bukkit, keyOffset, CraftNamespacedKey.fromMinecraft(location)); ART_BY_ID.put(i, bukkit); ART_BY_NAME.put(lookupName, bukkit); - ArclightMod.LOGGER.debug("Registered {} as art {}", paintingType.getRegistryName(), bukkit); + ArclightMod.LOGGER.debug("Registered {} as art {}", location, bukkit); i++; } } @@ -233,7 +234,8 @@ public class BukkitRegistry { Field key = Arrays.stream(Biome.class.getDeclaredFields()).filter(it -> it.getName().equals("key")).findAny().orElse(null); long keyOffset = Unsafe.objectFieldOffset(key); for (net.minecraft.world.level.biome.Biome biome : ForgeRegistries.BIOMES) { - String name = ResourceLocationUtil.standardize(biome.getRegistryName()); + var location = ForgeRegistries.BIOMES.getKey(biome); + String name = ResourceLocationUtil.standardize(location); Biome bukkit; try { bukkit = Biome.valueOf(name); @@ -243,8 +245,8 @@ public class BukkitRegistry { if (bukkit == null) { bukkit = EnumHelper.makeEnum(Biome.class, name, i++, ImmutableList.of(), ImmutableList.of()); newTypes.add(bukkit); - Unsafe.putObject(bukkit, keyOffset, CraftNamespacedKey.fromMinecraft(biome.getRegistryName())); - ArclightMod.LOGGER.debug("Registered {} as biome {}", biome.getRegistryName(), bukkit); + Unsafe.putObject(bukkit, keyOffset, CraftNamespacedKey.fromMinecraft(location)); + ArclightMod.LOGGER.debug("Registered {} as biome {}", location, bukkit); } } EnumHelper.addEnums(Biome.class, newTypes); @@ -256,8 +258,9 @@ public class BukkitRegistry { List newTypes = new ArrayList<>(); Field key = Arrays.stream(Villager.Profession.class.getDeclaredFields()).filter(it -> it.getName().equals("key")).findAny().orElse(null); long keyOffset = Unsafe.objectFieldOffset(key); - for (VillagerProfession villagerProfession : ForgeRegistries.PROFESSIONS) { - String name = ResourceLocationUtil.standardize(villagerProfession.getRegistryName()); + for (VillagerProfession villagerProfession : ForgeRegistries.VILLAGER_PROFESSIONS) { + var location = ForgeRegistries.VILLAGER_PROFESSIONS.getKey(villagerProfession); + String name = ResourceLocationUtil.standardize(location); Villager.Profession profession; try { profession = Villager.Profession.valueOf(name); @@ -267,8 +270,8 @@ public class BukkitRegistry { if (profession == null) { profession = EnumHelper.makeEnum(Villager.Profession.class, name, i++, ImmutableList.of(), ImmutableList.of()); newTypes.add(profession); - Unsafe.putObject(profession, keyOffset, CraftNamespacedKey.fromMinecraft(villagerProfession.getRegistryName())); - ArclightMod.LOGGER.debug("Registered {} as villager profession {}", villagerProfession.getRegistryName(), profession); + Unsafe.putObject(profession, keyOffset, CraftNamespacedKey.fromMinecraft(location)); + ArclightMod.LOGGER.debug("Registered {} as villager profession {}", location, profession); } } EnumHelper.addEnums(Villager.Profession.class, newTypes); @@ -298,9 +301,9 @@ public class BukkitRegistry { private static void loadEntities() { int origin = EntityType.values().length; int i = origin; - List newTypes = new ArrayList<>(ForgeRegistries.ENTITIES.getEntries().size() - origin + 1); // UNKNOWN - for (net.minecraft.world.entity.EntityType type : ForgeRegistries.ENTITIES) { - ResourceLocation location = type.getRegistryName(); + List newTypes = new ArrayList<>(ForgeRegistries.ENTITY_TYPES.getEntries().size() - origin + 1); // UNKNOWN + for (net.minecraft.world.entity.EntityType type : ForgeRegistries.ENTITY_TYPES) { + ResourceLocation location = ForgeRegistries.ENTITY_TYPES.getKey(type); EntityType entityType = null; boolean found = false; if (location.getNamespace().equals(NamespacedKey.MINECRAFT)) { @@ -327,12 +330,13 @@ public class BukkitRegistry { putBool(Enchantment.class, "acceptingNew", true); for (net.minecraft.world.item.enchantment.Enchantment enc : ForgeRegistries.ENCHANTMENTS) { try { - String name = ResourceLocationUtil.standardize(enc.getRegistryName()); + var location = ForgeRegistries.ENCHANTMENTS.getKey(enc); + String name = ResourceLocationUtil.standardize(location); ArclightEnchantment enchantment = new ArclightEnchantment(enc, name); Enchantment.registerEnchantment(enchantment); - ArclightMod.LOGGER.debug("Registered {} as enchantment {}", enc.getRegistryName(), enchantment); + ArclightMod.LOGGER.debug("Registered {} as enchantment {}", location, enchantment); } catch (Exception e) { - ArclightMod.LOGGER.error("Failed to register enchantment {}: {}", enc.getRegistryName(), e); + ArclightMod.LOGGER.error("Failed to register enchantment {}: {}", enc, e); } } Enchantment.stopAcceptingRegistrations(); @@ -348,12 +352,13 @@ public class BukkitRegistry { putBool(PotionEffectType.class, "acceptingNew", true); for (MobEffect eff : ForgeRegistries.MOB_EFFECTS) { try { - String name = ResourceLocationUtil.standardize(eff.getRegistryName()); + var location = ForgeRegistries.MOB_EFFECTS.getKey(eff); + String name = ResourceLocationUtil.standardize(location); ArclightPotionEffect effect = new ArclightPotionEffect(eff, name); PotionEffectType.registerPotionEffectType(effect); - ArclightMod.LOGGER.debug("Registered {} as potion {}", eff.getRegistryName(), effect); + ArclightMod.LOGGER.debug("Registered {} as potion {}", location, effect); } catch (Exception e) { - ArclightMod.LOGGER.error("Failed to register potion type {}: {}", eff.getRegistryName(), e); + ArclightMod.LOGGER.error("Failed to register potion type {}: {}", eff, e); } } PotionEffectType.stopAcceptingRegistrations(); @@ -363,15 +368,16 @@ public class BukkitRegistry { BiMap map = HashBiMap.create(Unsafe.getStatic(CraftPotionUtil.class, "regular")); putStatic(CraftPotionUtil.class, "regular", map); for (var potion : ForgeRegistries.POTIONS) { - if (CraftPotionUtil.toBukkit(potion.getRegistryName().toString()).getType() == PotionType.UNCRAFTABLE && potion != Potions.EMPTY) { - String name = ResourceLocationUtil.standardize(potion.getRegistryName()); + var location = ForgeRegistries.POTIONS.getKey(potion); + if (CraftPotionUtil.toBukkit(location.toString()).getType() == PotionType.UNCRAFTABLE && potion != Potions.EMPTY) { + String name = ResourceLocationUtil.standardize(location); MobEffectInstance effectInstance = potion.getEffects().isEmpty() ? null : potion.getEffects().get(0); PotionType potionType = EnumHelper.makeEnum(PotionType.class, name, typeId++, Arrays.asList(PotionEffectType.class, boolean.class, boolean.class), Arrays.asList(effectInstance == null ? null : PotionEffectType.getById(MobEffect.getId(effectInstance.getEffect())), false, false)); newTypes.add(potionType); - map.put(potionType, potion.getRegistryName().toString()); - ArclightMod.LOGGER.debug("Registered {} as potion type {}", potion.getRegistryName(), potionType); + map.put(potionType, location.toString()); + ArclightMod.LOGGER.debug("Registered {} as potion type {}", location, potionType); } } EnumHelper.addEnums(PotionType.class, newTypes); @@ -383,7 +389,7 @@ public class BukkitRegistry { int origin = i; List list = new ArrayList<>(); for (Block block : ForgeRegistries.BLOCKS) { - ResourceLocation location = block.getRegistryName(); + ResourceLocation location = ForgeRegistries.BLOCKS.getKey(block); String name = ResourceLocationUtil.standardize(location); Material material = BY_NAME.get(name); if (material == null) { @@ -407,7 +413,7 @@ public class BukkitRegistry { } } for (Item item : ForgeRegistries.ITEMS) { - ResourceLocation location = item.getRegistryName(); + ResourceLocation location = ForgeRegistries.ITEMS.getKey(item); String name = ResourceLocationUtil.standardize(location); Material material = BY_NAME.get(name); if (material == null) { @@ -467,7 +473,7 @@ public class BukkitRegistry { private static Set> registries() { return ImmutableSet.of(ForgeRegistries.BLOCKS, ForgeRegistries.ITEMS, ForgeRegistries.MOB_EFFECTS, ForgeRegistries.POTIONS, - ForgeRegistries.ENTITIES, ForgeRegistries.BLOCK_ENTITIES, + ForgeRegistries.ENTITY_TYPES, ForgeRegistries.BLOCK_ENTITY_TYPES, ForgeRegistries.BIOMES); } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/entity/ArclightModChestedHorse.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/entity/ArclightModChestedHorse.java index 8f9b59ef..85e7cb41 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/entity/ArclightModChestedHorse.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/entity/ArclightModChestedHorse.java @@ -16,7 +16,7 @@ public class ArclightModChestedHorse extends CraftChestedHorse { public ArclightModChestedHorse(CraftServer server, AbstractChestedHorse entity) { super(server, entity); - this.entityType = EntityType.valueOf(ResourceLocationUtil.standardize(ForgeRegistries.ENTITIES.getKey(entity.getType()))); + this.entityType = EntityType.valueOf(ResourceLocationUtil.standardize(ForgeRegistries.ENTITY_TYPES.getKey(entity.getType()))); } @Override diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/entity/ArclightModEntity.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/entity/ArclightModEntity.java index af7fa6c5..caf357ba 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/entity/ArclightModEntity.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/entity/ArclightModEntity.java @@ -14,7 +14,7 @@ public class ArclightModEntity extends CraftEntity { public ArclightModEntity(CraftServer server, Entity entity) { super(server, entity); - this.entityType = EntityType.valueOf(ResourceLocationUtil.standardize(ForgeRegistries.ENTITIES.getKey(entity.getType()))); + this.entityType = EntityType.valueOf(ResourceLocationUtil.standardize(ForgeRegistries.ENTITY_TYPES.getKey(entity.getType()))); } @Override diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/entity/ArclightModHorse.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/entity/ArclightModHorse.java index 9c3895ea..feb83f60 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/entity/ArclightModHorse.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/entity/ArclightModHorse.java @@ -16,7 +16,7 @@ public class ArclightModHorse extends CraftAbstractHorse { public ArclightModHorse(CraftServer server, AbstractHorse entity) { super(server, entity); - this.entityType = EntityType.valueOf(ResourceLocationUtil.standardize(ForgeRegistries.ENTITIES.getKey(entity.getType()))); + this.entityType = EntityType.valueOf(ResourceLocationUtil.standardize(ForgeRegistries.ENTITY_TYPES.getKey(entity.getType()))); } @Override diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/entity/ArclightModLivingEntity.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/entity/ArclightModLivingEntity.java index f53f6d79..78803b4f 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/entity/ArclightModLivingEntity.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/entity/ArclightModLivingEntity.java @@ -14,7 +14,7 @@ public class ArclightModLivingEntity extends CraftLivingEntity { public ArclightModLivingEntity(CraftServer server, LivingEntity entity) { super(server, entity); - this.entityType = EntityType.valueOf(ResourceLocationUtil.standardize(ForgeRegistries.ENTITIES.getKey(entity.getType()))); + this.entityType = EntityType.valueOf(ResourceLocationUtil.standardize(ForgeRegistries.ENTITY_TYPES.getKey(entity.getType()))); } @Override diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/entity/ArclightModMinecart.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/entity/ArclightModMinecart.java index b52b7e4c..1f500eac 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/entity/ArclightModMinecart.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/entity/ArclightModMinecart.java @@ -14,7 +14,7 @@ public class ArclightModMinecart extends CraftMinecart { public ArclightModMinecart(CraftServer server, AbstractMinecart entity) { super(server, entity); - this.entityType = EntityType.valueOf(ResourceLocationUtil.standardize(ForgeRegistries.ENTITIES.getKey(entity.getType()))); + this.entityType = EntityType.valueOf(ResourceLocationUtil.standardize(ForgeRegistries.ENTITY_TYPES.getKey(entity.getType()))); } @Override diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/entity/ArclightModMinecartContainer.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/entity/ArclightModMinecartContainer.java index 26007283..1a80e518 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/entity/ArclightModMinecartContainer.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/entity/ArclightModMinecartContainer.java @@ -14,7 +14,7 @@ public class ArclightModMinecartContainer extends CraftMinecartContainer { public ArclightModMinecartContainer(CraftServer server, AbstractMinecartContainer entity) { super(server, entity); - this.entityType = EntityType.valueOf(ResourceLocationUtil.standardize(ForgeRegistries.ENTITIES.getKey(entity.getType()))); + this.entityType = EntityType.valueOf(ResourceLocationUtil.standardize(ForgeRegistries.ENTITY_TYPES.getKey(entity.getType()))); } @Override diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/entity/ArclightModMob.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/entity/ArclightModMob.java index 13fc7a46..16f406d2 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/entity/ArclightModMob.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/entity/ArclightModMob.java @@ -15,7 +15,7 @@ public class ArclightModMob extends CraftMob { public ArclightModMob(CraftServer server, Mob entity) { super(server, entity); - this.entityType = EntityType.valueOf(ResourceLocationUtil.standardize(ForgeRegistries.ENTITIES.getKey(entity.getType()))); + this.entityType = EntityType.valueOf(ResourceLocationUtil.standardize(ForgeRegistries.ENTITY_TYPES.getKey(entity.getType()))); } @Override diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/entity/ArclightModProjectile.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/entity/ArclightModProjectile.java index de874686..860ac630 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/entity/ArclightModProjectile.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/entity/ArclightModProjectile.java @@ -15,7 +15,7 @@ public class ArclightModProjectile extends CraftProjectile { public ArclightModProjectile(CraftServer server, Entity entity) { super(server, (Projectile) entity); - this.entityType = EntityType.valueOf(ResourceLocationUtil.standardize(ForgeRegistries.ENTITIES.getKey(entity.getType()))); + this.entityType = EntityType.valueOf(ResourceLocationUtil.standardize(ForgeRegistries.ENTITY_TYPES.getKey(entity.getType()))); } @Override diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/entity/ArclightModRaider.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/entity/ArclightModRaider.java index e0ac5015..68dfc3e9 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/entity/ArclightModRaider.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/entity/ArclightModRaider.java @@ -15,7 +15,7 @@ public class ArclightModRaider extends CraftRaider { public ArclightModRaider(CraftServer server, Raider entity) { super(server, entity); - this.entityType = EntityType.valueOf(ResourceLocationUtil.standardize(ForgeRegistries.ENTITIES.getKey(entity.getType()))); + this.entityType = EntityType.valueOf(ResourceLocationUtil.standardize(ForgeRegistries.ENTITY_TYPES.getKey(entity.getType()))); } @Override diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/event/ArclightEventDispatcherRegistry.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/event/ArclightEventDispatcherRegistry.java index 3f8dd6af..98ab5165 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/event/ArclightEventDispatcherRegistry.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/event/ArclightEventDispatcherRegistry.java @@ -13,7 +13,6 @@ public abstract class ArclightEventDispatcherRegistry { MinecraftForge.EVENT_BUS.register(new EntityTeleportEventDispatcher()); MinecraftForge.EVENT_BUS.register(new ItemEntityEventDispatcher()); MinecraftForge.EVENT_BUS.register(new WorldEventDispatcher()); - MinecraftForge.EVENT_BUS.register(new ChunkEventHandler()); ArclightMod.LOGGER.info("registry.forge-event"); } 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 07c470d6..dba37a53 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,11 +2,12 @@ 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.ArclightCaptures; 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; -import net.minecraftforge.event.world.BlockEvent; +import net.minecraftforge.event.level.BlockEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import org.bukkit.Bukkit; import org.bukkit.craftbukkit.v.block.CraftBlock; @@ -15,14 +16,13 @@ import org.bukkit.event.Cancellable; import org.bukkit.event.block.Action; import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.entity.EntityInteractEvent; -import io.izzel.arclight.common.mod.util.ArclightCaptures; public class BlockBreakEventDispatcher { @SubscribeEvent(receiveCanceled = true) public void onBreakBlock(BlockEvent.BreakEvent event) { - if (DistValidate.isValid(event.getWorld())) { - CraftBlock craftBlock = CraftBlock.at(event.getWorld(), event.getPos()); + if (DistValidate.isValid(event.getLevel())) { + CraftBlock craftBlock = CraftBlock.at(event.getLevel(), event.getPos()); BlockBreakEvent breakEvent = new BlockBreakEvent(craftBlock, ((ServerPlayerEntityBridge) event.getPlayer()).bridge$getBukkitEntity()); ArclightCaptures.captureBlockBreakPlayer(breakEvent); breakEvent.setCancelled(event.isCanceled()); @@ -35,13 +35,13 @@ public class BlockBreakEventDispatcher { @SubscribeEvent public void onFarmlandBreak(BlockEvent.FarmlandTrampleEvent event) { - if (!DistValidate.isValid(event.getWorld())) return; + if (!DistValidate.isValid(event.getLevel())) return; Entity entity = event.getEntity(); Cancellable cancellable; if (entity instanceof Player) { cancellable = CraftEventFactory.callPlayerInteractEvent((Player) entity, Action.PHYSICAL, event.getPos(), null, null, null); } else { - cancellable = new EntityInteractEvent(((EntityBridge) entity).bridge$getBukkitEntity(), CraftBlock.at(event.getWorld(), event.getPos())); + cancellable = new EntityInteractEvent(((EntityBridge) entity).bridge$getBukkitEntity(), CraftBlock.at(event.getLevel(), event.getPos())); Bukkit.getPluginManager().callEvent((EntityInteractEvent) cancellable); } 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 2f66e4e2..ae893d0e 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 @@ -8,7 +8,7 @@ import net.minecraft.core.Direction; import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.Entity; import net.minecraftforge.common.util.BlockSnapshot; -import net.minecraftforge.event.world.BlockEvent; +import net.minecraftforge.event.level.BlockEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import org.bukkit.Bukkit; import org.bukkit.block.BlockState; @@ -30,10 +30,10 @@ public class BlockPlaceEventDispatcher { if (entity instanceof ServerPlayerEntityBridge playerEntity) { Player player = playerEntity.bridge$getBukkitEntity(); Direction direction = ArclightCaptures.getPlaceEventDirection(); - if (direction != null && DistValidate.isValid(event.getWorld())) { + if (direction != null && DistValidate.isValid(event.getLevel())) { 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())); + CraftBlock againstBlock = CraftBlock.at(event.getLevel(), event.getPos().relative(direction.getOpposite())); ItemStack bukkitStack; EquipmentSlot bukkitHand; if (hand == InteractionHand.MAIN_HAND) { @@ -65,13 +65,13 @@ public class BlockPlaceEventDispatcher { if (entity instanceof ServerPlayerEntityBridge playerEntity) { Player player = playerEntity.bridge$getBukkitEntity(); Direction direction = ArclightCaptures.getPlaceEventDirection(); - if (direction != null && DistValidate.isValid(event.getWorld())) { + if (direction != null && DistValidate.isValid(event.getLevel())) { InteractionHand hand = ArclightCaptures.getPlaceEventHand(InteractionHand.MAIN_HAND); List placedBlocks = new ArrayList<>(event.getReplacedBlockSnapshots().size()); for (BlockSnapshot snapshot : event.getReplacedBlockSnapshots()) { placedBlocks.add(ArclightBlockSnapshot.fromBlockSnapshot(snapshot, true).getState()); } - CraftBlock againstBlock = CraftBlock.at(event.getWorld(), event.getPos().relative(direction.getOpposite())); + CraftBlock againstBlock = CraftBlock.at(event.getLevel(), event.getPos().relative(direction.getOpposite())); ItemStack bukkitStack; if (hand == InteractionHand.MAIN_HAND) { bukkitStack = player.getInventory().getItemInMainHand(); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/event/ChunkEventHandler.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/event/ChunkEventHandler.java deleted file mode 100644 index b70d7b24..00000000 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/event/ChunkEventHandler.java +++ /dev/null @@ -1,36 +0,0 @@ -package io.izzel.arclight.common.mod.server.event; - -import io.izzel.arclight.common.bridge.core.world.chunk.ChunkBridge; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.Tag; -import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.chunk.ChunkStatus; -import net.minecraftforge.event.world.ChunkDataEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import org.bukkit.craftbukkit.v.persistence.CraftPersistentDataContainer; - -public class ChunkEventHandler { - - @SubscribeEvent - public void onChunkLoad(ChunkDataEvent.Load event) { - if (event.getStatus() == ChunkStatus.ChunkType.LEVELCHUNK) { - ChunkAccess chunk = event.getChunk(); - CompoundTag nbt = event.getData(); - Tag values = nbt.get("ChunkBukkitValues"); - if (values instanceof CompoundTag) { - ((ChunkBridge) chunk).bridge$getPersistentContainer().putAll((CompoundTag) values); - } - } - } - - @SubscribeEvent - public void onChunkSave(ChunkDataEvent.Save event) { - ChunkAccess chunk = event.getChunk(); - if (chunk instanceof ChunkBridge) { - CraftPersistentDataContainer container = ((ChunkBridge) chunk).bridge$getPersistentContainer(); - if (!container.isEmpty()) { - event.getData().put("ChunkBukkitValues", container.toTagCompound()); - } - } - } -} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/event/EntityEventDispatcher.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/event/EntityEventDispatcher.java index de3ac9ad..56d176e9 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/event/EntityEventDispatcher.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/event/EntityEventDispatcher.java @@ -22,13 +22,13 @@ public class EntityEventDispatcher { @SubscribeEvent(receiveCanceled = true) public void onLivingDeath(LivingDropsEvent event) { - if (event.getEntityLiving() instanceof ServerPlayer) { + if (event.getEntity() instanceof ServerPlayer) { // handled at ServerPlayerEntityMixin#onDeath // Cancelled at io.izzel.arclight.common.mixin.core.world.entity.LivingEntityMixin#arclight$cancelEvent // event.setCanceled(true); return; } - LivingEntity livingEntity = event.getEntityLiving(); + LivingEntity livingEntity = event.getEntity(); Collection drops = event.getDrops(); if (!(drops instanceof ArrayList)) { drops = new ArrayList<>(drops); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/event/EntityPotionEffectEventDispatcher.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/event/EntityPotionEffectEventDispatcher.java index e64a690f..ab41bb2b 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/event/EntityPotionEffectEventDispatcher.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/event/EntityPotionEffectEventDispatcher.java @@ -1,22 +1,21 @@ package io.izzel.arclight.common.mod.server.event; import io.izzel.arclight.common.bridge.core.entity.LivingEntityBridge; -import net.minecraftforge.event.entity.living.PotionEvent; +import net.minecraftforge.event.entity.living.MobEffectEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import org.bukkit.craftbukkit.v.event.CraftEventFactory; import org.bukkit.event.entity.EntityPotionEffectEvent; public class EntityPotionEffectEventDispatcher { - // todo 再检查一遍 @SubscribeEvent(receiveCanceled = true) - public void onPotionRemove(PotionEvent.PotionRemoveEvent event) { - if (event.getPotionEffect() == null) { + public void onPotionRemove(MobEffectEvent.Remove event) { + if (event.getEffectInstance() == null) { return; } - EntityPotionEffectEvent.Cause cause = ((LivingEntityBridge) event.getEntityLiving()).bridge$getEffectCause().orElse(EntityPotionEffectEvent.Cause.UNKNOWN); - EntityPotionEffectEvent.Action action = ((LivingEntityBridge) event.getEntityLiving()).bridge$getAndResetAction(); - EntityPotionEffectEvent bukkitEvent = CraftEventFactory.callEntityPotionEffectChangeEvent(event.getEntityLiving(), event.getPotionEffect(), null, cause, action); + EntityPotionEffectEvent.Cause cause = ((LivingEntityBridge) event.getEntity()).bridge$getEffectCause().orElse(EntityPotionEffectEvent.Cause.UNKNOWN); + EntityPotionEffectEvent.Action action = ((LivingEntityBridge) event.getEntity()).bridge$getAndResetAction(); + EntityPotionEffectEvent bukkitEvent = CraftEventFactory.callEntityPotionEffectChangeEvent(event.getEntity(), event.getEffectInstance(), null, cause, action); event.setCanceled(bukkitEvent.isCancelled()); } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/event/ItemEntityEventDispatcher.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/event/ItemEntityEventDispatcher.java index c0955d8a..39d7b683 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/event/ItemEntityEventDispatcher.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/event/ItemEntityEventDispatcher.java @@ -8,6 +8,6 @@ public class ItemEntityEventDispatcher { @SubscribeEvent(receiveCanceled = true) public void onExpire(ItemExpireEvent event) { - event.setCanceled(CraftEventFactory.callItemDespawnEvent(event.getEntityItem()).isCancelled()); + event.setCanceled(CraftEventFactory.callItemDespawnEvent(event.getEntity()).isCancelled()); } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/event/WorldEventDispatcher.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/event/WorldEventDispatcher.java index 7a7a9dac..092e4440 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/event/WorldEventDispatcher.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/event/WorldEventDispatcher.java @@ -2,16 +2,16 @@ package io.izzel.arclight.common.mod.server.event; import io.izzel.arclight.common.bridge.bukkit.CraftServerBridge; import net.minecraft.server.level.ServerLevel; -import net.minecraftforge.event.world.WorldEvent; +import net.minecraftforge.event.level.LevelEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import org.bukkit.Bukkit; public class WorldEventDispatcher { @SubscribeEvent - public void onWorldUnload(WorldEvent.Unload event) { - if (event.getWorld() instanceof ServerLevel) { - ((CraftServerBridge) Bukkit.getServer()).bridge$removeWorld(((ServerLevel) event.getWorld())); + public void onWorldUnload(LevelEvent.Unload event) { + if (event.getLevel() instanceof ServerLevel level) { + ((CraftServerBridge) Bukkit.getServer()).bridge$removeWorld(level); } } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/ArclightCaptures.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/ArclightCaptures.java index 75f2cb83..330cc670 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/ArclightCaptures.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/ArclightCaptures.java @@ -14,6 +14,7 @@ import org.bukkit.TreeType; import org.bukkit.block.BlockState; import org.bukkit.craftbukkit.v.event.CraftPortalEvent; import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.entity.EntityPotionEffectEvent; import java.util.ArrayList; import java.util.List; @@ -242,6 +243,34 @@ public class ArclightCaptures { return (T) tickingBlockEntity; } + private static EntityPotionEffectEvent.Cause effectCause; + + public static void captureEffectCause(EntityPotionEffectEvent.Cause cause) { + effectCause = cause; + } + + public static EntityPotionEffectEvent.Cause getEffectCause() { + try { + return effectCause; + } finally { + effectCause = null; + } + } + + private static BlockPos spreadPos; + + public static void captureSpreadSource(BlockPos source) { + spreadPos = source.immutable(); + } + + public static BlockPos getSpreadPos() { + return spreadPos; + } + + public static void resetSpreadSource() { + spreadPos = null; + } + private static void recapture(String type) { throw new IllegalStateException("Recapturing " + type); } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/ArclightPingEvent.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/ArclightPingEvent.java index 6b783ff0..cdc193cc 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/ArclightPingEvent.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/ArclightPingEvent.java @@ -22,7 +22,7 @@ public class ArclightPingEvent extends ServerListPingEvent { private final Object[] players; public ArclightPingEvent(Connection networkManager, MinecraftServer server) { - super(((InetSocketAddress) networkManager.getRemoteAddress()).getAddress(), server.getMotd(), server.getPlayerList().getMaxPlayers()); + super(((InetSocketAddress) networkManager.getRemoteAddress()).getAddress(), server.getMotd(), server.previewsChat(), server.getPlayerList().getMaxPlayers()); this.icon = ((CraftServer) Bukkit.getServer()).getServerIcon(); this.players = server.getPlayerList().players.toArray(); } @@ -38,7 +38,7 @@ public class ArclightPingEvent extends ServerListPingEvent { @Override @NotNull public Iterator iterator() throws UnsupportedOperationException { - return new Iterator() { + return new Iterator<>() { int i; int ret = Integer.MIN_VALUE; ServerPlayer player; diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/PluginEventHandler.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/PluginEventHandler.java index aff54e78..a7a97b2b 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/PluginEventHandler.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/PluginEventHandler.java @@ -2,7 +2,6 @@ package io.izzel.arclight.common.mod.util; import io.izzel.arclight.api.Unsafe; import io.izzel.arclight.common.mod.ArclightMod; -import net.minecraftforge.eventbus.ASMEventHandler; import net.minecraftforge.eventbus.EventBus; import net.minecraftforge.eventbus.api.Event; import net.minecraftforge.eventbus.api.EventPriority; @@ -19,6 +18,8 @@ import java.lang.invoke.MethodType; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.WildcardType; import java.util.Arrays; import java.util.HashSet; import java.util.Optional; @@ -27,30 +28,52 @@ import java.util.concurrent.ConcurrentHashMap; import static org.objectweb.asm.Opcodes.*; -public class PluginEventHandler extends ASMEventHandler { +public class PluginEventHandler implements IEventListener { private static final String HANDLER_DESC = Type.getInternalName(IEventListener.class); private static final String HANDLER_FUNC_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(Event.class)); private static final MethodHandle MH_GET_LISTENERS; private static final MethodHandle MH_ADD_LISTENERS; - private static final MethodHandle MH_UNIQUE_NAME; static { try { MH_GET_LISTENERS = Unsafe.lookup().findGetter(EventBus.class, "listeners", ConcurrentHashMap.class); MH_ADD_LISTENERS = Unsafe.lookup().findVirtual(EventBus.class, "addToListeners", MethodType.methodType(void.class, Object.class, Class.class, IEventListener.class, EventPriority.class)); - MH_UNIQUE_NAME = Unsafe.lookup().findVirtual(ASMEventHandler.class, "getUniqueName", MethodType.methodType(String.class, Method.class)); } catch (Exception e) { throw new RuntimeException(e); } } - private final Plugin plugin; + private final IEventListener handler; + private final SubscribeEvent subInfo; + private java.lang.reflect.Type filter = null; + private String readable; - public PluginEventHandler(Plugin plugin, Object target, Method method, boolean isGeneric) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException { - super(target, method, isGeneric); - this.plugin = plugin; + + public PluginEventHandler(Plugin plugin, Object target, Method method, boolean isGeneric) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { + if (Modifier.isStatic(method.getModifiers())) { + handler = (IEventListener) createWrapper(method).getDeclaredConstructor().newInstance(); + } else { + handler = (IEventListener) createWrapper(method).getConstructor(Object.class).newInstance(target); + } + subInfo = method.getAnnotation(SubscribeEvent.class); + readable = "PL: " + plugin.getName() + " ASM: " + target + " " + method.getName() + Type.getMethodDescriptor(method); + if (isGeneric) { + java.lang.reflect.Type type = method.getGenericParameterTypes()[0]; + if (type instanceof ParameterizedType) { + filter = ((ParameterizedType) type).getActualTypeArguments()[0]; + if (filter instanceof ParameterizedType) // Unlikely that nested generics will ever be relevant for event filtering, so discard them + { + filter = ((ParameterizedType) filter).getRawType(); + } else if (filter instanceof WildcardType wfilter) { + // If there's a wildcard filter of Object.class, then remove the filter. + if (wfilter.getUpperBounds().length == 1 && wfilter.getUpperBounds()[0] == Object.class && wfilter.getLowerBounds().length == 0) { + filter = null; + } + } + } + } } @SuppressWarnings("unchecked") @@ -123,26 +146,26 @@ public class PluginEventHandler extends ASMEventHandler { private static void register(Class eventType, Object target, Method method, Plugin plugin, EventBus bus) { try { - ASMEventHandler asm = new PluginEventHandler(plugin, target, method, IGenericEvent.class.isAssignableFrom(eventType)); + var asm = new PluginEventHandler(plugin, target, method, IGenericEvent.class.isAssignableFrom(eventType)); MH_ADD_LISTENERS.invokeExact(bus, target, eventType, (IEventListener) asm, asm.getPriority()); } catch (Throwable e) { ArclightMod.LOGGER.error("Error registering event handler: {} {}", eventType, method, e); } } - @Override + private String getUniqueName(Method callback) { + return String.format("%s.__%s_%s_%s", callback.getDeclaringClass().getPackageName(), callback.getDeclaringClass().getSimpleName(), + callback.getName(), + callback.getParameterTypes()[0].getSimpleName()); + } + public Class createWrapper(Method callback) { ClassWriter cw = new ClassWriter(0); MethodVisitor mv; boolean isStatic = Modifier.isStatic(callback.getModifiers()); - String name; - try { - name = (String) MH_UNIQUE_NAME.invoke(this, callback); - } catch (Throwable throwable) { - throw new RuntimeException(throwable); - } + String name = getUniqueName(callback); String desc = name.replace('.', '/'); String instType = Type.getInternalName(callback.getDeclaringClass()); String eventType = Type.getInternalName(callback.getParameterTypes()[0]); @@ -188,8 +211,24 @@ public class PluginEventHandler extends ASMEventHandler { return Unsafe.defineClass(name, bytes, 0, bytes.length, callback.getDeclaringClass().getClassLoader(), callback.getDeclaringClass().getProtectionDomain()); } + public EventPriority getPriority() { + return subInfo.priority(); + } + + @SuppressWarnings("rawtypes") + @Override + public void invoke(Event event) { + if (handler != null) { + if (!event.isCancelable() || !event.isCanceled() || subInfo.receiveCanceled()) { + if (filter == null || filter == ((IGenericEvent) event).getGenericType()) { + handler.invoke(event); + } + } + } + } + @Override public String toString() { - return "PL:" + plugin.getName() + " " + super.toString(); + return readable; } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/ClassLoaderRepo.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/ClassLoaderRepo.java index c144a4ae..ba01c48a 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/ClassLoaderRepo.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/util/remapper/ClassLoaderRepo.java @@ -1,12 +1,14 @@ package io.izzel.arclight.common.mod.util.remapper; import io.izzel.arclight.api.PluginPatcher; +import io.izzel.arclight.api.Unsafe; import net.md_5.specialsource.repo.ClassRepo; import org.objectweb.asm.ClassReader; import org.objectweb.asm.tree.ClassNode; -import java.io.IOException; import java.io.InputStream; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodType; import java.net.URL; import java.net.URLClassLoader; import java.net.URLConnection; @@ -26,11 +28,11 @@ public class ClassLoaderRepo implements ClassRepo, PluginPatcher.ClassRepo { @Override public ClassNode findClass(String internalName, int parsingOptions) { - URL url = classLoader instanceof URLClassLoader - ? ((URLClassLoader) classLoader).findResource(internalName + ".class") // search local - : classLoader.getResource(internalName + ".class"); - if (url == null) return null; try { + URL url = classLoader instanceof URLClassLoader + ? ((URLClassLoader) classLoader).findResource(internalName + ".class") // search local + : (URL) H_FIND_RESOURCE.invokeExact(classLoader, internalName + ".class"); + if (url == null) return null; URLConnection connection = url.openConnection(); try (InputStream inputStream = connection.getInputStream()) { ClassReader reader = new ClassReader(inputStream); @@ -38,8 +40,18 @@ public class ClassLoaderRepo implements ClassRepo, PluginPatcher.ClassRepo { reader.accept(classNode, parsingOptions); return classNode; } - } catch (IOException ignored) { + } catch (Throwable ignored) { } return null; } + + private static final MethodHandle H_FIND_RESOURCE; + + static { + try { + H_FIND_RESOURCE = Unsafe.lookup().findVirtual(ClassLoader.class, "findResource", MethodType.methodType(URL.class, String.class)); + } catch (NoSuchMethodException | IllegalAccessException e) { + throw new RuntimeException(e); + } + } } diff --git a/arclight-common/src/main/resources/META-INF/accesstransformer.cfg b/arclight-common/src/main/resources/META-INF/accesstransformer.cfg index 2ac630ba..b5e62bc2 100644 --- a/arclight-common/src/main/resources/META-INF/accesstransformer.cfg +++ b/arclight-common/src/main/resources/META-INF/accesstransformer.cfg @@ -497,3 +497,37 @@ public net.minecraft.world.level.levelgen.structure.templatesystem.StructureMana public net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager m_163778_(Lnet/minecraft/resources/ResourceLocation;)Ljava/util/Optional; public net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager f_74326_ public net.minecraft.world.level.material.MaterialColor f_76387_ +# Bukkit 1.19 +public net.minecraft.util.datafix.fixes.BlockStateData m_14942_(ILjava/lang/String;[Ljava/lang/String;)V +public net.minecraft.world.entity.animal.frog.Tadpole f_218680_ +public net.minecraft.world.entity.animal.goat.Goat f_218750_ +public net.minecraft.world.entity.animal.goat.Goat f_218751_ +public net.minecraft.world.entity.animal.horse.SkeletonHorse f_30892_ +public net.minecraft.world.entity.decoration.Painting m_218891_(Lnet/minecraft/core/Holder;)V +public net.minecraft.world.entity.monster.Vex f_33978_ +public net.minecraft.world.entity.monster.Vex f_33979_ +public net.minecraft.world.entity.monster.Vindicator f_34071_ +public net.minecraft.world.entity.npc.Villager m_35524_()V +public net.minecraft.world.entity.vehicle.Boat f_38279_ +public net.minecraft.world.inventory.AnvilMenu f_39000_ +# public net.minecraft.world.item.BucketItem f_40687_ +public net.minecraft.world.item.trading.MerchantOffer f_45317_ +public net.minecraft.world.item.trading.MerchantOffer f_45316_ +public net.minecraft.world.level.block.FireBlock f_221147_ +public net.minecraft.world.level.block.entity.SculkShriekerBlockEntity f_222831_ +public net.minecraft.world.level.block.entity.EnderChestBlockEntity f_155511_ +public net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity f_58320_ +public net.minecraft.world.level.block.state.properties.IntegerProperty f_223001_ +public net.minecraft.world.level.block.state.properties.IntegerProperty f_223000_ +public net.minecraft.world.level.levelgen.structure.placement.StructurePlacement f_227026_ +public net.minecraft.world.level.levelgen.structure.placement.StructurePlacement f_227024_ +public net.minecraft.world.level.levelgen.structure.placement.StructurePlacement f_227023_ +public net.minecraft.world.level.levelgen.structure.placement.StructurePlacement f_227022_ +public net.minecraft.world.level.levelgen.structure.placement.StructurePlacement f_227025_ +public net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager m_230411_(Ljava/nio/file/Path;Lnet/minecraft/resources/ResourceLocation;Ljava/lang/String;)Ljava/nio/file/Path; +public net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager m_230431_(Lnet/minecraft/resources/ResourceLocation;)Ljava/util/Optional; +public net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager m_230427_(Lnet/minecraft/resources/ResourceLocation;)Ljava/util/Optional; +public net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager m_230404_(Lnet/minecraft/nbt/CompoundTag;)Lnet/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate; +public net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager f_230345_ +public net.minecraft.world.level.storage.LevelStorageSource$LevelStorageAccess f_230867_ +public-f net.minecraft.server.ReloadableServerResources f_206847_ diff --git a/arclight-common/src/main/resources/mixins.arclight.core.json b/arclight-common/src/main/resources/mixins.arclight.core.json index e95c0b87..a623ebc6 100644 --- a/arclight-common/src/main/resources/mixins.arclight.core.json +++ b/arclight-common/src/main/resources/mixins.arclight.core.json @@ -39,11 +39,9 @@ "network.chat.StyleMixin", "network.chat.TextColorMixin", "network.protocol.PacketThreadUtilMixin", - "network.protocol.game.CChatMessagePacketMixin", "network.protocol.game.CCloseWindowPacketMixin", "network.protocol.game.CPlayerTryUseItemOnBlockPacketMixin", "network.protocol.game.CPlayerTryUseItemPacketMixin", - "network.protocol.game.SChatPacketMixin", "network.protocol.game.SWorldBorderPacketMixin", "network.protocol.handshake.CHandshakePacketMixin", "network.rcon.RConConsoleSourceMixin", @@ -53,7 +51,7 @@ "server.PlayerAdvancementsMixin", "server.ServerFunctionManagerMixin", "server.ServerScoreboardMixin", - "server.WorldStemMixin", + "server.WorldLoader_PackConfigMixin", "server.commands.EffectCommandMixin", "server.commands.GameRuleCommandMixin", "server.commands.ReloadCommandMixin", @@ -87,6 +85,7 @@ "world.damagesource.DamageSourceMixin", "world.damagesource.IndirectEntityDamageSourceMixin", "world.effect.MobEffectMixin", + "world.effect.MobEffectUtilMixin", "world.entity.AgeableMobMixin", "world.entity.AreaEffectCloudEntityMixin", "world.entity.EntityMixin", @@ -98,7 +97,6 @@ "world.entity.LivingEntityMixin", "world.entity.MobMixin", "world.entity.PathfinderMobMixin", - "world.entity.ai.attributes.RangedAttributeMixin", "world.entity.ai.behavior.AssignProfessionFromJobSiteMixin", "world.entity.ai.behavior.HarvestFarmlandMixin", "world.entity.ai.behavior.InteractWithDoorMixin", @@ -153,6 +151,8 @@ "world.entity.animal.TurtleMixin", "world.entity.animal.WolfMixin", "world.entity.animal.axolotl.AxolotlMixin", + "world.entity.animal.frog.TadpoleMixin", + "world.entity.animal.goat.GoatMixin", "world.entity.animal.horse.AbstractHorseMixin", "world.entity.animal.horse.LlamaMixin", "world.entity.animal.horse.TraderLlamaEntity_FollowTraderGoalMixin", @@ -187,6 +187,7 @@ "world.entity.monster.SlimeMixin", "world.entity.monster.SpellcastingIllager_UseSpellGoalMixin", "world.entity.monster.SpiderMixin", + "world.entity.monster.StriderMixin", "world.entity.monster.Vex_CopyOwnerTargetGoalMixin", "world.entity.monster.WitchMixin", "world.entity.monster.WitherSkeletonMixin", @@ -195,7 +196,9 @@ "world.entity.monster.ZombifiedPiglinMixin", "world.entity.monster.piglin.PiglinAiMixin", "world.entity.monster.piglin.PiglinMixin", + "world.entity.monster.warden.WardenMixin", "world.entity.npc.AbstractVillagerMixin", + "world.entity.npc.InventoryCarrierMixin", "world.entity.npc.VillagerMixin", "world.entity.npc.WanderingTraderMixin", "world.entity.player.InventoryMixin", @@ -228,12 +231,11 @@ "world.entity.vehicle.AbstractMinecartContainerMixin", "world.entity.vehicle.AbstractMinecartMixin", "world.entity.vehicle.BoatMixin", + "world.entity.vehicle.ChestBoatMixin", "world.entity.vehicle.MinecartCommandBlock_MinecartCommandBaseMixin", "world.food.FoodDataMixin", "world.gen.WorldGenRegionMixin", - "world.gen.feature.structure.StructureFeatureManagerMixin", "world.gen.feature.structure.SwampHutPieceMixin", - "world.gen.feature.template.TemplateManagerMixin", "world.inventory.AbstractContainerMenuMixin", "world.inventory.AbstractFurnaceContainerMixin", "world.inventory.BeaconContainerMixin", @@ -320,7 +322,9 @@ "world.level.block.BasePressurePlateBlockMixin", "world.level.block.BedBlockMixin", "world.level.block.BeehiveBlockMixin", + "world.level.block.BigDripleafBlockMixin", "world.level.block.BlockMixin", + "world.level.block.BuddingAmethystBlockMixin", "world.level.block.BushBlockMixin", "world.level.block.ButtonBlockMixin", "world.level.block.CactusBlockMixin", @@ -329,6 +333,7 @@ "world.level.block.CarvedPumpkinBlockMixin", "world.level.block.CauldronBlockMixin", "world.level.block.CaveVinesMixin", + "world.level.block.ChangeOverTimeBlockMixin", "world.level.block.ChestBlock2_1Mixin", "world.level.block.ChestBlockMixin", "world.level.block.ChorusFlowerBlockMixin", @@ -348,6 +353,7 @@ "world.level.block.DaylightDetectorBlockMixin", "world.level.block.DetectorRailBlockMixin", "world.level.block.DiodeBlockMixin", + "world.level.block.DirtPathBlockMixin", "world.level.block.DispenserBlockMixin_Accessor", "world.level.block.DoorBlockMixin", "world.level.block.DoublePlantBlockMixin", @@ -367,27 +373,38 @@ "world.level.block.LeavesBlockMixin", "world.level.block.LecternBlockMixin", "world.level.block.LeverBlockMixin", + "world.level.block.LightningRodBlockMixin", "world.level.block.LilyPadBlockMixin", "world.level.block.LiquidBlockMixin", "world.level.block.MagmaBlockMixin", + "world.level.block.MultifaceSpreader_SpreadConfigMixin", + "world.level.block.MultifaceSpreaderMixin", "world.level.block.MushroomBlockMixin", "world.level.block.NetherPortalBlockMixin", "world.level.block.NetherWartBlockMixin", "world.level.block.NoteBlockMixin", + "world.level.block.NyliumBlockMixin", "world.level.block.ObserverBlockMixin", "world.level.block.PistonBlockMixin", "world.level.block.PointedDripstoneBlockMixin", "world.level.block.PortalInfoMixin", "world.level.block.PortalShapeMixin", + "world.level.block.PowderSnowBlockMixin", "world.level.block.PoweredRailBlockMixin", "world.level.block.PressurePlateBlockMixin", "world.level.block.RedstoneLampBlockMixin", "world.level.block.RedstoneOreBlockMixin", "world.level.block.RedstoneTorchBlockMixin", "world.level.block.RedstoneWireBlockMixin", + "world.level.block.RootedDirtBlockMixin", "world.level.block.SaplingBlockMixin", "world.level.block.ScaffoldingBlockMixin", + "world.level.block.SculkBlockMixin", + "world.level.block.SculkSensorBlockMixin", + "world.level.block.SculkShriekerBlockMixin", + "world.level.block.SculkVeinBlockMixin", "world.level.block.SnowBlockMixin", + "world.level.block.SnowLayerBlockMixin", "world.level.block.SpongeBlockMixin", "world.level.block.SpreadableSnowyDirtBlockMixin", "world.level.block.StemBlockMixin", @@ -413,19 +430,21 @@ "world.level.block.entity.CommandBlockLogicMixin", "world.level.block.entity.CommandBlockTileEntity1Mixin", "world.level.block.entity.ConduitBlockEntityMixin", + "world.level.block.entity.ContainerOpenersCounterMixin", "world.level.block.entity.DispenserBlockEntityMixin", "world.level.block.entity.EndGatewayBlockEntityMixin", "world.level.block.entity.HopperBlockEntityMixin", "world.level.block.entity.LecternBlockEntityMixin", "world.level.block.entity.LecternTileEntity1Mixin", "world.level.block.entity.LockableBlockEntityMixin", + "world.level.block.entity.SculkCatalystBlockEntityMixin", "world.level.block.entity.ShulkerBoxBlockEntityMixin", "world.level.block.entity.SignBlockEntityMixin", "world.level.block.state.BlockBehaviour_BlockStateBaseMixin", "world.level.block.state.BlockBehaviourMixin", - "world.level.block.state.properties.IntegerPropertyMixin", "world.level.border.WorldBorderMixin", "world.level.chunk.ChunkAccessMixin", + "world.level.chunk.ChunkGeneratorMixin", "world.level.chunk.LevelChunk_BoundTickingBlockEntityMixin", "world.level.chunk.LevelChunkMixin", "world.level.chunk.LevelChunkSectionMixin", @@ -434,9 +453,9 @@ "world.level.chunk.storage.RegionFileCacheMixin", "world.level.entity.PersistentEntitySectionManagerMixin", "world.level.gameevent.vibrations.VibrationListenerMixin", - "world.level.levelgen.ChunkGeneratorMixin", "world.level.levelgen.structure.templatesystem.StructureTemplateMixin", "world.level.portal.PortalForcerMixin", + "world.level.redstone.NeighborUpdaterMixin", "world.level.saveddata.maps.MapDataMixin", "world.level.saveddata.maps.MapItemSavedData_HoldingPlayerMixin", "world.level.storage.loot.LootTableManagerMixin", @@ -447,15 +466,15 @@ "world.level.storage.loot.predicates.RandomChanceWithLootingMixin", "world.level.storage.loot.predicates.SurvivesExplosionMixin", "world.spawner.BaseSpawnerMixin", + "world.spawner.NaturalSpawnerMixin", "world.spawner.PatrolSpawnerMixin", "world.spawner.PhantomSpawnerMixin", "world.spawner.WanderingTraderSpawnerMixin", "world.spawner.WorldEntitySpawner_EntityDensityManagerMixin", - "world.spawner.WorldEntitySpawnerMixin", "world.storage.DerivedWorldInfoMixin", "world.storage.LevelStorageSource_LevelStorageAccessMixin", "world.storage.LevelStorageSourceMixin", "world.storage.PlayerDataMixin", - "world.storage.ServerWorldInfoMixin" + "world.storage.PrimaryLevelDataMixin" ] } \ No newline at end of file diff --git a/arclight-common/src/main/resources/mixins.arclight.impl.forge.optimization.dfu.json b/arclight-common/src/main/resources/mixins.arclight.impl.forge.optimization.dfu.json deleted file mode 100644 index 635496eb..00000000 --- a/arclight-common/src/main/resources/mixins.arclight.impl.forge.optimization.dfu.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "minVersion": "0.8", - "package": "io.izzel.arclight.common.mixin.optimization.dfu", - "target": "@env(DEFAULT)", - "refmap": "mixins.arclight.refmap.json", - "compatibilityLevel": "JAVA_11", - "mixins": [ - "BlockEntityTypeMixin_DFU", - "CraftMagicNumbersMixin_DFU", - "DataFixesManagerMixin_DFU", - "EntityType_BuilderMixin_DFU", - "MainMixin_DFU" - ] -} \ No newline at end of file diff --git a/arclight-forge/build.gradle b/arclight-forge/build.gradle index 05fef20f..60c964c7 100644 --- a/arclight-forge/build.gradle +++ b/arclight-forge/build.gradle @@ -39,12 +39,13 @@ repositories { maven { url = 'https://files.minecraftforge.net/maven/' } maven { url = 'https://jitpack.io/' } maven { url = 'https://maven.izzel.io/releases' } + mavenCentral() } def embedLibs = [/*"org.spongepowered:mixin:$mixinVersion", */ 'org.yaml:snakeyaml:1.30', - 'org.xerial:sqlite-jdbc:3.36.0.3', 'mysql:mysql-connector-java:8.0.27', + 'org.xerial:sqlite-jdbc:3.36.0.3', 'mysql:mysql-connector-java:8.0.29', /*'commons-lang:commons-lang:2.6',*/ 'com.googlecode.json-simple:json-simple:1.1.1', - 'org.apache.logging.log4j:log4j-jul:2.17.0', 'net.md-5:SpecialSource:1.11.0', + 'org.apache.logging.log4j:log4j-jul:2.17.2', 'net.md-5:SpecialSource:1.11.0', 'org.jline:jline-terminal-jansi:3.12.1', 'org.fusesource.jansi:jansi:1.18', /*'org.jline:jline-terminal:3.12.1', 'org.jline:jline-reader:3.12.1',*/ 'jline:jline:2.12.1', 'org.apache.maven:maven-resolver-provider:3.8.1', @@ -61,18 +62,18 @@ def embedLibs = [/*"org.spongepowered:mixin:$mixinVersion", */ 'org.yaml:snakeya 'com.typesafe:config:1.3.1'] dependencies { - implementation 'com.google.guava:guava:31.0.1-jre' - implementation 'org.ow2.asm:asm:9.2' - implementation 'org.ow2.asm:asm-tree:9.2' - implementation 'cpw.mods:modlauncher:9.0.7' - implementation 'cpw.mods:securejarhandler:0.9.45' - implementation 'net.minecraftforge:forgespi:4.0.9' - gson 'com.google.code.gson:gson:2.8.9' - implementation 'org.apache.logging.log4j:log4j-api:2.17.0' - implementation 'org.apache.logging.log4j:log4j-core:2.17.0' - implementation 'org.jetbrains:annotations:22.0.0' + implementation 'com.google.guava:guava:31.1-jre' + implementation 'org.ow2.asm:asm:9.3' + implementation 'org.ow2.asm:asm-tree:9.3' + implementation 'cpw.mods:modlauncher:9.0.24' + implementation 'cpw.mods:securejarhandler:2.1.4' + implementation 'net.minecraftforge:forgespi:6.0.0' + gson 'com.google.code.gson:gson:2.9.0' + implementation 'org.apache.logging.log4j:log4j-api:2.17.2' + implementation 'org.apache.logging.log4j:log4j-core:2.17.2' + implementation 'org.jetbrains:annotations:23.0.0' implementation 'org.spongepowered:mixin:0.8.3' - implementation 'org.apache.logging.log4j:log4j-jul:2.17.0' + implementation 'org.apache.logging.log4j:log4j-jul:2.17.2' for (def lib : embedLibs) { installer lib } @@ -196,6 +197,22 @@ compileApplaunchJava { sourceCompatibility = targetCompatibility = JavaVersion.VERSION_1_7 } +task runProdServer(type: JavaExec) { + classpath = files(tasks.jar) + systemProperties 'terminal.ansi': 'true' + systemProperties 'mixin.debug.export': 'true' + systemProperties 'arclight.alwaysExtract': 'true' + systemProperties 'arclight.remapper.dump': './.mixin.out/plugin_classes' + workingDir System.env.ARCLIGHT_PROD_DIR ?: file('run_prod') + maxHeapSize '4G' + args 'nogui' + standardInput System.in + javaLauncher.convention(javaToolchains.launcherFor { + languageVersion = JavaLanguageVersion.of(17) + }) + dependsOn project(':arclight-common').tasks.build, project.tasks.build +} + publishing { repositories { maven { diff --git a/arclight-forge/src/main/java/io/izzel/arclight/boot/AbstractBootstrap.java b/arclight-forge/src/main/java/io/izzel/arclight/boot/AbstractBootstrap.java index b5665f15..63dd5272 100644 --- a/arclight-forge/src/main/java/io/izzel/arclight/boot/AbstractBootstrap.java +++ b/arclight-forge/src/main/java/io/izzel/arclight/boot/AbstractBootstrap.java @@ -90,7 +90,7 @@ public class AbstractBootstrap { } protected void setupMod() throws Exception { - ArclightVersion.setVersion(ArclightVersion.v1_18_R2); + ArclightVersion.setVersion(ArclightVersion.v1_19_R1); try (InputStream stream = getClass().getModule().getResourceAsStream("/META-INF/MANIFEST.MF")) { Manifest manifest = new Manifest(stream); Attributes attributes = manifest.getMainAttributes(); diff --git a/arclight-forge/src/main/java/io/izzel/arclight/boot/mod/ArclightLocator_Forge.java b/arclight-forge/src/main/java/io/izzel/arclight/boot/mod/ArclightLocator_Forge.java index 11639aad..627cd92d 100644 --- a/arclight-forge/src/main/java/io/izzel/arclight/boot/mod/ArclightLocator_Forge.java +++ b/arclight-forge/src/main/java/io/izzel/arclight/boot/mod/ArclightLocator_Forge.java @@ -6,6 +6,7 @@ import cpw.mods.jarhandling.impl.SimpleJarMetadata; import net.minecraftforge.forgespi.language.IModFileInfo; import net.minecraftforge.forgespi.locating.IModFile; import net.minecraftforge.forgespi.locating.IModLocator; +import net.minecraftforge.forgespi.locating.IModProvider; import net.minecraftforge.forgespi.locating.ModFileFactory; import java.io.IOException; @@ -33,8 +34,8 @@ public class ArclightLocator_Forge implements IModLocator { } @Override - public List scanMods() { - return List.of(arclight); + public List scanMods() { + return List.of(new ModFileOrException(arclight, null)); } @Override @@ -65,7 +66,7 @@ public class ArclightLocator_Forge implements IModLocator { try { var cl = forName("net.minecraftforge.fml.loading.moddiscovery.ModFile"); var lookup = MethodHandles.lookup(); - var handle = lookup.findConstructor(cl, MethodType.methodType(void.class, SecureJar.class, IModLocator.class, ModFileFactory.ModFileInfoParser.class)); + var handle = lookup.findConstructor(cl, MethodType.methodType(void.class, SecureJar.class, IModProvider.class, ModFileFactory.ModFileInfoParser.class)); var version = System.getProperty("arclight.version"); var path = Paths.get(".arclight", "mod_file", version + ".jar"); var parserCl = forName("net.minecraftforge.fml.loading.moddiscovery.ModFileParser"); diff --git a/arclight-forge/src/main/resources/async_catcher.json b/arclight-forge/src/main/resources/async_catcher.json index 03597c19..71310db4 100644 --- a/arclight-forge/src/main/resources/async_catcher.json +++ b/arclight-forge/src/main/resources/async_catcher.json @@ -1,8 +1,7 @@ { "net/minecraft/server/level/ServerLevel": { "m_8872_(Lnet/minecraft/world/entity/Entity;)Z": "entity add", - "m_142646_()Lnet/minecraft/world/level/entity/LevelEntityGetter;": "chunk entity get", - "m_142346_(Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/level/gameevent/GameEvent;Lnet/minecraft/core/BlockPos;)V": "game event trigger" + "m_142646_()Lnet/minecraft/world/level/entity/LevelEntityGetter;": "chunk entity get" }, "net/minecraft/server/level/ServerLevel$EntityCallbacks": { "m_141985_(Lnet/minecraft/world/entity/Entity;)V": "entity register", diff --git a/build.gradle b/build.gradle index 570525f2..4ed82ac4 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ allprojects { group 'io.izzel.arclight' - version '1.0.6' + version '1.0.0-SNAPSHOT' def getGitHash = { -> def stdout = new ByteArrayOutputStream() @@ -13,9 +13,9 @@ allprojects { ext { agpVersion = '1.23' - minecraftVersion = '1.18.2' - forgeVersion = '40.1.59' - apiVersion = '1.2.6' + minecraftVersion = '1.19.1' + forgeVersion = '42.0.0' + apiVersion = '1.3.0' toolsVersion = '1.3.+' mixinVersion = '0.8.5' gitHash = getGitHash() diff --git a/forge-installer/src/main/java/io/izzel/arclight/forgeinstaller/ForgeInstaller.java b/forge-installer/src/main/java/io/izzel/arclight/forgeinstaller/ForgeInstaller.java index f0fc6ddf..a6411763 100644 --- a/forge-installer/src/main/java/io/izzel/arclight/forgeinstaller/ForgeInstaller.java +++ b/forge-installer/src/main/java/io/izzel/arclight/forgeinstaller/ForgeInstaller.java @@ -59,10 +59,10 @@ public class ForgeInstaller { private static final String SERVER_URL = "https://arclight.mcxk.net/net/minecraft/server/minecraft_server.%s.jar"; private static final String MAPPING_URL = "https://arclight.mcxk.net/net/minecraft/server/mappings_server.%s.txt"; private static final Map VERSION_HASH = Map.of( - "1.18.2", "c8f83c5655308435b3dcf03c06d9fe8740a77469" + "1.19.1", "8399e1211e95faa421c1507b322dbeae86d604df" ); private static final Map MAPPING_HASH = Map.of( - "1.18.2", "e562f588fea155d96291267465dc3323bfe1551b" + "1.19.1", "3565648cdd47ae15738fb804a95a659137d7cfd3" ); public static List modInstall(Consumer logger) throws Throwable { diff --git a/i18n-config/src/main/java/io/izzel/arclight/i18n/conf/OptimizationSpec.java b/i18n-config/src/main/java/io/izzel/arclight/i18n/conf/OptimizationSpec.java index eadc7411..08ef74a8 100644 --- a/i18n-config/src/main/java/io/izzel/arclight/i18n/conf/OptimizationSpec.java +++ b/i18n-config/src/main/java/io/izzel/arclight/i18n/conf/OptimizationSpec.java @@ -9,9 +9,6 @@ public class OptimizationSpec { @Setting("cache-plugin-class") private boolean cachePluginClass; - @Setting("disable-data-fixer") - private boolean disableDFU; - @Setting("goal-selector-update-interval") private int goalSelectorInterval; @@ -19,10 +16,6 @@ public class OptimizationSpec { return cachePluginClass; } - public boolean isDisableDFU() { - return disableDFU; - } - public int getGoalSelectorInterval() { return goalSelectorInterval; }