Update upstream (CraftBukkit)

This commit is contained in:
IzzelAliz 2021-10-22 15:13:43 +08:00
parent 7ab7ff6839
commit f434cd49d2
No known key found for this signature in database
GPG Key ID: EE50E123A11D8338
21 changed files with 156 additions and 51 deletions

View File

@ -39,5 +39,7 @@ public interface WorldBridge extends IWorldWriterBridge, IWorldBridge {
long bridge$ticksPerWaterAmbientSpawns(); long bridge$ticksPerWaterAmbientSpawns();
long bridge$ticksPerWaterUndergroundSpawns();
ResourceKey<DimensionType> bridge$getTypeKey(); ResourceKey<DimensionType> bridge$getTypeKey();
} }

View File

@ -1,26 +1,23 @@
package io.izzel.arclight.common.mixin.bukkit; package io.izzel.arclight.common.mixin.bukkit;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import io.izzel.arclight.common.bridge.core.block.FireBlockBridge;
import io.izzel.arclight.common.bridge.bukkit.MaterialBridge; import io.izzel.arclight.common.bridge.bukkit.MaterialBridge;
import io.izzel.arclight.common.bridge.core.block.FireBlockBridge;
import io.izzel.arclight.common.mod.ArclightMod; import io.izzel.arclight.common.mod.ArclightMod;
import io.izzel.arclight.common.mod.server.block.ArclightTileInventory;
import io.izzel.arclight.i18n.LocalizedException; import io.izzel.arclight.i18n.LocalizedException;
import io.izzel.arclight.i18n.conf.MaterialPropertySpec; import io.izzel.arclight.i18n.conf.MaterialPropertySpec;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.Container;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.FallingBlock; import net.minecraft.world.level.block.FallingBlock;
import net.minecraft.world.level.block.entity.BlockEntity;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.block.BlockState; import org.bukkit.block.BlockState;
import org.bukkit.craftbukkit.v.block.CraftBlock; import org.bukkit.craftbukkit.v.block.CraftBlock;
import org.bukkit.craftbukkit.v.block.CraftBlockEntityState;
import org.bukkit.craftbukkit.v.block.CraftBlockState; import org.bukkit.craftbukkit.v.block.CraftBlockState;
import org.bukkit.craftbukkit.v.block.CraftBlockStates;
import org.bukkit.craftbukkit.v.inventory.CraftMetaArmorStand; import org.bukkit.craftbukkit.v.inventory.CraftMetaArmorStand;
import org.bukkit.craftbukkit.v.inventory.CraftMetaBanner; import org.bukkit.craftbukkit.v.inventory.CraftMetaBanner;
import org.bukkit.craftbukkit.v.inventory.CraftMetaBlockState; import org.bukkit.craftbukkit.v.inventory.CraftMetaBlockState;
@ -357,7 +354,6 @@ public abstract class MaterialMixin implements MaterialBridge {
this.setupBlockStateFunc(); this.setupBlockStateFunc();
} }
@SuppressWarnings({"rawtypes", "unchecked"})
private void setupBlockStateFunc() { private void setupBlockStateFunc() {
if (arclight$spec.blockStateClass != null && !arclight$spec.blockStateClass.equalsIgnoreCase("auto")) { if (arclight$spec.blockStateClass != null && !arclight$spec.blockStateClass.equalsIgnoreCase("auto")) {
try { try {
@ -390,13 +386,7 @@ public abstract class MaterialMixin implements MaterialBridge {
} }
} }
if (this.arclight$stateFunc == null) { if (this.arclight$stateFunc == null) {
this.arclight$stateFunc = b -> { this.arclight$stateFunc = CraftBlockStates::getBlockState;
BlockEntity tileEntity = b.getCraftWorld().getHandle().getBlockEntity(b.getPosition());
if (tileEntity instanceof Container) {
return new ArclightTileInventory(b, tileEntity.getClass());
}
return tileEntity == null ? new CraftBlockState(b) : new CraftBlockEntityState<>(b, tileEntity.getClass());
};
} }
} }

View File

@ -297,6 +297,7 @@ public abstract class PlayerListMixin implements PlayerListBridge {
location = new Location(((WorldBridge) spawnWorld).bridge$getWorld(), vec3d.x, vec3d.y, vec3d.z); location = new Location(((WorldBridge) spawnWorld).bridge$getWorld(), vec3d.x, vec3d.y, vec3d.z);
} else if (pos != null) { } else if (pos != null) {
playerIn.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.NO_RESPAWN_BLOCK_AVAILABLE, 0.0f)); playerIn.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.NO_RESPAWN_BLOCK_AVAILABLE, 0.0f));
playerIn.setRespawnPosition(Level.OVERWORLD, null, 0f, false, false); // CraftBukkit - SPIGOT-5988: Clear respawn location when obstructed
} }
} }
if (location == null) { if (location == null) {
@ -413,6 +414,7 @@ public abstract class PlayerListMixin implements PlayerListBridge {
location = new Location(((WorldBridge) spawnWorld).bridge$getWorld(), vec3d.x, vec3d.y, vec3d.z); location = new Location(((WorldBridge) spawnWorld).bridge$getWorld(), vec3d.x, vec3d.y, vec3d.z);
} else if (pos != null) { } else if (pos != null) {
playerIn.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.NO_RESPAWN_BLOCK_AVAILABLE, 0.0f)); playerIn.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.NO_RESPAWN_BLOCK_AVAILABLE, 0.0f));
playerIn.setRespawnPosition(Level.OVERWORLD, null, 0f, false, false);
} }
} }
if (location == null) { if (location == null) {

View File

@ -88,6 +88,7 @@ public abstract class ExperienceOrbMixin extends EntityMixin {
itemstack.setDamageValue(itemstack.getDamageValue() - j); itemstack.setDamageValue(itemstack.getDamageValue() - j);
int k = i - this.durabilityToXp(j); int k = i - this.durabilityToXp(j);
this.value = k;
return k > 0 ? this.repairPlayerItems(player, k) : 0; return k > 0 ? this.repairPlayerItems(player, k) : 0;
} else { } else {

View File

@ -46,6 +46,7 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items; import net.minecraft.world.item.Items;
import net.minecraft.world.level.GameRules; import net.minecraft.world.level.GameRules;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.gameevent.GameEvent; import net.minecraft.world.level.gameevent.GameEvent;
import net.minecraftforge.common.ForgeHooks; import net.minecraftforge.common.ForgeHooks;
import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.MinecraftForge;
@ -910,7 +911,8 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
this.setHealth(1.0F); this.setHealth(1.0F);
this.removeAllEffects(EntityPotionEffectEvent.Cause.TOTEM); this.removeAllEffects(EntityPotionEffectEvent.Cause.TOTEM);
this.addEffect(new MobEffectInstance(MobEffects.REGENERATION, 900, 1), EntityPotionEffectEvent.Cause.TOTEM);bridge$pushEffectCause(EntityPotionEffectEvent.Cause.TOTEM); this.addEffect(new MobEffectInstance(MobEffects.REGENERATION, 900, 1), EntityPotionEffectEvent.Cause.TOTEM);
bridge$pushEffectCause(EntityPotionEffectEvent.Cause.TOTEM);
this.addEffect(new MobEffectInstance(MobEffects.ABSORPTION, 100, 1), EntityPotionEffectEvent.Cause.TOTEM); this.addEffect(new MobEffectInstance(MobEffects.ABSORPTION, 100, 1), EntityPotionEffectEvent.Cause.TOTEM);
this.addEffect(new MobEffectInstance(MobEffects.FIRE_RESISTANCE, 800, 1), EntityPotionEffectEvent.Cause.TOTEM); this.addEffect(new MobEffectInstance(MobEffects.FIRE_RESISTANCE, 800, 1), EntityPotionEffectEvent.Cause.TOTEM);
this.level.broadcastEntityEvent((Entity) (Object) this, (byte) 35); this.level.broadcastEntityEvent((Entity) (Object) this, (byte) 35);
@ -928,6 +930,11 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
} }
} }
@Redirect(method = "createWitherRose", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;setBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;I)Z"))
private boolean arclight$fireWitherRoseForm(Level instance, BlockPos pPos, BlockState pNewState, int pFlags) {
return CraftEventFactory.handleBlockFormEvent(instance, pPos, pNewState, 3, (Entity) (Object) this);
}
@Redirect(method = "getDamageAfterArmorAbsorb", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;hurtArmor(Lnet/minecraft/world/damagesource/DamageSource;F)V")) @Redirect(method = "getDamageAfterArmorAbsorb", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;hurtArmor(Lnet/minecraft/world/damagesource/DamageSource;F)V"))
public void arclight$muteDamageArmor(LivingEntity entity, DamageSource damageSource, float damage) { public void arclight$muteDamageArmor(LivingEntity entity, DamageSource damageSource, float damage) {
} }

