From 9e7575a95be84aa7489f269bc31e31d44c451240 Mon Sep 17 00:00:00 2001 From: IzzelAliz Date: Thu, 26 Aug 2021 22:17:58 +0800 Subject: [PATCH] Update spigot changes --- arclight-common/build.gradle | 7 +- .../level/levelgen/ChunkGeneratorBridge.java | 20 +++++ .../bukkit/CraftRegionAccessorMixin.java | 40 ++++++++++ .../common/mixin/bukkit/CraftWorldMixin.java | 20 +---- .../core/server/level/ServerLevelMixin.java | 3 +- .../mixin/core/world/ExplosionMixin.java | 8 +- .../mixin/core/world/entity/EntityMixin.java | 3 +- .../core/world/entity/LivingEntityMixin.java | 1 + .../world/entity/animal/MushroomCowMixin.java | 27 +++++++ .../world/entity/animal/SnowGolemMixin.java | 13 ++++ .../core/world/entity/monster/SlimeMixin.java | 1 + .../entity/player/ServerPlayerMixin.java | 11 ++- .../world/item/HangingEntityItemMixin.java | 3 +- .../mixin/core/world/level/LevelMixin.java | 37 ++++++--- .../level/levelgen/ChunkGeneratorMixin.java | 77 +++++++++++++++++++ .../NoiseBasedChunkGeneratorMixin.java | 53 +++++++++++++ .../resources/META-INF/accesstransformer.cfg | 2 + .../resources/mixins.arclight.bukkit.json | 1 + .../main/resources/mixins.arclight.core.json | 2 + ...xins.arclight.impl.forge.optimization.json | 2 +- 20 files changed, 289 insertions(+), 42 deletions(-) create mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/world/level/levelgen/ChunkGeneratorBridge.java create mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/CraftRegionAccessorMixin.java create mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/levelgen/ChunkGeneratorMixin.java create mode 100644 arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/levelgen/NoiseBasedChunkGeneratorMixin.java diff --git a/arclight-common/build.gradle b/arclight-common/build.gradle index af8efca6..24bfde07 100644 --- a/arclight-common/build.gradle +++ b/arclight-common/build.gradle @@ -4,15 +4,18 @@ buildscript { maven { url = 'https://repo.spongepowered.org/maven' } mavenCentral() maven { url = 'https://maven.izzel.io/releases' } + maven { url = 'https://maven.parchmentmc.org' } } dependencies { - classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: "${forge_gradle_version}" + classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: "${forge_gradle_version}", changing: true + classpath 'org.parchmentmc:librarian:1.+' classpath 'org.spongepowered:mixingradle:0.7.2-SNAPSHOT' classpath "io.izzel.arclight:arclight-gradle-plugin:$agpVersion" } } apply plugin: 'net.minecraftforge.gradle' +apply plugin: 'org.parchmentmc.librarian.forgegradle' apply plugin: 'org.spongepowered.mixin' apply plugin: 'java' apply plugin: 'idea' @@ -35,7 +38,7 @@ configurations { java.toolchain.languageVersion = JavaLanguageVersion.of(16) minecraft { - mappings channel: 'official', version: minecraftVersion + mappings channel: 'parchment', version: "2021.08.22-$minecraftVersion" accessTransformer = project.file('src/main/resources/META-INF/accesstransformer.cfg') } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/world/level/levelgen/ChunkGeneratorBridge.java b/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/world/level/levelgen/ChunkGeneratorBridge.java new file mode 100644 index 00000000..2f251287 --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/bridge/core/world/level/levelgen/ChunkGeneratorBridge.java @@ -0,0 +1,20 @@ +package io.izzel.arclight.common.bridge.core.world.level.levelgen; + +import net.minecraft.server.level.WorldGenRegion; +import net.minecraft.world.level.StructureFeatureManager; +import net.minecraft.world.level.biome.BiomeSource; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.levelgen.WorldgenRandom; + +import java.util.Random; + +public interface ChunkGeneratorBridge { + + void bridge$addDecorations(WorldGenRegion region, StructureFeatureManager structureManager, boolean vanilla); + + void bridge$buildBedrock(ChunkAccess chunkAccess, Random random); + + WorldgenRandom bridge$buildSurface(WorldGenRegion region, ChunkAccess chunkAccess); + + void bridge$setBiomeSource(BiomeSource biomeSource); +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/CraftRegionAccessorMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/CraftRegionAccessorMixin.java new file mode 100644 index 00000000..b7491962 --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/CraftRegionAccessorMixin.java @@ -0,0 +1,40 @@ +package io.izzel.arclight.common.mixin.bukkit; + +import io.izzel.arclight.common.bridge.bukkit.EntityTypeBridge; +import org.bukkit.Location; +import org.bukkit.craftbukkit.v.CraftRegionAccessor; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.util.Consumer; +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.CallbackInfoReturnable; + +import java.util.function.Function; + +@Mixin(value = CraftRegionAccessor.class, remap = false) +public abstract class CraftRegionAccessorMixin { + + // @formatter:off + @Shadow public abstract T addEntity(net.minecraft.world.entity.Entity entity, CreatureSpawnEvent.SpawnReason reason, Consumer function, boolean randomizeData) throws IllegalArgumentException; + // @formatter:on + + @Inject(method = "spawnEntity(Lorg/bukkit/Location;Lorg/bukkit/entity/EntityType;)Lorg/bukkit/entity/Entity;", cancellable = true, at = @At("HEAD")) + private void arclight$useFactory(Location loc, EntityType entityType, CallbackInfoReturnable cir) { + Function factory = ((EntityTypeBridge) (Object) entityType).bridge$entityFactory(); + if (factory != null) { + cir.setReturnValue(this.addEntity(factory.apply(loc), CreatureSpawnEvent.SpawnReason.CUSTOM, null, true)); + } + } + + @Inject(method = "spawnEntity(Lorg/bukkit/Location;Lorg/bukkit/entity/EntityType;Z)Lorg/bukkit/entity/Entity;", cancellable = true, at = @At("HEAD")) + private void arclight$useFactory(Location loc, EntityType entityType, boolean randomizeData, CallbackInfoReturnable cir) { + Function factory = ((EntityTypeBridge) (Object) entityType).bridge$entityFactory(); + if (factory != null) { + cir.setReturnValue(this.addEntity(factory.apply(loc), CreatureSpawnEvent.SpawnReason.CUSTOM, null, randomizeData)); + } + } +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/CraftWorldMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/CraftWorldMixin.java index 755c15b7..efa635d6 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/CraftWorldMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/bukkit/CraftWorldMixin.java @@ -1,40 +1,22 @@ package io.izzel.arclight.common.mixin.bukkit; -import io.izzel.arclight.common.bridge.bukkit.EntityTypeBridge; import io.izzel.arclight.common.bridge.core.world.server.ServerWorldBridge; -import org.bukkit.Location; +import net.minecraft.server.level.ServerLevel; import org.bukkit.craftbukkit.v.CraftWorld; -import org.bukkit.entity.Entity; -import org.bukkit.entity.EntityType; -import org.bukkit.event.entity.CreatureSpawnEvent; 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.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.io.File; -import java.util.function.Function; -import net.minecraft.server.level.ServerLevel; @Mixin(value = CraftWorld.class, remap = false) public abstract class CraftWorldMixin { // @formatter:off @Shadow @Final private ServerLevel world; - @Shadow public abstract T addEntity(net.minecraft.world.entity.Entity entity, CreatureSpawnEvent.SpawnReason reason) throws IllegalArgumentException; // @formatter:on - @Inject(method = "spawnEntity", cancellable = true, at = @At("HEAD")) - private void arclight$useFactory(Location loc, EntityType entityType, CallbackInfoReturnable cir) { - Function factory = ((EntityTypeBridge) (Object) entityType).bridge$entityFactory(); - if (factory != null) { - cir.setReturnValue(this.addEntity(factory.apply(loc), CreatureSpawnEvent.SpawnReason.CUSTOM)); - } - } - /** * @author IzzelAliz * @reason 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 4b9d19d2..a8594c47 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 @@ -108,10 +108,11 @@ public abstract class ServerLevelMixin extends LevelMixin implements ServerWorld throw new RuntimeException(); } - public void arclight$constructor(MinecraftServer server, Executor backgroundExecutor, LevelStorageSource.LevelStorageAccess levelSave, ServerLevelData serverWorldInfo, ResourceKey dimension, DimensionType dimensionType, ChunkProgressListener statusListener, ChunkGenerator chunkGenerator, boolean isDebug, long seed, List specialSpawners, boolean shouldBeTicking, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) { + public void arclight$constructor(MinecraftServer server, Executor backgroundExecutor, LevelStorageSource.LevelStorageAccess levelSave, ServerLevelData serverWorldInfo, ResourceKey dimension, DimensionType 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); this.generator = gen; this.environment = env; + this.biomeProvider = biomeProvider; if (gen != null) { CustomChunkGenerator generator = new CustomChunkGenerator((ServerLevel) (Object) this, this.chunkSource.getGenerator(), gen); ((ServerChunkProviderBridge) this.chunkSource).bridge$setChunkGenerator(generator); 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 907b37f7..90faac91 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 @@ -295,20 +295,20 @@ public abstract class ExplosionMixin implements ExplosionBridge { boolean cancelled; List bukkitBlocks; - float yield; + float bukkitYield; if (exploder != null) { EntityExplodeEvent event = new EntityExplodeEvent(exploder, location, blockList, this.blockInteraction == Explosion.BlockInteraction.DESTROY ? 1.0F / this.radius : 1.0F); Bukkit.getPluginManager().callEvent(event); cancelled = event.isCancelled(); bukkitBlocks = event.blockList(); - yield = event.getYield(); + bukkitYield = event.getYield(); } else { BlockExplodeEvent event = new BlockExplodeEvent(location.getBlock(), blockList, this.blockInteraction == Explosion.BlockInteraction.DESTROY ? 1.0F / this.radius : 1.0F); Bukkit.getPluginManager().callEvent(event); cancelled = event.isCancelled(); bukkitBlocks = event.blockList(); - yield = event.getYield(); + bukkitYield = event.getYield(); } this.toBlow.clear(); @@ -317,6 +317,6 @@ public abstract class ExplosionMixin implements ExplosionBridge { BlockPos blockPos = new BlockPos(block.getX(), block.getY(), block.getZ()); this.toBlow.add(blockPos); } - return cancelled ? Float.NaN : yield; + return cancelled ? Float.NaN : bukkitYield; } } 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 1916c4e0..8c1fda0e 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 @@ -212,6 +212,7 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge, private static final int CURRENT_LEVEL = 2; public boolean persist = true; + public boolean generation; public boolean valid; public org.bukkit.projectiles.ProjectileSource projectileSource; // For projectiles only public boolean forceExplosionKnockback; // SPIGOT-949 @@ -714,7 +715,7 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge, @Inject(method = "setSwimming", cancellable = true, at = @At(value = "HEAD")) public void arclight$setSwimming$EntityToggleSwimEvent(boolean flag, CallbackInfo ci) { // CraftBukkit start - if (this.isSwimming() != flag && (Object) this instanceof LivingEntity) { + if (this.isValid() && this.isSwimming() != flag && (Object) this instanceof LivingEntity) { if (CraftEventFactory.callToggleSwimEvent((LivingEntity) (Object) this, flag).isCancelled()) { ci.cancel(); } 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 99540ad4..72b8cf36 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 @@ -180,6 +180,7 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt @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(); // @formatter:on public int expToDrop; diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/animal/MushroomCowMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/animal/MushroomCowMixin.java index 8c451751..02eb2b01 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/animal/MushroomCowMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/animal/MushroomCowMixin.java @@ -1,14 +1,20 @@ package io.izzel.arclight.common.mixin.core.world.entity.animal; +import io.izzel.arclight.common.bridge.core.entity.EntityBridge; import io.izzel.arclight.common.bridge.core.world.WorldBridge; import net.minecraft.sounds.SoundSource; import net.minecraft.world.entity.animal.Cow; import net.minecraft.world.entity.animal.MushroomCow; +import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.item.ItemStack; +import org.bukkit.Bukkit; import org.bukkit.craftbukkit.v.event.CraftEventFactory; import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.event.entity.EntityDropItemEvent; import org.bukkit.event.entity.EntityTransformEvent; 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.Redirect; @@ -21,6 +27,10 @@ import java.util.List; @Mixin(MushroomCow.class) public abstract class MushroomCowMixin extends AnimalMixin { + // @formatter:off + @Shadow protected abstract List shearInternal(SoundSource pCategory); + // @formatter:on + @Redirect(method = "shearInternal", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/animal/MushroomCow;discard()V")) private void arclight$animalTransformPre(MushroomCow mushroomCow) { } @@ -34,4 +44,21 @@ public abstract class MushroomCowMixin extends AnimalMixin { this.discard(); } } + + /** + * @author IzzelAliz + * @reason + */ + @Overwrite + public void shear(SoundSource pCategory) { + for (ItemStack s : shearInternal(pCategory)) { + var itemEntity = new ItemEntity(this.level, this.getX(), this.getY(1.0D), this.getZ(), s); + EntityDropItemEvent event = new EntityDropItemEvent(this.getBukkitEntity(), (org.bukkit.entity.Item) ((EntityBridge) itemEntity).bridge$getBukkitEntity()); + Bukkit.getPluginManager().callEvent(event); + if (event.isCancelled()) { + continue; + } + this.level.addFreshEntity(itemEntity); + } + } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/animal/SnowGolemMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/animal/SnowGolemMixin.java index 4e1ae190..fb70b68f 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/animal/SnowGolemMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/animal/SnowGolemMixin.java @@ -1,8 +1,10 @@ package io.izzel.arclight.common.mixin.core.world.entity.animal; +import net.minecraft.sounds.SoundSource; 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 io.izzel.arclight.common.mixin.core.world.entity.PathfinderMobMixin; import net.minecraft.core.BlockPos; @@ -10,6 +12,7 @@ import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.entity.animal.SnowGolem; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.state.BlockState; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(SnowGolem.class) public abstract class SnowGolemMixin extends PathfinderMobMixin { @@ -23,4 +26,14 @@ public abstract class SnowGolemMixin extends PathfinderMobMixin { private boolean arclight$blockForm(Level world, BlockPos pos, BlockState state) { return CraftEventFactory.handleBlockFormEvent(world, pos, state, (SnowGolem) (Object) this); } + + @Inject(method = "shear", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/animal/SnowGolem;spawnAtLocation(Lnet/minecraft/world/item/ItemStack;F)Lnet/minecraft/world/entity/item/ItemEntity;")) + private void arclight$forceDropOn(SoundSource pCategory, CallbackInfo ci) { + this.forceDrops = true; + } + + @Inject(method = "shear", at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/world/entity/animal/SnowGolem;spawnAtLocation(Lnet/minecraft/world/item/ItemStack;F)Lnet/minecraft/world/entity/item/ItemEntity;")) + private void arclight$forceDropOff(SoundSource pCategory, CallbackInfo ci) { + this.forceDrops = false; + } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/monster/SlimeMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/monster/SlimeMixin.java index d73c41f4..a94160eb 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/monster/SlimeMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/entity/monster/SlimeMixin.java @@ -67,6 +67,7 @@ public abstract class SlimeMixin extends MobMixin { slimes.add(slimeentity); } if (CraftEventFactory.callEntityTransformEvent((net.minecraft.world.entity.monster.Slime) (Object) this, slimes, EntityTransformEvent.TransformReason.SPLIT).isCancelled()) { + super.remove(p_149847_); return; } for (LivingEntity living : slimes) { 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 8d3943fe..855d7e6a 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 @@ -335,6 +335,7 @@ public abstract class ServerPlayerMixin extends PlayerMixin implements ServerPla loot.add(craftItemStack); } } + this.keepLevel = keepInventory; if (!keepInventory) { this.getInventory().replaceWith(copyInv); } @@ -672,6 +673,10 @@ public abstract class ServerPlayerMixin extends PlayerMixin implements ServerPla return this.containerCounter; } + @Redirect(method = "openMenu", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerPlayer;closeContainer()V")) + private void arclight$skipSwitch(ServerPlayer serverPlayer) { + } + @Inject(method = "openMenu", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/world/MenuProvider;createMenu(ILnet/minecraft/world/entity/player/Inventory;Lnet/minecraft/world/entity/player/Player;)Lnet/minecraft/world/inventory/AbstractContainerMenu;")) private void arclight$invOpen(MenuProvider itileinventory, CallbackInfoReturnable cir, AbstractContainerMenu container) { if (container != null) { @@ -905,13 +910,13 @@ public abstract class ServerPlayerMixin extends PlayerMixin implements ServerPla public void reset() { float exp = 0.0f; - boolean keepInventory = this.level.getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY); - if (this.keepLevel || keepInventory) { + if (this.keepLevel) { exp = this.experienceProgress; this.newTotalExp = this.totalExperience; this.newLevel = this.experienceLevel; } this.setHealth(this.getMaxHealth()); + this.stopUsingItem(); this.remainingFireTicks = 0; this.fallDistance = 0.0f; this.foodData = new FoodData(); @@ -928,7 +933,7 @@ public abstract class ServerPlayerMixin extends PlayerMixin implements ServerPla this.lastHurtByMob = null; this.combatTracker = new CombatTracker((ServerPlayer) (Object) this); this.lastSentExp = -1; - if (this.keepLevel || keepInventory) { + if (this.keepLevel) { this.experienceProgress = exp; } else { this.giveExperiencePoints(this.newExp); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/HangingEntityItemMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/HangingEntityItemMixin.java index 67fc03ed..99c89d3f 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/HangingEntityItemMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/item/HangingEntityItemMixin.java @@ -14,6 +14,7 @@ import org.bukkit.Bukkit; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.craftbukkit.v.block.CraftBlock; +import org.bukkit.craftbukkit.v.inventory.CraftItemStack; import org.bukkit.entity.Hanging; import org.bukkit.entity.Player; import org.bukkit.event.hanging.HangingPlaceEvent; @@ -33,7 +34,7 @@ public class HangingEntityItemMixin { Block blockClicked = CraftBlock.at(world, blockPos); BlockFace blockFace = CraftBlock.notchToBlockFace(direction); - HangingPlaceEvent event = new HangingPlaceEvent((Hanging) ((EntityBridge) hangingEntity).bridge$getBukkitEntity(), who, blockClicked, blockFace); + HangingPlaceEvent event = new HangingPlaceEvent((Hanging) ((EntityBridge) hangingEntity).bridge$getBukkitEntity(), who, blockClicked, blockFace, CraftItemStack.asBukkitCopy(itemStack)); Bukkit.getPluginManager().callEvent(event); if (event.isCancelled()) { 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 7ff7931a..6367f37d 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 @@ -3,7 +3,9 @@ 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; import io.izzel.arclight.common.bridge.core.world.server.ServerChunkProviderBridge; +import io.izzel.arclight.common.bridge.core.world.server.ServerWorldBridge; import io.izzel.arclight.common.mod.ArclightMod; import io.izzel.arclight.common.mod.server.ArclightServer; import io.izzel.arclight.common.mod.server.world.WrappedWorlds; @@ -18,6 +20,7 @@ import net.minecraft.world.entity.Entity; 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; @@ -35,7 +38,9 @@ import org.bukkit.craftbukkit.v.CraftWorld; import org.bukkit.craftbukkit.v.block.CraftBlock; import org.bukkit.craftbukkit.v.block.data.CraftBlockData; 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.event.block.BlockPhysicsEvent; import org.bukkit.event.entity.CreatureSpawnEvent; @@ -85,6 +90,7 @@ public abstract class LevelMixin implements WorldBridge, LevelWriter { public boolean populating; public org.bukkit.generator.ChunkGenerator generator; protected org.bukkit.World.Environment environment; + protected org.bukkit.generator.BiomeProvider biomeProvider; public org.spigotmc.SpigotWorldConfig spigotConfig; @SuppressWarnings("unused") // Access transformed to public by ArclightMixinPlugin private static BlockPos lastPhysicsProblem; // Spigot @@ -94,10 +100,11 @@ public abstract class LevelMixin implements WorldBridge, LevelWriter { throw new RuntimeException(); } - public void arclight$constructor(WritableLevelData worldInfo, ResourceKey dimension, final DimensionType dimensionType, Supplier profiler, boolean isRemote, boolean isDebug, long seed, org.bukkit.generator.ChunkGenerator gen, org.bukkit.World.Environment env) { + public void arclight$constructor(WritableLevelData worldInfo, ResourceKey dimension, final DimensionType 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); this.generator = gen; this.environment = env; + this.biomeProvider = biomeProvider; bridge$getWorld(); } @@ -219,7 +226,7 @@ public abstract class LevelMixin implements WorldBridge, LevelWriter { @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); + 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(); @@ -240,17 +247,27 @@ public abstract class LevelMixin implements WorldBridge, LevelWriter { throw new RuntimeException(e); } } - if (generator == null) { - generator = getCraftServer().getGenerator(((ServerLevelData) this.getLevelData()).getLevelName()); - if (generator != null && (Object) this instanceof ServerLevel serverWorld) { - CustomChunkGenerator gen = new CustomChunkGenerator(serverWorld, serverWorld.getChunkSource().getGenerator(), generator); - ((ServerChunkProviderBridge) serverWorld.getChunkSource()).bridge$setChunkGenerator(gen); - } - } if (environment == null) { environment = ArclightServer.getEnvironment(this.typeKey); } - this.world = new CraftWorld((ServerLevel) (Object) this, generator, environment); + if (generator == null) { + 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); + if (biomeProvider == null && generator != null) { + biomeProvider = generator.getDefaultBiomeProvider(worldInfo); + } + var generator = serverWorld.getChunkSource().getGenerator(); + if (biomeProvider != null) { + BiomeSource biomeSource = new CustomWorldChunkManager(worldInfo, biomeProvider, serverWorld.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY)); + ((ChunkGeneratorBridge) generator).bridge$setBiomeSource(biomeSource); + } + CustomChunkGenerator gen = new CustomChunkGenerator(serverWorld, generator, this.generator); + ((ServerChunkProviderBridge) serverWorld.getChunkSource()).bridge$setChunkGenerator(gen); + } + } + this.world = new CraftWorld((ServerLevel) (Object) this, generator, biomeProvider, environment); getCraftServer().addWorld(this.world); } return this.world; 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/levelgen/ChunkGeneratorMixin.java new file mode 100644 index 00000000..44def114 --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/levelgen/ChunkGeneratorMixin.java @@ -0,0 +1,77 @@ +package io.izzel.arclight.common.mixin.core.world.level.levelgen; + +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.server.level.WorldGenRegion; +import net.minecraft.world.level.StructureFeatureManager; +import net.minecraft.world.level.biome.BiomeSource; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.ChunkGenerator; +import net.minecraft.world.level.levelgen.WorldgenRandom; +import org.bukkit.craftbukkit.v.generator.CraftLimitedRegion; +import org.bukkit.generator.BlockPopulator; +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 java.util.Random; + +@Mixin(ChunkGenerator.class) +public abstract class ChunkGeneratorMixin implements ChunkGeneratorBridge { + + // @formatter:off + @Shadow public abstract void applyBiomeDecoration(WorldGenRegion p_62168_, StructureFeatureManager p_62169_); + @Shadow @Final @Mutable protected BiomeSource biomeSource; + @Shadow @Final @Mutable protected BiomeSource runtimeBiomeSource; + // @formatter:on + + public void addDecorations(WorldGenRegion region, StructureFeatureManager structureManager, boolean vanilla) { + if (vanilla) { + this.applyBiomeDecoration(region, 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().size() != 0) { + CraftLimitedRegion limitedRegion = new CraftLimitedRegion(region); + int x = region.getCenter().x; + int z = region.getCenter().z; + for (BlockPopulator populator : world.getPopulators()) { + WorldgenRandom random = new WorldgenRandom(); + random.setDecorationSeed(region.getSeed(), x, z); + populator.populate(world, random, x, z, limitedRegion); + } + limitedRegion.saveEntities(); + limitedRegion.breakLink(); + } + } + + public void buildBedrock(ChunkAccess chunkAccess, Random random) { + throw new UnsupportedOperationException("Methode not overridden"); + } + + public WorldgenRandom buildSurface(WorldGenRegion region, ChunkAccess chunkAccess) { + throw new UnsupportedOperationException("Methode not overridden"); + } + + @Override + public void bridge$addDecorations(WorldGenRegion region, StructureFeatureManager structureManager, boolean vanilla) { + addDecorations(region, structureManager, vanilla); + } + + @Override + public void bridge$buildBedrock(ChunkAccess chunkAccess, Random random) { + buildBedrock(chunkAccess, random); + } + + @Override + public WorldgenRandom bridge$buildSurface(WorldGenRegion region, ChunkAccess chunkAccess) { + return buildSurface(region, chunkAccess); + } + + @Override + public void bridge$setBiomeSource(BiomeSource biomeSource) { + this.biomeSource = this.runtimeBiomeSource = biomeSource; + } +} diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/levelgen/NoiseBasedChunkGeneratorMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/levelgen/NoiseBasedChunkGeneratorMixin.java new file mode 100644 index 00000000..0f86c14d --- /dev/null +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/level/levelgen/NoiseBasedChunkGeneratorMixin.java @@ -0,0 +1,53 @@ +package io.izzel.arclight.common.mixin.core.world.level.levelgen; + +import net.minecraft.server.level.WorldGenRegion; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator; +import net.minecraft.world.level.levelgen.WorldgenRandom; +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; + +import java.util.Random; + +@Mixin(NoiseBasedChunkGenerator.class) +public abstract class NoiseBasedChunkGeneratorMixin extends ChunkGeneratorMixin { + + // @formatter:off + @Shadow public abstract void buildSurfaceAndBedrock(WorldGenRegion p_64381_, ChunkAccess p_64382_); + @Shadow protected abstract void setBedrock(ChunkAccess pChunk, Random pRandom); + // @formatter:on + + private transient boolean arclight$skipBedrock; + private transient WorldgenRandom arclight$random; + + @Inject(method = "buildSurfaceAndBedrock", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, + at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/levelgen/NoiseBasedChunkGenerator;setBedrock(Lnet/minecraft/world/level/chunk/ChunkAccess;Ljava/util/Random;)V")) + private void arclight$skipAndReturn(WorldGenRegion region, ChunkAccess chunkAccess, CallbackInfo ci, ChunkPos chunkPos, int i, int j, WorldgenRandom random) { + if (arclight$skipBedrock) { + arclight$random = random; + ci.cancel(); + } + } + + @Override + public WorldgenRandom buildSurface(WorldGenRegion region, ChunkAccess chunkAccess) { + try { + arclight$skipBedrock = true; + this.buildSurfaceAndBedrock(region, chunkAccess); + return arclight$random; + } finally { + arclight$random = null; + arclight$skipBedrock = false; + } + } + + @Override + public void buildBedrock(ChunkAccess chunkAccess, Random random) { + this.setBedrock(chunkAccess, random); + } +} diff --git a/arclight-common/src/main/resources/META-INF/accesstransformer.cfg b/arclight-common/src/main/resources/META-INF/accesstransformer.cfg index 9a4307ae..19942aad 100644 --- a/arclight-common/src/main/resources/META-INF/accesstransformer.cfg +++ b/arclight-common/src/main/resources/META-INF/accesstransformer.cfg @@ -6,6 +6,8 @@ public net.minecraft.world.entity.monster.SpellcasterIllager$IllagerSpell public-f net.minecraft.network.protocol.handshake.ClientIntentionPacket f_134721_ # hostName public net.minecraft.server.network.ServerGamePacketListenerImpl$EntityInteraction public net.minecraft.server.MinecraftServer$TimeProfiler +public net.minecraft.world.level.chunk.ChunkGenerator f_62140_ # strongholdSeed +public net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator f_64318_ # settings # Misc public net.minecraft.server.PlayerAdvancements f_135964_ public net.minecraft.server.level.PlayerRespawnLogic m_8264_(Lnet/minecraft/server/level/ServerLevel;IIZ)Lnet/minecraft/core/BlockPos; diff --git a/arclight-common/src/main/resources/mixins.arclight.bukkit.json b/arclight-common/src/main/resources/mixins.arclight.bukkit.json index f36d22d8..28801632 100644 --- a/arclight-common/src/main/resources/mixins.arclight.bukkit.json +++ b/arclight-common/src/main/resources/mixins.arclight.bukkit.json @@ -28,6 +28,7 @@ "CraftMagicNumbersMixin", "CraftMetaItemMixin", "CraftPlayerMixin", + "CraftRegionAccessorMixin", "CraftServerMixin", "CraftVillagerMixin", "CraftWorldMixin", diff --git a/arclight-common/src/main/resources/mixins.arclight.core.json b/arclight-common/src/main/resources/mixins.arclight.core.json index 78ec7e52..dd2bf6ef 100644 --- a/arclight-common/src/main/resources/mixins.arclight.core.json +++ b/arclight-common/src/main/resources/mixins.arclight.core.json @@ -425,6 +425,8 @@ "world.level.chunk.LevelChunkMixin", "world.level.chunk.storage.ChunkLoaderMixin", "world.level.chunk.storage.RegionFileCacheMixin", + "world.level.levelgen.ChunkGeneratorMixin", + "world.level.levelgen.NoiseBasedChunkGeneratorMixin", "world.level.portal.PortalForcerMixin", "world.level.saveddata.maps.MapData_MapInfoMixin", "world.level.saveddata.maps.MapDataMixin", diff --git a/arclight-common/src/main/resources/mixins.arclight.impl.forge.optimization.json b/arclight-common/src/main/resources/mixins.arclight.impl.forge.optimization.json index 840981bb..85f771d8 100644 --- a/arclight-common/src/main/resources/mixins.arclight.impl.forge.optimization.json +++ b/arclight-common/src/main/resources/mixins.arclight.impl.forge.optimization.json @@ -2,7 +2,7 @@ "minVersion": "0.8", "package": "io.izzel.arclight.common.mixin.optimization.general", "target": "@env(DEFAULT)", - "refmap": "mixins.arclight.impl.forge.refmap.json", + "refmap": "mixins.arclight.refmap.json", "compatibilityLevel": "JAVA_11", "mixins": [ "ClassInheritanceMultiMapMixin",