feat: 从PCA中迁移部分功能

This commit is contained in:
Disy authored and zly2006 committed 2024-07-11 12:14:01 +08:00
1 parent 9dc306f18a
commit f30e7425e6
39 files changed
+1354 -49

No files matched your search

@@ -1,4 +1,4 @@
package com.github.zly2006.carpetslsaddition.mixin;
package com.github.zly2006.carpetslsaddition.mixin.block;
import net.minecraft.block.*;
import net.minecraft.block.entity.BlockEntity;
@@ -1,4 +1,4 @@
package com.github.zly2006.carpetslsaddition.mixin;
package com.github.zly2006.carpetslsaddition.mixin.block;
import carpet.patches.EntityPlayerMPFake;
import com.github.zly2006.carpetslsaddition.PlayerAccess;
@@ -1,4 +1,4 @@
package com.github.zly2006.carpetslsaddition.mixin;
package com.github.zly2006.carpetslsaddition.mixin.carpet;
import carpet.patches.EntityPlayerMPFake;
import com.github.zly2006.carpetslsaddition.SLSCarpetSettings;
@@ -12,7 +12,7 @@ import org.spongepowered.asm.mixin.injection.Redirect;
import java.util.Optional;
import java.util.UUID;
@Mixin(value = EntityPlayerMPFake.class)
@Mixin(value = EntityPlayerMPFake.class, remap = false)
public class MixinFakePlayer {
@Redirect(method = "createFake", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/UserCache;findByName(Ljava/lang/String;)Ljava/util/Optional;"))
private static Optional<GameProfile> onCreate(UserCache instance, String name) {
@@ -1,12 +1,10 @@
package com.github.zly2006.carpetslsaddition.mixin;
package com.github.zly2006.carpetslsaddition.mixin.carpet;
import carpet.api.settings.SettingsManager;
import com.github.zly2006.carpetslsaddition.SettingsManagerAccessor;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import java.nio.file.Path;
@Mixin(value = SettingsManager.class, remap = false)
public abstract class MixinSettingsManager implements SettingsManagerAccessor {
@Shadow protected abstract void loadConfigurationFromConf();
@@ -0,0 +1,62 @@
package com.github.zly2006.carpetslsaddition.mixin.entity;
import com.github.zly2006.carpetslsaddition.util.SitEntity;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.decoration.ArmorStandEntity;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtElement;
import net.minecraft.world.World;
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(ArmorStandEntity.class)
public abstract class MixinArmorStandEntity extends LivingEntity implements SitEntity {
private boolean sitEntity = false; // 用于标识该盔甲架是否用于玩家乘坐
protected MixinArmorStandEntity(EntityType<? extends LivingEntity> entityType, World world) {
super(entityType, world);
}
@Shadow
protected abstract void setMarker(boolean marker);
@Override
public boolean isSitEntity() {
return sitEntity;
}
@Override
public void setSitEntity(boolean isSitEntity) {
this.sitEntity = isSitEntity;
this.setMarker(isSitEntity);
this.setInvisible(isSitEntity);
}
@Override
protected void removePassenger(Entity passenger) {
if (this.isSitEntity()) {
this.setPosition(this.getX(), this.getY() + 0.16, this.getZ());
this.kill();
}
super.removePassenger(passenger);
}
@Inject(method = "writeCustomDataToNbt", at = @At(value = "RETURN"))
private void postWriteCustomDataToNbt(NbtCompound nbt, CallbackInfo ci) {
if (this.sitEntity) {
nbt.putBoolean("SitEntity", true);
}
}
@Inject(method = "readCustomDataFromNbt", at = @At(value = "RETURN"))
private void postReadCustomDataFromNbt(NbtCompound nbt, CallbackInfo ci) {
if (nbt.contains("SitEntity", NbtElement.BYTE_TYPE)) {
this.sitEntity = nbt.getBoolean("SitEntity");
}
}
}
@@ -1,4 +1,4 @@
package com.github.zly2006.carpetslsaddition.mixin;
package com.github.zly2006.carpetslsaddition.mixin.entity;
import net.minecraft.entity.FallingBlockEntity;
import net.minecraft.entity.damage.DamageSource;
@@ -1,4 +1,4 @@
package com.github.zly2006.carpetslsaddition.mixin;
package com.github.zly2006.carpetslsaddition.mixin.entity;
import com.github.zly2006.carpetslsaddition.SLSCarpetSettings;
import net.minecraft.entity.ItemEntity;
@@ -1,4 +1,4 @@
package com.github.zly2006.carpetslsaddition.mixin;
package com.github.zly2006.carpetslsaddition.mixin.entity;
import com.github.zly2006.carpetslsaddition.PlayerAccess;
import net.minecraft.block.BlockState;
@@ -0,0 +1,66 @@
package com.github.zly2006.carpetslsaddition.mixin.entity;
import com.github.zly2006.carpetslsaddition.SLSCarpetSettings;
import com.github.zly2006.carpetslsaddition.util.SitEntity;
import com.mojang.authlib.GameProfile;
import net.minecraft.entity.decoration.ArmorStandEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.network.encryption.PlayerPublicKey;
import net.minecraft.network.packet.s2c.play.EntityTrackerUpdateS2CPacket;
import net.minecraft.server.network.ServerPlayNetworkHandler;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@Mixin(ServerPlayerEntity.class)
public abstract class MixinServerPlayerEntity extends PlayerEntity {
@Shadow
public ServerPlayNetworkHandler networkHandler;
private int sneakTimes = 0;
private long lastSneakTime = 0;
public MixinServerPlayerEntity(World world, BlockPos pos, float yaw, GameProfile gameProfile, @Nullable PlayerPublicKey publicKey) {
super(world, pos, yaw, gameProfile, publicKey);
}
@Override
public void setSneaking(boolean sneaking){
if (!SLSCarpetSettings.playerSit || (sneaking && this.isSneaking())) {
super.setSneaking(sneaking);
return;
}
if (sneaking) {
long nowTime = System.currentTimeMillis();
if (nowTime - lastSneakTime < 400 && sneakTimes == 0) {
return;
}
super.setSneaking(true);
if (this.isOnGround() && nowTime - lastSneakTime < 400) {
sneakTimes += 1;
if (sneakTimes == 3) {
ArmorStandEntity armorStandEntity = new ArmorStandEntity(world, this.getX(), this.getY() - 0.16, this.getZ());
((SitEntity) armorStandEntity).setSitEntity(true);
world.spawnEntity(armorStandEntity);
this.setSneaking(false);
this.startRiding(armorStandEntity);
sneakTimes = 0;
}
} else {
sneakTimes = 1;
}
lastSneakTime = nowTime;
} else {
super.setSneaking(false);
// 同步潜行状态到客户端
// 如果不同步的话客户端会认为仍在潜行,从而碰撞箱的高度会计算错误
if (sneakTimes == 0 && this.networkHandler != null) {
this.networkHandler.sendPacket(new EntityTrackerUpdateS2CPacket(this.getId(), this.getDataTracker(), true));
}
}
}
}
@@ -1,4 +1,4 @@
package com.github.zly2006.carpetslsaddition.mixin;
package com.github.zly2006.carpetslsaddition.mixin.entity;
import com.github.zly2006.carpetslsaddition.SLSCarpetSettings;
import net.minecraft.entity.EntityType;
@@ -37,7 +37,7 @@ public abstract class MixinVillagerEntity extends MerchantEntity {
tickCount--;
}
else {
tickCount = SLSCarpetSettings.skipTicksForJoblessVillager + 1;
tickCount = SLSCarpetSettings.skipTicksForJoblessVillager;
ci.cancel();
if (this.getHeadRollingTimeLeft() > 0) {
@@ -0,0 +1,55 @@
package com.github.zly2006.carpetslsaddition.mixin.item;
import com.github.zly2006.carpetslsaddition.SLSCarpetSettings;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.ShulkerBoxBlock;
import net.minecraft.block.entity.ShulkerBoxBlockEntity;
import net.minecraft.item.DyeItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemUsageContext;
import net.minecraft.util.ActionResult;
import net.minecraft.util.DyeColor;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@Mixin(DyeItem.class)
public abstract class MixinDyeItem extends Item {
public MixinDyeItem(Settings settings) {
super(settings);
}
@Shadow
public abstract DyeColor getColor();
@Override
public ActionResult useOnBlock(ItemUsageContext context) {
if (!SLSCarpetSettings.useDyeOnShulkerBox) {
return ActionResult.PASS;
}
World world = context.getWorld();
BlockPos pos = context.getBlockPos();
BlockState blockState = world.getBlockState(pos);
if (blockState.isOf(Blocks.SHULKER_BOX)) {
if (!world.isClient()) {
ShulkerBoxBlockEntity blockEntity = (ShulkerBoxBlockEntity) world.getBlockEntity(pos);
BlockState newBlockState = ShulkerBoxBlock.get(getColor()).getDefaultState().with(ShulkerBoxBlock.FACING, blockState.get(ShulkerBoxBlock.FACING));
if (world.setBlockState(pos, newBlockState)) {
ShulkerBoxBlockEntity newBlockEntity = (ShulkerBoxBlockEntity) world.getBlockEntity(pos);
assert blockEntity != null;
assert newBlockEntity != null;
newBlockEntity.readInventoryNbt(blockEntity.createNbt());
newBlockEntity.setCustomName(blockEntity.getCustomName());
newBlockEntity.markDirty();
context.getStack().decrement(1);
}
}
return ActionResult.success(world.isClient);
}
return ActionResult.PASS;
}
}
@@ -1,4 +1,4 @@
package com.github.zly2006.carpetslsaddition.mixin;
package com.github.zly2006.carpetslsaddition.mixin.item;
import com.github.zly2006.carpetslsaddition.PlayerAccess;
import net.minecraft.block.BlockState;
@@ -0,0 +1,68 @@
package com.github.zly2006.carpetslsaddition.mixin.item;
import com.github.zly2006.carpetslsaddition.SLSCarpetSettings;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.ShulkerBoxBlock;
import net.minecraft.block.entity.ShulkerBoxBlockEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.*;
import net.minecraft.potion.PotionUtil;
import net.minecraft.potion.Potions;
import net.minecraft.util.ActionResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
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.Objects;
@Mixin(PotionItem.class)
public abstract class MixinPotionItem extends Item {
public MixinPotionItem(Settings settings) {
super(settings);
}
@Inject(method = "useOnBlock", at = @At(value = "HEAD"), cancellable = true)
public void useOnBlock(ItemUsageContext context, CallbackInfoReturnable<ActionResult> cir) {
ItemStack itemStack = context.getStack();
PlayerEntity player = context.getPlayer();
if (!SLSCarpetSettings.useDyeOnShulkerBox ||
player == null ||
itemStack.getItem() != Items.POTION ||
PotionUtil.getPotion(itemStack) != Potions.WATER) {
return;
}
World world = context.getWorld();
BlockPos pos = context.getBlockPos();
BlockState blockState = world.getBlockState(pos);
Block block = blockState.getBlock();
if (block instanceof ShulkerBoxBlock && ((ShulkerBoxBlock) block).getColor() != null) {
if (!world.isClient()) {
ShulkerBoxBlockEntity blockEntity = (ShulkerBoxBlockEntity) world.getBlockEntity(pos);
BlockState newBlockState = Blocks.SHULKER_BOX.getDefaultState().
with(ShulkerBoxBlock.FACING, blockState.get(ShulkerBoxBlock.FACING));
if (world.setBlockState(pos, newBlockState)) {
ShulkerBoxBlockEntity newBlockEntity = (ShulkerBoxBlockEntity) world.getBlockEntity(pos);
assert blockEntity != null;
assert newBlockEntity != null;
newBlockEntity.readInventoryNbt(blockEntity.createNbt());
newBlockEntity.setCustomName(blockEntity.getCustomName());
newBlockEntity.markDirty();
if (!player.isCreative()) {
context.getStack().decrement(1);
Objects.requireNonNull(context.getPlayer()).getInventory().insertStack(new ItemStack(Items.GLASS_BOTTLE));
}
}
}
cir.setReturnValue(ActionResult.success(world.isClient));
}
}
}
@@ -1,4 +1,4 @@
package com.github.zly2006.carpetslsaddition.mixin;
package com.github.zly2006.carpetslsaddition.mixin.player;
import net.minecraft.entity.player.PlayerAbilities;
import org.spongepowered.asm.mixin.Mixin;
@@ -1,20 +1,19 @@
package com.github.zly2006.carpetslsaddition.mixin;
package com.github.zly2006.carpetslsaddition.mixin.player;
import com.github.zly2006.carpetslsaddition.SLSCarpetSettings;
import com.github.zly2006.carpetslsaddition.util.ShulkerBoxItemUtil;
import net.minecraft.entity.player.PlayerAbilities;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
import org.spongepowered.asm.mixin.Final;
import net.minecraft.util.Nameable;
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.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(PlayerInventory.class)
public class MixinPlayerInventory {
public abstract class MixinPlayerInventory implements Inventory, Nameable {
@Redirect(method = "insertStack(ILnet/minecraft/item/ItemStack;)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerEntity;getAbilities()Lnet/minecraft/entity/player/PlayerAbilities;"))
private PlayerAbilities insertStack(PlayerEntity instance) {
if (SLSCarpetSettings.creativeNoInfinitePickup) {
@@ -32,4 +31,27 @@ public class MixinPlayerInventory {
}
return instance.getAbilities();
}
// 修改潜影盒拾取逻辑,使从地上捡起潜影盒时仍可堆叠
@Redirect(method = "canStackAddMore",
at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;isStackable()Z", ordinal = 0))
private boolean canStackAddMoreIsStackable(ItemStack itemStack) {
return ShulkerBoxItemUtil.isStackable(itemStack);
}
@Redirect(method = "canStackAddMore", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;getMaxCount()I", ordinal = 0))
private int canStackAddMoreGetMaxCount(ItemStack itemStack) {
return ShulkerBoxItemUtil.getMaxCount(itemStack);
}
@Redirect(method = "addStack(ILnet/minecraft/item/ItemStack;)I", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;getMaxCount()I", ordinal = -1))
private int addStackGetMaxCount(ItemStack itemStack) {
return ShulkerBoxItemUtil.getMaxCount(itemStack);
}
// 避免死循环
@Redirect(method = "offer", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;getMaxCount()I", ordinal = 0))
private int offerGetMaxCount(ItemStack itemStack) {
return ShulkerBoxItemUtil.getMaxCount(itemStack);
}
}
@@ -0,0 +1,31 @@
package com.github.zly2006.carpetslsaddition.mixin.protocol.pcaSyncProtocol.block;
import com.github.zly2006.carpetslsaddition.SLSCarpetSettings;
import com.github.zly2006.carpetslsaddition.ServerMain;
import com.github.zly2006.carpetslsaddition.network.pca.PcaSyncProtocol;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.AbstractFurnaceBlockEntity;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.block.entity.LockableContainerBlockEntity;
import net.minecraft.inventory.SidedInventory;
import net.minecraft.recipe.RecipeInputProvider;
import net.minecraft.recipe.RecipeUnlocker;
import net.minecraft.util.math.BlockPos;
import org.spongepowered.asm.mixin.Mixin;
@Mixin(AbstractFurnaceBlockEntity.class)
public abstract class MixinAbstractFurnaceBlockEntity extends LockableContainerBlockEntity implements SidedInventory, RecipeUnlocker, RecipeInputProvider {
protected MixinAbstractFurnaceBlockEntity(BlockEntityType<?> blockEntityType, BlockPos blockPos, BlockState blockState) {
super(blockEntityType, blockPos, blockState);
}
@Override
public void markDirty() {
super.markDirty();
if (SLSCarpetSettings.pcaSyncProtocol && PcaSyncProtocol.syncBlockEntityToClient(this)) {
ServerMain.LOGGER.debug("update AbstractFurnaceBlockEntity: {}", this.pos);
}
}
}
@@ -0,0 +1,28 @@
package com.github.zly2006.carpetslsaddition.mixin.protocol.pcaSyncProtocol.block;
import com.github.zly2006.carpetslsaddition.SLSCarpetSettings;
import com.github.zly2006.carpetslsaddition.ServerMain;
import com.github.zly2006.carpetslsaddition.network.pca.PcaSyncProtocol;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BarrelBlockEntity;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.block.entity.LootableContainerBlockEntity;
import net.minecraft.util.math.BlockPos;
import org.spongepowered.asm.mixin.Mixin;
@Mixin(BarrelBlockEntity.class)
public abstract class MixinBarrelBlockEntity extends LootableContainerBlockEntity {
protected MixinBarrelBlockEntity(BlockEntityType<?> blockEntityType, BlockPos blockPos, BlockState blockState) {
super(blockEntityType, blockPos, blockState);
}
@Override
public void markDirty() {
super.markDirty();
if (SLSCarpetSettings.pcaSyncProtocol && PcaSyncProtocol.syncBlockEntityToClient(this)) {
ServerMain.LOGGER.debug("update BarrelBlockEntity: {}", this.pos);
}
}
}
@@ -0,0 +1,59 @@
package com.github.zly2006.carpetslsaddition.mixin.protocol.pcaSyncProtocol.block;
import com.github.zly2006.carpetslsaddition.SLSCarpetSettings;
import com.github.zly2006.carpetslsaddition.ServerMain;
import com.github.zly2006.carpetslsaddition.network.pca.PcaSyncProtocol;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BeehiveBlockEntity;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.entity.Entity;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
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.CallbackInfoReturnable;
import java.util.List;
import java.util.Objects;
@Mixin(BeehiveBlockEntity.class)
public abstract class MixinBeehiveBlockEntity extends BlockEntity {
public MixinBeehiveBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
}
@Inject(method = "tickBees", at = @At(value = "INVOKE", target = "Ljava/util/Iterator;remove()V", shift = At.Shift.AFTER))
private static void postTickBees(World world, BlockPos pos, BlockState state, List<BeehiveBlockEntity.Bee> bees, BlockPos flowerPos, CallbackInfo ci) {
if (SLSCarpetSettings.pcaSyncProtocol && PcaSyncProtocol.syncBlockEntityToClient(Objects.requireNonNull(world.getBlockEntity(pos)))) {
ServerMain.LOGGER.debug("update BeehiveBlockEntity: {}", pos);
}
}
@Inject(method = "tryReleaseBee", at = @At(value = "RETURN"))
public void postTryReleaseBee(BlockState state, BeehiveBlockEntity.BeeState beeState, CallbackInfoReturnable<List<Entity>> cir) {
if (SLSCarpetSettings.pcaSyncProtocol && PcaSyncProtocol.syncBlockEntityToClient(this) && cir.getReturnValue() != null) {
ServerMain.LOGGER.debug("update BeehiveBlockEntity: {}", this.pos);
}
}
@Inject(method = "readNbt", at = @At(value = "RETURN"))
public void postFromTag(NbtCompound nbt, CallbackInfo ci) {
if (SLSCarpetSettings.pcaSyncProtocol && PcaSyncProtocol.syncBlockEntityToClient(this)) {
ServerMain.LOGGER.debug("update BeehiveBlockEntity: {}", this.pos);
}
}
@Inject(method = "tryEnterHive(Lnet/minecraft/entity/Entity;ZI)V", at = @At(value = "INVOKE",
target = "Lnet/minecraft/entity/Entity;discard()V", ordinal = 0))
public void postEnterHive(Entity entity, boolean hasNectar, int ticksInHive, CallbackInfo ci) {
if (SLSCarpetSettings.pcaSyncProtocol && PcaSyncProtocol.syncBlockEntityToClient(this)) {
ServerMain.LOGGER.debug("update BeehiveBlockEntity: {}", this.pos);
}
}
}
@@ -0,0 +1,28 @@
package com.github.zly2006.carpetslsaddition.mixin.protocol.pcaSyncProtocol.block;
import com.github.zly2006.carpetslsaddition.SLSCarpetSettings;
import com.github.zly2006.carpetslsaddition.ServerMain;
import com.github.zly2006.carpetslsaddition.network.pca.PcaSyncProtocol;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.block.entity.BrewingStandBlockEntity;
import net.minecraft.block.entity.LockableContainerBlockEntity;
import net.minecraft.inventory.SidedInventory;
import net.minecraft.util.math.BlockPos;
import org.spongepowered.asm.mixin.Mixin;
@Mixin(BrewingStandBlockEntity.class)
public abstract class MixinBrewingStandBlockEntity extends LockableContainerBlockEntity implements SidedInventory {
protected MixinBrewingStandBlockEntity(BlockEntityType<?> blockEntityType, BlockPos blockPos, BlockState blockState) {
super(blockEntityType, blockPos, blockState);
}
@Override
public void markDirty() {
super.markDirty();
if (SLSCarpetSettings.pcaSyncProtocol && PcaSyncProtocol.syncBlockEntityToClient(this)) {
ServerMain.LOGGER.debug("update BrewingStandBlockEntity: {}", this.pos);
}
}
}
@@ -0,0 +1,30 @@
package com.github.zly2006.carpetslsaddition.mixin.protocol.pcaSyncProtocol.block;
import com.github.zly2006.carpetslsaddition.SLSCarpetSettings;
import com.github.zly2006.carpetslsaddition.ServerMain;
import com.github.zly2006.carpetslsaddition.network.pca.PcaSyncProtocol;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.block.entity.ChestBlockEntity;
import net.minecraft.block.entity.LidOpenable;
import net.minecraft.block.entity.LootableContainerBlockEntity;
import net.minecraft.util.math.BlockPos;
import org.spongepowered.asm.mixin.Mixin;
// 由于陷阱箱继承自箱子,因此不用 mixin 陷阱箱
// implements ChestAnimationProgress 会出错 不知道为啥
@Mixin(ChestBlockEntity.class)
public abstract class MixinChestBlockEntity extends LootableContainerBlockEntity implements LidOpenable {
protected MixinChestBlockEntity(BlockEntityType<?> blockEntityType, BlockPos blockPos, BlockState blockState) {
super(blockEntityType, blockPos, blockState);
}
@Override
public void markDirty() {
super.markDirty();
if (SLSCarpetSettings.pcaSyncProtocol && PcaSyncProtocol.syncBlockEntityToClient(this)) {
ServerMain.LOGGER.debug("update ChestBlockEntity: {}", this.pos);
}
}
}
@@ -0,0 +1,26 @@
package com.github.zly2006.carpetslsaddition.mixin.protocol.pcaSyncProtocol.block;
import com.github.zly2006.carpetslsaddition.SLSCarpetSettings;
import com.github.zly2006.carpetslsaddition.ServerMain;
import com.github.zly2006.carpetslsaddition.network.pca.PcaSyncProtocol;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.block.entity.ComparatorBlockEntity;
import net.minecraft.util.math.BlockPos;
import org.spongepowered.asm.mixin.Mixin;
@Mixin(ComparatorBlockEntity.class)
public abstract class MixinComparatorBlockEntity extends BlockEntity {
public MixinComparatorBlockEntity(BlockEntityType<?> blockEntityType, BlockPos blockPos, BlockState blockState) {
super(blockEntityType, blockPos, blockState);
}
@Override
public void markDirty() {
super.markDirty();
if (SLSCarpetSettings.pcaSyncProtocol && PcaSyncProtocol.syncBlockEntityToClient(this)) {
ServerMain.LOGGER.debug("update ComparatorBlockEntity: {}", this.pos);
}
}
}
@@ -0,0 +1,27 @@
package com.github.zly2006.carpetslsaddition.mixin.protocol.pcaSyncProtocol.block;
import com.github.zly2006.carpetslsaddition.SLSCarpetSettings;
import com.github.zly2006.carpetslsaddition.ServerMain;
import com.github.zly2006.carpetslsaddition.network.pca.PcaSyncProtocol;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.block.entity.DispenserBlockEntity;
import net.minecraft.block.entity.LootableContainerBlockEntity;
import net.minecraft.util.math.BlockPos;
import org.spongepowered.asm.mixin.Mixin;
@Mixin(DispenserBlockEntity.class)
public abstract class MixinDispenserBlockEntity extends LootableContainerBlockEntity {
protected MixinDispenserBlockEntity(BlockEntityType<?> blockEntityType, BlockPos blockPos, BlockState blockState) {
super(blockEntityType, blockPos, blockState);
}
@Override
public void markDirty() {
super.markDirty();
if (SLSCarpetSettings.pcaSyncProtocol && PcaSyncProtocol.syncBlockEntityToClient(this)) {
ServerMain.LOGGER.debug("update DispenserBlockEntity: {}", this.pos);
}
}
}
@@ -0,0 +1,41 @@
package com.github.zly2006.carpetslsaddition.mixin.protocol.pcaSyncProtocol.block;
import com.github.zly2006.carpetslsaddition.SLSCarpetSettings;
import com.github.zly2006.carpetslsaddition.ServerMain;
import com.github.zly2006.carpetslsaddition.network.pca.PcaSyncProtocol;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.block.entity.Hopper;
import net.minecraft.block.entity.HopperBlockEntity;
import net.minecraft.block.entity.LootableContainerBlockEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
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.function.BooleanSupplier;
@Mixin(HopperBlockEntity.class)
public abstract class MixinHopperBlockEntity extends LootableContainerBlockEntity implements Hopper {
protected MixinHopperBlockEntity(BlockEntityType<?> blockEntityType, BlockPos blockPos, BlockState blockState) {
super(blockEntityType, blockPos, blockState);
}
@Inject(method = "insertAndExtract", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/entity/HopperBlockEntity;markDirty(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;)V"))
private static void onInsertAndExtract(World world, BlockPos pos, BlockState state, HopperBlockEntity blockEntity, BooleanSupplier booleanSupplier, CallbackInfoReturnable<Boolean> cir) {
if (SLSCarpetSettings.pcaSyncProtocol && PcaSyncProtocol.syncBlockEntityToClient(blockEntity)) {
ServerMain.LOGGER.debug("update HopperBlockEntity: {}", pos);
}
}
@Override
public void markDirty() {
super.markDirty();
if (SLSCarpetSettings.pcaSyncProtocol && PcaSyncProtocol.syncBlockEntityToClient(this)) {
ServerMain.LOGGER.debug("update HopperBlockEntity: {}", this.pos);
}
}
}
@@ -0,0 +1,28 @@
package com.github.zly2006.carpetslsaddition.mixin.protocol.pcaSyncProtocol.block;
import com.github.zly2006.carpetslsaddition.SLSCarpetSettings;
import com.github.zly2006.carpetslsaddition.ServerMain;
import com.github.zly2006.carpetslsaddition.network.pca.PcaSyncProtocol;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.block.entity.LootableContainerBlockEntity;
import net.minecraft.block.entity.ShulkerBoxBlockEntity;
import net.minecraft.inventory.SidedInventory;
import net.minecraft.util.math.BlockPos;
import org.spongepowered.asm.mixin.Mixin;
@Mixin(ShulkerBoxBlockEntity.class)
public abstract class MixinShulkerBoxBlockEntity extends LootableContainerBlockEntity implements SidedInventory {
protected MixinShulkerBoxBlockEntity(BlockEntityType<?> blockEntityType, BlockPos blockPos, BlockState blockState) {
super(blockEntityType, blockPos, blockState);
}
@Override
public void markDirty() {
super.markDirty();
if (SLSCarpetSettings.pcaSyncProtocol && PcaSyncProtocol.syncBlockEntityToClient(this)) {
ServerMain.LOGGER.debug("update ShulkerBoxBlockEntity: {}", this.pos);
}
}
}
@@ -0,0 +1,31 @@
package com.github.zly2006.carpetslsaddition.mixin.protocol.pcaSyncProtocol.entity;
import com.github.zly2006.carpetslsaddition.SLSCarpetSettings;
import com.github.zly2006.carpetslsaddition.ServerMain;
import com.github.zly2006.carpetslsaddition.network.pca.PcaSyncProtocol;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.JumpingMount;
import net.minecraft.entity.Saddleable;
import net.minecraft.entity.passive.AbstractHorseEntity;
import net.minecraft.entity.passive.AnimalEntity;
import net.minecraft.inventory.Inventory;
import net.minecraft.inventory.InventoryChangedListener;
import net.minecraft.world.World;
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(AbstractHorseEntity.class)
public abstract class MixinHorseBaseEntity extends AnimalEntity implements InventoryChangedListener, JumpingMount, Saddleable {
protected MixinHorseBaseEntity(EntityType<? extends AnimalEntity> entityType, World world) {
super(entityType, world);
}
@Inject(method = "onInventoryChanged", at = @At(value = "HEAD"))
private void updateEntity(Inventory sender, CallbackInfo ci) {
if (SLSCarpetSettings.pcaSyncProtocol && PcaSyncProtocol.syncEntityToClient(this)) {
ServerMain.LOGGER.debug("update HorseBaseEntity inventory: onInventoryChanged.");
}
}
}
@@ -0,0 +1,48 @@
package com.github.zly2006.carpetslsaddition.mixin.protocol.pcaSyncProtocol.entity;
import com.github.zly2006.carpetslsaddition.SLSCarpetSettings;
import com.github.zly2006.carpetslsaddition.ServerMain;
import com.github.zly2006.carpetslsaddition.network.pca.PcaSyncProtocol;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.Npc;
import net.minecraft.entity.passive.MerchantEntity;
import net.minecraft.entity.passive.PassiveEntity;
import net.minecraft.inventory.Inventory;
import net.minecraft.inventory.InventoryChangedListener;
import net.minecraft.inventory.SimpleInventory;
import net.minecraft.village.Merchant;
import net.minecraft.world.World;
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(MerchantEntity.class)
public abstract class MixinMerchantEntity extends PassiveEntity implements Npc, Merchant, InventoryChangedListener {
@Final
@Shadow
private SimpleInventory inventory;
protected MixinMerchantEntity(EntityType<? extends PassiveEntity> entityType, World world) {
super(entityType, world);
}
@Inject(method = "<init>(Lnet/minecraft/entity/EntityType;Lnet/minecraft/world/World;)V", at = @At(value = "RETURN"))
private void addInventoryListener(EntityType<? extends MerchantEntity> entityType, World world, CallbackInfo info) {
if (this.world.isClient()) {
return;
}
this.inventory.addListener(this);
}
@Override
public void onInventoryChanged(Inventory inventory) {
if (SLSCarpetSettings.pcaSyncProtocol && PcaSyncProtocol.syncEntityToClient(this)) {
ServerMain.LOGGER.debug("update villager inventory: onInventoryChanged.");
}
}
}
@@ -0,0 +1,29 @@
package com.github.zly2006.carpetslsaddition.mixin.protocol.pcaSyncProtocol.entity;
import com.github.zly2006.carpetslsaddition.SLSCarpetSettings;
import com.github.zly2006.carpetslsaddition.ServerMain;
import com.github.zly2006.carpetslsaddition.network.pca.PcaSyncProtocol;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.vehicle.AbstractMinecartEntity;
import net.minecraft.entity.vehicle.StorageMinecartEntity;
import net.minecraft.inventory.Inventory;
import net.minecraft.screen.NamedScreenHandlerFactory;
import net.minecraft.world.World;
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(StorageMinecartEntity.class)
public abstract class MixinStorageMinecartEntity extends AbstractMinecartEntity implements Inventory, NamedScreenHandlerFactory {
protected MixinStorageMinecartEntity(EntityType<?> entityType, World world) {
super(entityType, world);
}
@Inject(method = "markDirty", at = @At(value = "RETURN"))
private void updateInventory(CallbackInfo ci) {
if (SLSCarpetSettings.pcaSyncProtocol && PcaSyncProtocol.syncEntityToClient(this)) {
ServerMain.LOGGER.debug("update StorageMinecartEntity inventory.");
}
}
}
@@ -0,0 +1,26 @@
package com.github.zly2006.carpetslsaddition.mixin.screen;
import com.github.zly2006.carpetslsaddition.util.ShulkerBoxItemUtil;
import net.minecraft.item.ItemStack;
import net.minecraft.screen.ScreenHandler;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(ScreenHandler.class)
public class MixinScreenHandler {
@Redirect(method = "insertItem", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;isStackable()Z", ordinal = 0))
private boolean insertItemIsStackable(ItemStack itemStack) {
return ShulkerBoxItemUtil.isStackable(itemStack);
}
@Redirect(method = "insertItem", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;getMaxCount()I"))
private int insertItemGetMaxCount0(ItemStack itemStack) {
return ShulkerBoxItemUtil.getMaxCount(itemStack);
}
@Redirect(method = "internalOnSlotClick", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;getMaxCount()I", ordinal = -1))
private int removeStackGetMaxCount(ItemStack itemStack) {
return ShulkerBoxItemUtil.getMaxCount(itemStack);
}
}
@@ -0,0 +1,16 @@
package com.github.zly2006.carpetslsaddition.mixin.screen;
import com.github.zly2006.carpetslsaddition.util.ShulkerBoxItemUtil;
import net.minecraft.item.ItemStack;
import net.minecraft.screen.slot.Slot;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(Slot.class)
public class MixinSlot {
@Redirect(method = "getMaxItemCount(Lnet/minecraft/item/ItemStack;)I", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;getMaxCount()I", ordinal = 0))
private int getMaxItemCount(ItemStack itemStack) {
return ShulkerBoxItemUtil.getMaxCount(itemStack);
}
}
@@ -0,0 +1,38 @@
package com.github.zly2006.carpetslsaddition.mixin.server;
import com.github.zly2006.carpetslsaddition.SLSCarpetSettings;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.server.PlayerManager;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.Identifier;
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.zip.CRC32;
@Mixin(PlayerManager.class)
public class MixinPlayerManager {
@Inject(method = "sendWorldInfo", at = @At(value = "RETURN"))
public void preOnSendWorldInfo(ServerPlayerEntity player, ServerWorld world, CallbackInfo ci) {
if (SLSCarpetSettings.xaeroWorldName.equals("#none")) {
return;
}
Identifier xaeroworldmap = new Identifier("xaeroworldmap", "main");
Identifier xaerominimap = new Identifier("xaerominimap", "main");
CRC32 crc = new CRC32();
crc.update(SLSCarpetSettings.xaeroWorldName.getBytes());
ByteBuf buf = Unpooled.buffer();
buf.writeByte(0);
buf.writeInt((int) crc.getValue());
ServerPlayNetworking.send(player, xaeroworldmap, new PacketByteBuf(buf.duplicate()));
ServerPlayNetworking.send(player, xaerominimap, new PacketByteBuf(buf.duplicate()));
}
}
@@ -1,4 +1,4 @@
package com.github.zly2006.carpetslsaddition.mixin;
package com.github.zly2006.carpetslsaddition.mixin.world;
import com.github.zly2006.carpetslsaddition.SLSCarpetSettings;
import net.minecraft.entity.EntityType;