View File

@ -594,7 +594,7 @@ public abstract class ServerPlayerMixin extends PlayerMixin implements ServerPla
private Either<Player.BedSleepingProblem, Unit> getBedResult(BlockPos blockposition, Direction enumdirection) { private Either<Player.BedSleepingProblem, Unit> getBedResult(BlockPos blockposition, Direction enumdirection) {
if (!this.isSleeping() && this.isAlive()) { if (!this.isSleeping() && this.isAlive()) {
if (!this.level.dimensionType().natural()) { if (!this.level.dimensionType().natural() || !this.level.dimensionType().bedWorks()) {
return Either.left(Player.BedSleepingProblem.NOT_POSSIBLE_HERE); return Either.left(Player.BedSleepingProblem.NOT_POSSIBLE_HERE);
} }
if (!this.bedInRange(blockposition, enumdirection)) { if (!this.bedInRange(blockposition, enumdirection)) {

View File

@ -9,7 +9,7 @@ import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
@Mixin(StructureFeatureManager.class) @Mixin(StructureFeatureManager.class)
public class StructureManagerMixin { public class StructureFeatureManagerMixin {
@Shadow @Final private LevelAccessor level; @Shadow @Final private LevelAccessor level;

View File

@ -214,6 +214,7 @@ public abstract class RepairContainerMixin extends ItemCombinerMixin {
// this.outputSlot.setInventorySlotContents(0, itemstack1); // this.outputSlot.setInventorySlotContents(0, itemstack1);
CraftEventFactory.callPrepareAnvilEvent(getBukkitView(), itemstack1); CraftEventFactory.callPrepareAnvilEvent(getBukkitView(), itemstack1);
this.sendAllDataToRemote();
this.broadcastChanges(); this.broadcastChanges();
} }
} }

View File

@ -15,7 +15,7 @@ import net.minecraft.world.level.block.state.properties.Property;
import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.CollisionContext;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v.block.CraftBlock; import org.bukkit.craftbukkit.v.block.CraftBlock;
import org.bukkit.craftbukkit.v.block.CraftBlockState; import org.bukkit.craftbukkit.v.block.CraftBlockStates;
import org.bukkit.craftbukkit.v.block.data.CraftBlockData; import org.bukkit.craftbukkit.v.block.data.CraftBlockData;
import org.bukkit.craftbukkit.v.event.CraftEventFactory; import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -42,7 +42,7 @@ public abstract class BlockItemMixin {
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;")) 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<InteractionResult> cir, BlockPlaceContext context1) { private void arclight$prePlaceLilypad(BlockPlaceContext context, CallbackInfoReturnable<InteractionResult> cir, BlockPlaceContext context1) {
if ((Object) this instanceof WaterLilyBlockItem) { if ((Object) this instanceof WaterLilyBlockItem) {
this.arclight$state = CraftBlockState.getBlockState(context1.getLevel(), context1.getClickedPos()); this.arclight$state = CraftBlockStates.getBlockState(context1.getLevel(), context1.getClickedPos());
} }
} }

View File

@ -86,6 +86,7 @@ public abstract class LevelMixin implements WorldBridge, LevelWriter {
public long ticksPerMonsterSpawns; public long ticksPerMonsterSpawns;
public long ticksPerWaterSpawns; public long ticksPerWaterSpawns;
public long ticksPerWaterAmbientSpawns; public long ticksPerWaterAmbientSpawns;
public long ticksPerWaterUndergroundCreatureSpawns;
public long ticksPerAmbientSpawns; public long ticksPerAmbientSpawns;
public boolean populating; public boolean populating;
public org.bukkit.generator.ChunkGenerator generator; public org.bukkit.generator.ChunkGenerator generator;
@ -116,6 +117,7 @@ public abstract class LevelMixin implements WorldBridge, LevelWriter {
this.ticksPerMonsterSpawns = this.getCraftServer().getTicksPerMonsterSpawns(); this.ticksPerMonsterSpawns = this.getCraftServer().getTicksPerMonsterSpawns();
this.ticksPerWaterSpawns = this.getCraftServer().getTicksPerWaterSpawns(); this.ticksPerWaterSpawns = this.getCraftServer().getTicksPerWaterSpawns();
this.ticksPerWaterAmbientSpawns = this.getCraftServer().getTicksPerWaterAmbientSpawns(); this.ticksPerWaterAmbientSpawns = this.getCraftServer().getTicksPerWaterAmbientSpawns();
this.ticksPerWaterUndergroundCreatureSpawns = this.getCraftServer().getTicksPerWaterUndergroundCreatureSpawns();
this.ticksPerAmbientSpawns = this.getCraftServer().getTicksPerAmbientSpawns(); this.ticksPerAmbientSpawns = this.getCraftServer().getTicksPerAmbientSpawns();
this.typeKey = this.getCraftServer().getHandle().getServer().registryAccess().registryOrThrow(Registry.DIMENSION_TYPE_REGISTRY) this.typeKey = this.getCraftServer().getHandle().getServer().registryAccess().registryOrThrow(Registry.DIMENSION_TYPE_REGISTRY)
.getResourceKey(dimensionType) .getResourceKey(dimensionType)
@ -152,6 +154,11 @@ public abstract class LevelMixin implements WorldBridge, LevelWriter {
return ticksPerWaterAmbientSpawns; return ticksPerWaterAmbientSpawns;
} }
@Override
public long bridge$ticksPerWaterUndergroundSpawns() {
return ticksPerWaterUndergroundCreatureSpawns;
}
public ResourceKey<DimensionType> getTypeKey() { public ResourceKey<DimensionType> getTypeKey() {
return this.typeKey; return this.typeKey;
} }

View File

@ -0,0 +1,29 @@
package io.izzel.arclight.common.mixin.core.world.level.block;
import net.minecraft.core.BlockPos;
import net.minecraft.world.MenuProvider;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.ChestBlock;
import net.minecraft.world.level.block.DoubleBlockCombiner;
import net.minecraft.world.level.block.entity.ChestBlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import javax.annotation.Nullable;
import java.util.Optional;
@Mixin(ChestBlock.class)
public abstract class ChestBlockMixin {
// @formatter:off
@Shadow public abstract DoubleBlockCombiner.NeighborCombineResult<? extends ChestBlockEntity> combine(BlockState pState, Level pLevel, BlockPos pPos, boolean pOverride);
@Shadow @Final private static DoubleBlockCombiner.Combiner<ChestBlockEntity, Optional<MenuProvider>> MENU_PROVIDER_COMBINER;
// @formatter:on
@Nullable
public MenuProvider getInventory(BlockState state, Level level, BlockPos pos, boolean ignoreObstructions) {
return this.combine(state, level, pos, ignoreObstructions).apply(MENU_PROVIDER_COMBINER).orElse(null);
}
}

View File

@ -9,6 +9,7 @@ import net.minecraft.world.level.block.ConcretePowderBlock;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v.block.CraftBlockState; import org.bukkit.craftbukkit.v.block.CraftBlockState;
import org.bukkit.craftbukkit.v.block.CraftBlockStates;
import org.bukkit.craftbukkit.v.event.CraftEventFactory; import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.bukkit.event.block.BlockFormEvent; import org.bukkit.event.block.BlockFormEvent;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
@ -34,7 +35,7 @@ public abstract class ConcretePowderBlockMixin extends FallingBlockMixin {
public BlockState arclight$blockForm(@Coerce ConcretePowderBlockMixin block, BlockPlaceContext context) { public BlockState arclight$blockForm(@Coerce ConcretePowderBlockMixin block, BlockPlaceContext context) {
Level world = context.getLevel(); Level world = context.getLevel();
BlockPos blockPos = context.getClickedPos(); BlockPos blockPos = context.getClickedPos();
CraftBlockState blockState = CraftBlockState.getBlockState(world, blockPos); CraftBlockState blockState = CraftBlockStates.getBlockState(world, blockPos);
blockState.setData(this.concrete); blockState.setData(this.concrete);
BlockFormEvent event = new BlockFormEvent(blockState.getBlock(), blockState); BlockFormEvent event = new BlockFormEvent(blockState.getBlock(), blockState);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
@ -49,7 +50,7 @@ public abstract class ConcretePowderBlockMixin extends FallingBlockMixin {
if (!(worldIn instanceof Level)) { if (!(worldIn instanceof Level)) {
return this.concrete; return this.concrete;
} }
CraftBlockState blockState = CraftBlockState.getBlockState(worldIn, currentPos); CraftBlockState blockState = CraftBlockStates.getBlockState(worldIn, currentPos);
blockState.setData(this.concrete); blockState.setData(this.concrete);
BlockFormEvent event = new BlockFormEvent(blockState.getBlock(), blockState); BlockFormEvent event = new BlockFormEvent(blockState.getBlock(), blockState);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);

View File

@ -15,6 +15,7 @@ import org.bukkit.Bukkit;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v.block.CraftBlock; import org.bukkit.craftbukkit.v.block.CraftBlock;
import org.bukkit.craftbukkit.v.block.CraftBlockState; import org.bukkit.craftbukkit.v.block.CraftBlockState;
import org.bukkit.craftbukkit.v.block.CraftBlockStates;
import org.bukkit.craftbukkit.v.event.CraftEventFactory; import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.bukkit.event.block.BlockBurnEvent; import org.bukkit.event.block.BlockBurnEvent;
import org.bukkit.event.block.BlockFadeEvent; import org.bukkit.event.block.BlockFadeEvent;
@ -71,7 +72,7 @@ public abstract class FireBlockMixin implements FireBlockBridge {
if (!(worldIn instanceof Level)) { if (!(worldIn instanceof Level)) {
return Blocks.AIR.defaultBlockState(); return Blocks.AIR.defaultBlockState();
} }
CraftBlockState blockState = CraftBlockState.getBlockState(worldIn, currentPos); CraftBlockState blockState = CraftBlockStates.getBlockState(worldIn, currentPos);
blockState.setData(Blocks.AIR.defaultBlockState()); blockState.setData(Blocks.AIR.defaultBlockState());
BlockFadeEvent event = new BlockFadeEvent(blockState.getBlock(), blockState); BlockFadeEvent event = new BlockFadeEvent(blockState.getBlock(), blockState);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);

View File

@ -23,6 +23,7 @@ import org.bukkit.World;
import org.bukkit.block.BlockState; import org.bukkit.block.BlockState;
import org.bukkit.craftbukkit.v.block.CraftBlock; import org.bukkit.craftbukkit.v.block.CraftBlock;
import org.bukkit.craftbukkit.v.block.CraftBlockState; import org.bukkit.craftbukkit.v.block.CraftBlockState;
import org.bukkit.craftbukkit.v.block.CraftBlockStates;
import org.bukkit.craftbukkit.v.event.CraftPortalEvent; import org.bukkit.craftbukkit.v.event.CraftPortalEvent;
import org.bukkit.event.world.PortalCreateEvent; import org.bukkit.event.world.PortalCreateEvent;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
@ -67,7 +68,7 @@ public abstract class PortalSizeMixin implements PortalSizeBridge {
World world = ((WorldBridge) ((IWorldBridge) this.level).bridge$getMinecraftWorld()).bridge$getWorld(); World world = ((WorldBridge) ((IWorldBridge) this.level).bridge$getMinecraftWorld()).bridge$getWorld();
net.minecraft.world.level.block.state.BlockState blockState = Blocks.NETHER_PORTAL.defaultBlockState().setValue(NetherPortalBlock.AXIS, this.axis); net.minecraft.world.level.block.state.BlockState blockState = Blocks.NETHER_PORTAL.defaultBlockState().setValue(NetherPortalBlock.AXIS, this.axis);
BlockPos.betweenClosed(this.bottomLeft, this.bottomLeft.relative(Direction.UP, this.height - 1).relative(this.rightDir, this.width - 1)).forEach(pos -> { BlockPos.betweenClosed(this.bottomLeft, this.bottomLeft.relative(Direction.UP, this.height - 1).relative(this.rightDir, this.width - 1)).forEach(pos -> {
CraftBlockState state = CraftBlockState.getBlockState(((IWorldBridge) this.level).bridge$getMinecraftWorld(), pos, 18); CraftBlockState state = CraftBlockStates.getBlockState(((IWorldBridge) this.level).bridge$getMinecraftWorld(), pos, 18);
state.setData(blockState); state.setData(blockState);
this.blocks.add(state); this.blocks.add(state);
}); });

View File

@ -1,7 +1,6 @@
package io.izzel.arclight.common.mixin.core.world.level.block.entity; package io.izzel.arclight.common.mixin.core.world.level.block.entity;
import io.izzel.arclight.common.bridge.core.tileentity.TileEntityBridge; import io.izzel.arclight.common.bridge.core.tileentity.TileEntityBridge;
import io.izzel.arclight.common.bridge.core.world.WorldBridge;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
@ -57,10 +56,6 @@ public abstract class BlockEntityMixin implements TileEntityBridge {
public InventoryHolder getOwner() { public InventoryHolder getOwner() {
if (this.level == null) return null; if (this.level == null) return null;
org.bukkit.block.Block block = CraftBlock.at(this.level, this.worldPosition); org.bukkit.block.Block block = CraftBlock.at(this.level, this.worldPosition);
if (block == null) {
org.bukkit.Bukkit.getLogger().log(java.util.logging.Level.WARNING, "No block for owner at %s %d %d %d", new Object[]{((WorldBridge) level).bridge$getWorld(), worldPosition.getX(), worldPosition.getY(), worldPosition.getZ()});
return null;
}
org.bukkit.block.BlockState state = block.getState(); org.bukkit.block.BlockState state = block.getState();
if (state instanceof InventoryHolder) return (InventoryHolder) state; if (state instanceof InventoryHolder) return (InventoryHolder) state;
return null; return null;

View File

@ -0,0 +1,78 @@
package io.izzel.arclight.common.mixin.core.world.level.entity;
import com.google.common.collect.ImmutableList;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.chunk.storage.EntityStorage;
import net.minecraft.world.level.entity.ChunkEntities;
import net.minecraft.world.level.entity.EntityAccess;
import net.minecraft.world.level.entity.EntityPersistentStorage;
import net.minecraft.world.level.entity.EntitySection;
import net.minecraft.world.level.entity.EntitySectionStorage;
import net.minecraft.world.level.entity.PersistentEntitySectionManager;
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Coerce;
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 java.io.IOException;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Collectors;
@Mixin(PersistentEntitySectionManager.class)
public abstract class PersistentEntitySectionManagerMixin<T extends EntityAccess> {
// @formatter:off
@Shadow public abstract void close() throws IOException;
@Shadow @Final private EntityPersistentStorage<T> permanentStorage;
@Shadow @Final EntitySectionStorage<T> sectionStorage;
// @formatter:on
public void close(boolean save) throws IOException {
if (save) {
this.close();
} else {
this.permanentStorage.close();
}
}
public List<Entity> getEntities(ChunkPos chunkCoordIntPair) {
return sectionStorage.getExistingSectionsInChunk(chunkCoordIntPair.toLong())
.flatMap(EntitySection::getEntities).map(o -> (Entity) o).collect(Collectors.toList());
}
@Unique private boolean arclight$fireEvent = false;
@Inject(method = "storeChunkSections", locals = LocalCapture.CAPTURE_FAILHARD,
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/entity/EntityPersistentStorage;storeEntities(Lnet/minecraft/world/level/entity/ChunkEntities;)V"))
private void arclight$fireUnload(long pos, Consumer<T> consumer, CallbackInfoReturnable<Boolean> cir, @Coerce Object status, List<T> list) {
if (arclight$fireEvent) {
CraftEventFactory.callEntitiesUnloadEvent(((EntityStorage) permanentStorage).level, new ChunkPos(pos),
list.stream().map(entity -> (Entity) entity).collect(Collectors.toList()));
}
}
@Inject(method = "storeChunkSections", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/entity/EntityPersistentStorage;storeEntities(Lnet/minecraft/world/level/entity/ChunkEntities;)V"))
private void arclight$resetFlag(long pos, Consumer<T> consumer, CallbackInfoReturnable<Boolean> cir) {
arclight$fireEvent = false;
}
@Inject(method = "processChunkUnload", at = @At("HEAD"))
private void arclight$fireEvent(long pChunkPosValue, CallbackInfoReturnable<Boolean> cir) {
arclight$fireEvent = true;
}
@Inject(method = "processPendingLoads", locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", shift = At.Shift.AFTER, remap = false, target = "Lit/unimi/dsi/fastutil/longs/Long2ObjectMap;put(JLjava/lang/Object;)Ljava/lang/Object;"))
private void arclight$fireLoad(CallbackInfo ci, ChunkEntities<T> chunkEntities) {
List<Entity> entities = getEntities(chunkEntities.getPos());
CraftEventFactory.callEntitiesLoadEvent(((EntityStorage) permanentStorage).level, chunkEntities.getPos(), entities);
}
}

View File

@ -58,6 +58,7 @@ public abstract class WorldEntitySpawnerMixin {
boolean spawnWaterThisTick = ((WorldBridge) world).bridge$ticksPerWaterSpawns() != 0L && worldInfo.getGameTime() % ((WorldBridge) world).bridge$ticksPerWaterSpawns() == 0L; boolean spawnWaterThisTick = ((WorldBridge) world).bridge$ticksPerWaterSpawns() != 0L && worldInfo.getGameTime() % ((WorldBridge) world).bridge$ticksPerWaterSpawns() == 0L;
boolean spawnAmbientThisTick = ((WorldBridge) world).bridge$ticksPerAmbientSpawns() != 0L && worldInfo.getGameTime() % ((WorldBridge) world).bridge$ticksPerAmbientSpawns() == 0L; boolean spawnAmbientThisTick = ((WorldBridge) world).bridge$ticksPerAmbientSpawns() != 0L && worldInfo.getGameTime() % ((WorldBridge) world).bridge$ticksPerAmbientSpawns() == 0L;
boolean spawnWaterAmbientThisTick = ((WorldBridge) world).bridge$ticksPerWaterAmbientSpawns() != 0L && worldInfo.getGameTime() % ((WorldBridge) world).bridge$ticksPerWaterAmbientSpawns() == 0L; boolean spawnWaterAmbientThisTick = ((WorldBridge) world).bridge$ticksPerWaterAmbientSpawns() != 0L && worldInfo.getGameTime() % ((WorldBridge) world).bridge$ticksPerWaterAmbientSpawns() == 0L;
boolean spawnWaterUndergroundThisTick = ((WorldBridge) world).bridge$ticksPerWaterUndergroundSpawns() != 0L && worldInfo.getGameTime() % ((WorldBridge) world).bridge$ticksPerWaterUndergroundSpawns() == 0L;
for (MobCategory classification : classifications) { for (MobCategory classification : classifications) {
boolean spawnThisTick = true; boolean spawnThisTick = true;
int limit = classification.getMaxInstancesPerChunk(); int limit = classification.getMaxInstancesPerChunk();
@ -70,6 +71,10 @@ public abstract class WorldEntitySpawnerMixin {
spawnThisTick = spawnAnimalThisTick; spawnThisTick = spawnAnimalThisTick;
limit = ((WorldBridge) world).bridge$getWorld().getAnimalSpawnLimit(); limit = ((WorldBridge) world).bridge$getWorld().getAnimalSpawnLimit();
} }
case UNDERGROUND_WATER_CREATURE -> {
spawnThisTick = spawnWaterUndergroundThisTick;
limit = ((WorldBridge) world).bridge$getWorld().getWaterUndergroundCreatureSpawnLimit();
}
case WATER_CREATURE -> { case WATER_CREATURE -> {
spawnThisTick = spawnWaterThisTick; spawnThisTick = spawnWaterThisTick;
limit = ((WorldBridge) world).bridge$getWorld().getWaterAnimalSpawnLimit(); limit = ((WorldBridge) world).bridge$getWorld().getWaterAnimalSpawnLimit();

View File

@ -1,22 +0,0 @@
package io.izzel.arclight.common.mod.server.block;
import net.minecraft.world.Container;
import net.minecraft.world.level.block.entity.BlockEntity;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v.block.CraftBlockEntityState;
import org.bukkit.craftbukkit.v.inventory.CraftInventory;
import org.bukkit.inventory.BlockInventoryHolder;
import org.bukkit.inventory.Inventory;
import org.jetbrains.annotations.NotNull;
public class ArclightTileInventory<T extends BlockEntity & Container> extends CraftBlockEntityState<T> implements BlockInventoryHolder {
public ArclightTileInventory(Block block, Class<T> tileEntityClass) {
super(block, tileEntityClass);
}
@Override
public @NotNull Inventory getInventory() {
return new CraftInventory(this.getTileEntity());
}
}

View File

@ -8,6 +8,7 @@ import net.minecraft.world.level.block.state.BlockState;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v.block.CraftBlock; import org.bukkit.craftbukkit.v.block.CraftBlock;
import org.bukkit.craftbukkit.v.block.CraftBlockState; import org.bukkit.craftbukkit.v.block.CraftBlockState;
import org.bukkit.craftbukkit.v.block.CraftBlockStates;
import org.bukkit.event.block.CauldronLevelChangeEvent; import org.bukkit.event.block.CauldronLevelChangeEvent;
public class CauldronHooks { public class CauldronHooks {
@ -40,7 +41,7 @@ public class CauldronHooks {
} }
public static boolean changeLevel(BlockState old, Level world, BlockPos pos, BlockState state, Entity entity, CauldronLevelChangeEvent.ChangeReason reason) { public static boolean changeLevel(BlockState old, Level world, BlockPos pos, BlockState state, Entity entity, CauldronLevelChangeEvent.ChangeReason reason) {
CraftBlockState newState = CraftBlockState.getBlockState(world, pos); CraftBlockState newState = CraftBlockStates.getBlockState(world, pos);
newState.setData(state); newState.setData(state);
CauldronLevelChangeEvent event = new CauldronLevelChangeEvent( CauldronLevelChangeEvent event = new CauldronLevelChangeEvent(
CraftBlock.at(world, pos), CraftBlock.at(world, pos),

View File

@ -9,6 +9,10 @@ public net.minecraft.server.MinecraftServer$TimeProfiler
public net.minecraft.world.level.chunk.ChunkGenerator f_62140_ # strongholdSeed public net.minecraft.world.level.chunk.ChunkGenerator f_62140_ # strongholdSeed
public net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator f_64318_ # settings public net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator f_64318_ # settings
public net.minecraft.world.entity.monster.piglin.PiglinAi m_149965_(Lnet/minecraft/world/item/ItemStack;)Z # isLovedItem public net.minecraft.world.entity.monster.piglin.PiglinAi m_149965_(Lnet/minecraft/world/item/ItemStack;)Z # isLovedItem
public net.minecraft.world.level.chunk.storage.EntityStorage f_156538_ # level
public net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate f_74482_ # palettes
public net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate f_74483_ # entityInfoList
public net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager f_74326_ # structureRepository
# Misc # Misc
public net.minecraft.server.PlayerAdvancements f_135964_ 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; public net.minecraft.server.level.PlayerRespawnLogic m_8264_(Lnet/minecraft/server/level/ServerLevel;IIZ)Lnet/minecraft/core/BlockPos;

View File

@ -227,7 +227,7 @@
"world.entity.vehicle.MinecartCommandBlock_MinecartCommandBaseMixin", "world.entity.vehicle.MinecartCommandBlock_MinecartCommandBaseMixin",
"world.food.FoodDataMixin", "world.food.FoodDataMixin",
"world.gen.WorldGenRegionMixin", "world.gen.WorldGenRegionMixin",
"world.gen.feature.structure.StructureManagerMixin", "world.gen.feature.structure.StructureFeatureManagerMixin",
"world.gen.feature.structure.SwampHutPieceMixin", "world.gen.feature.structure.SwampHutPieceMixin",
"world.gen.feature.template.TemplateManagerMixin", "world.gen.feature.template.TemplateManagerMixin",
"world.inventory.AbstractContainerMenuMixin", "world.inventory.AbstractContainerMenuMixin",
@ -326,6 +326,7 @@
"world.level.block.CauldronBlockMixin", "world.level.block.CauldronBlockMixin",
"world.level.block.CaveVinesMixin", "world.level.block.CaveVinesMixin",
"world.level.block.ChestBlock2Mixin", "world.level.block.ChestBlock2Mixin",
"world.level.block.ChestBlockMixin",
"world.level.block.ChorusFlowerBlockMixin", "world.level.block.ChorusFlowerBlockMixin",
"world.level.block.CocoaBlockMixin", "world.level.block.CocoaBlockMixin",
"world.level.block.CommandBlockMixin", "world.level.block.CommandBlockMixin",
@ -425,6 +426,7 @@
"world.level.chunk.LevelChunkMixin", "world.level.chunk.LevelChunkMixin",
"world.level.chunk.storage.ChunkLoaderMixin", "world.level.chunk.storage.ChunkLoaderMixin",
"world.level.chunk.storage.RegionFileCacheMixin", "world.level.chunk.storage.RegionFileCacheMixin",
"world.level.entity.PersistentEntitySectionManagerMixin",
"world.level.levelgen.ChunkGeneratorMixin", "world.level.levelgen.ChunkGeneratorMixin",
"world.level.levelgen.NoiseBasedChunkGeneratorMixin", "world.level.levelgen.NoiseBasedChunkGeneratorMixin",
"world.level.portal.PortalForcerMixin", "world.level.portal.PortalForcerMixin",