Update upstream

This commit is contained in:
IzzelAliz 2022-10-06 09:44:29 +08:00
parent 25bf1ab839
commit 3a0b508f72
No known key found for this signature in database
GPG Key ID: EE50E123A11D8338
26 changed files with 350 additions and 25 deletions

View File

@ -862,6 +862,10 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB
((ServerPlayerEntityBridge) this.player).bridge$getBukkitEntity().updateInventory();
return;
}
itemstack = this.player.getItemInHand(enumhand); // Update in case it was changed in the event
if (itemstack.isEmpty()) {
return;
}
InteractionResult actionresulttype = this.player.gameMode.useItem(this.player, worldserver, itemstack, enumhand);
if (actionresulttype.shouldSwing()) {
this.player.swing(enumhand, true);
@ -1162,6 +1166,8 @@ public abstract class ServerPlayNetHandlerMixin implements ServerPlayNetHandlerB
if (s.isEmpty()) {
LOGGER.warn(this.player.getScoreboardName() + " tried to send an empty message");
} else if (getCraftPlayer().isConversing()) {
OutgoingPlayerChatMessage outgoing = OutgoingPlayerChatMessage.create(playerchatmessage);
outgoing.sendHeadersToRemainingPlayers(this.server.getPlayerList());
final String conversationInput = s;
((MinecraftServerBridge) this.server).bridge$queuedProcess(() -> getCraftPlayer().acceptConversationInput(conversationInput));
} else if (this.player.getChatVisibility() == ChatVisiblity.SYSTEM) { // Re-add "Command Only" flag check

View File

@ -0,0 +1,26 @@
package io.izzel.arclight.common.mixin.core.network.protocol.game;
import it.unimi.dsi.fastutil.shorts.ShortSet;
import net.minecraft.core.SectionPos;
import net.minecraft.network.protocol.game.ClientboundSectionBlocksUpdatePacket;
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.Mutable;
import org.spongepowered.asm.mixin.Shadow;
@Mixin(ClientboundSectionBlocksUpdatePacket.class)
public class ClientboundSectionBlocksUpdatePacketMixin {
@Shadow @Final @Mutable private SectionPos sectionPos;
@Shadow @Final @Mutable private boolean suppressLightUpdates;
@Shadow @Final @Mutable private short[] positions;
@Shadow @Final @Mutable private BlockState[] states;
public void arclight$constructor(SectionPos sectionposition, ShortSet shortset, BlockState[] states, boolean flag) {
this.sectionPos = sectionposition;
this.suppressLightUpdates = flag;
this.positions = shortset.toShortArray();
this.states = states;
}
}

View File

@ -216,6 +216,9 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge,
@Shadow public abstract int getMaxAirSupply();
@Shadow public abstract int getAirSupply();
@Shadow public abstract void gameEvent(GameEvent p_146851_);
@Shadow protected abstract SoundEvent getSwimSound();
@Shadow protected abstract SoundEvent getSwimSplashSound();
@Shadow protected abstract SoundEvent getSwimHighSpeedSplashSound();
// @formatter:on
private static final int CURRENT_LEVEL = 2;
@ -279,6 +282,18 @@ public abstract class EntityMixin implements InternalEntityBridge, EntityBridge,
return Entity.TOTAL_AIR_SUPPLY;
}
public SoundEvent getSwimSound0() {
return getSwimSound();
}
public SoundEvent getSwimSplashSound0() {
return getSwimSplashSound();
}
public SoundEvent getSwimHighSpeedSplashSound0() {
return getSwimHighSpeedSplashSound();
}
@Inject(method = "getMaxAirSupply", cancellable = true, at = @At("RETURN"))
private void arclight$useBukkitMaxAir(CallbackInfoReturnable<Integer> cir) {
cir.setReturnValue(this.maxAirTicks);

View File

@ -79,7 +79,7 @@ public abstract class ExperienceOrbMixin extends EntityMixin {
ItemStack itemstack = entry.getValue();
int j = Math.min(this.xpToDurability(this.value), itemstack.getDamageValue());
// CraftBukkit start
org.bukkit.event.player.PlayerItemMendEvent event = CraftEventFactory.callPlayerItemMendEvent(player, (ExperienceOrb) (Object) this, itemstack, j);
org.bukkit.event.player.PlayerItemMendEvent event = CraftEventFactory.callPlayerItemMendEvent(player, (ExperienceOrb) (Object) this, itemstack, entry.getKey(), j);
j = event.getRepairAmount();
if (event.isCancelled()) {
return i;

View File

@ -56,6 +56,7 @@ import net.minecraftforge.event.ForgeEventFactory;
import net.minecraftforge.event.entity.living.MobEffectEvent;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v.CraftEquipmentSlot;
import org.bukkit.craftbukkit.v.attribute.CraftAttributeMap;
import org.bukkit.craftbukkit.v.entity.CraftLivingEntity;
import org.bukkit.craftbukkit.v.entity.CraftPlayer;
@ -185,6 +186,11 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
@Shadow protected abstract void verifyEquippedItem(ItemStack p_181123_);
@Shadow public abstract boolean wasExperienceConsumed();
@Shadow public abstract int getExperienceReward();
@Shadow @Nullable protected abstract SoundEvent getHurtSound(DamageSource p_21239_);
@Shadow protected abstract SoundEvent getFallDamageSound(int p_21313_);
@Shadow protected abstract SoundEvent getDrinkingSound(ItemStack p_21174_);
@Shadow public abstract SoundEvent getEatingSound(ItemStack p_21202_);
@Shadow public abstract InteractionHand getUsedItemHand();
// @formatter:on
public int expToDrop;
@ -206,6 +212,26 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
this.entityData.set(DATA_HEALTH_ID, (float) this.getAttributeValue(Attributes.MAX_HEALTH));
}
public SoundEvent getHurtSound0(DamageSource damagesource) {
return getHurtSound(damagesource);
}
public SoundEvent getDeathSound0() {
return getDeathSound();
}
public SoundEvent getFallDamageSound0(int fallHeight) {
return getFallDamageSound(fallHeight);
}
public SoundEvent getDrinkingSound0(ItemStack itemstack) {
return getDrinkingSound(itemstack);
}
public SoundEvent getEatingSound0(ItemStack itemstack) {
return getEatingSound(itemstack);
}
@Redirect(method = "dropAllDeathLoot", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;dropExperience()V"))
private void arclight$dropLater(LivingEntity livingEntity) {
}
@ -890,16 +916,18 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
net.minecraft.world.item.ItemStack itemstack = null;
net.minecraft.world.item.ItemStack itemstack1 = ItemStack.EMPTY;
org.bukkit.inventory.EquipmentSlot bukkitHand = null;
for (InteractionHand hand : InteractionHand.values()) {
itemstack1 = this.getItemInHand(hand);
if (itemstack1.getItem() == Items.TOTEM_OF_UNDYING) {
itemstack = itemstack1.copy();
bukkitHand = CraftEquipmentSlot.getHand(hand);
// itemstack1.shrink(1);
break;
}
}
EntityResurrectEvent event = new EntityResurrectEvent(this.getBukkitEntity());
EntityResurrectEvent event = new EntityResurrectEvent(this.getBukkitEntity(), bukkitHand);
event.setCancelled(itemstack == null);
Bukkit.getPluginManager().callEvent(event);
@ -988,7 +1016,7 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt
private ItemStack arclight$itemConsume(ItemStack itemStack, Level worldIn, LivingEntity entityLiving, CallbackInfo ci) {
if (this instanceof ServerPlayerEntityBridge) {
final org.bukkit.inventory.ItemStack craftItem = CraftItemStack.asBukkitCopy(itemStack);
final PlayerItemConsumeEvent event = new PlayerItemConsumeEvent((Player) this.getBukkitEntity(), craftItem);
final PlayerItemConsumeEvent event = new PlayerItemConsumeEvent((Player) this.getBukkitEntity(), craftItem, CraftEquipmentSlot.getHand(this.getUsedItemHand()));
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
((ServerPlayerEntityBridge) this).bridge$getBukkitEntity().updateInventory();

View File

@ -10,6 +10,7 @@ import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.protocol.game.ClientboundSetEntityLinkPacket;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.Entity;
@ -66,6 +67,7 @@ public abstract class MobMixin extends LivingEntityMixin implements MobEntityBri
@Shadow protected abstract boolean canReplaceCurrentItem(ItemStack candidate, ItemStack existing);
@Shadow protected abstract void setItemSlotAndDropWhenKilled(EquipmentSlot p_233657_1_, ItemStack p_233657_2_);
@Shadow @Nullable public abstract <T extends Mob> T convertTo(EntityType<T> p_233656_1_, boolean p_233656_2_);
@Shadow @Nullable protected abstract SoundEvent getAmbientSound();
// @formatter:on
public boolean aware;
@ -94,6 +96,10 @@ public abstract class MobMixin extends LivingEntityMixin implements MobEntityBri
this.aware = true;
}
public SoundEvent getAmbientSound0() {
return getAmbientSound();
}
protected transient boolean arclight$targetSuccess = false;
private transient EntityTargetEvent.TargetReason arclight$reason;
private transient boolean arclight$fireEvent;
@ -235,7 +241,7 @@ public abstract class MobMixin extends LivingEntityMixin implements MobEntityBri
@Inject(method = "interact", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Mob;dropLeash(ZZ)V"))
private void arclight$unleash(Player player, InteractionHand hand, CallbackInfoReturnable<InteractionResult> cir) {
if (CraftEventFactory.callPlayerUnleashEntityEvent((Mob) (Object) this, player).isCancelled()) {
if (CraftEventFactory.callPlayerUnleashEntityEvent((Mob) (Object) this, player, hand).isCancelled()) {
((ServerPlayer) player).connection.send(new ClientboundSetEntityLinkPacket((Mob) (Object) this, this.getLeashHolder()));
cir.setReturnValue(InteractionResult.PASS);
}
@ -243,7 +249,7 @@ public abstract class MobMixin extends LivingEntityMixin implements MobEntityBri
@Inject(method = "checkAndHandleImportantInteractions", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Mob;setLeashedTo(Lnet/minecraft/world/entity/Entity;Z)V"))
private void arclight$leash(Player player, InteractionHand hand, CallbackInfoReturnable<InteractionResult> cir) {
if (CraftEventFactory.callPlayerLeashEntityEvent((Mob) (Object) this, player, player).isCancelled()) {
if (CraftEventFactory.callPlayerLeashEntityEvent((Mob) (Object) this, player, player, hand).isCancelled()) {
((ServerPlayer) player).connection.send(new ClientboundSetEntityLinkPacket((Mob) (Object) this, this.getLeashHolder()));
cir.setReturnValue(InteractionResult.PASS);
}

View File

@ -0,0 +1,45 @@
package io.izzel.arclight.common.mixin.core.world.entity.ai.behavior;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.valueproviders.UniformInt;
import net.minecraft.world.entity.AgeableMob;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.ai.behavior.BabyFollowAdult;
import net.minecraft.world.entity.ai.behavior.BehaviorUtils;
import net.minecraft.world.entity.ai.memory.MemoryModuleType;
import org.bukkit.craftbukkit.v.entity.CraftLivingEntity;
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.bukkit.event.entity.EntityTargetEvent;
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 java.util.function.Function;
@Mixin(BabyFollowAdult.class)
public abstract class BabyFollowAdultMixin<E extends AgeableMob> {
// @formatter:off
@Shadow protected abstract AgeableMob getNearestAdult(E p_147430_);
@Shadow @Final private Function<LivingEntity, Float> speedModifier;
@Shadow @Final private UniformInt followRange;
// @formatter:on
/**
* @author IzzelAliz
* @reason
*/
@Overwrite
protected void start(ServerLevel p_147426_, E entity, long p_147428_) {
var event = CraftEventFactory.callEntityTargetLivingEvent(entity, this.getNearestAdult(entity), EntityTargetEvent.TargetReason.FOLLOW_LEADER);
if (event.isCancelled()) {
return;
}
if (event.getTarget() != null) {
BehaviorUtils.setWalkAndLookTargetMemories(entity, ((CraftLivingEntity) event.getTarget()).getHandle(), this.speedModifier.apply(entity), this.followRange.getMinValue() - 1);
} else {
entity.getBrain().eraseMemory(MemoryModuleType.NEAREST_VISIBLE_ADULT);
}
}
}

View File

@ -0,0 +1,51 @@
package io.izzel.arclight.common.mixin.core.world.entity.ai.behavior;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.ai.behavior.BehaviorUtils;
import net.minecraft.world.entity.ai.behavior.GoToWantedItem;
import net.minecraft.world.entity.ai.memory.MemoryModuleType;
import net.minecraft.world.entity.animal.allay.Allay;
import net.minecraft.world.entity.item.ItemEntity;
import org.bukkit.craftbukkit.v.entity.CraftEntity;
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.bukkit.event.entity.EntityTargetEvent;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Optional;
@Mixin(GoToWantedItem.class)
public abstract class GoToWantedItemMixin<E extends LivingEntity> {
// @formatter:off
@Shadow protected abstract ItemEntity getClosestLovedItem(E p_23156_);
@Shadow @Final private float speedModifier;
// @formatter:on
@Inject(method = "start", cancellable = true, at = @At("HEAD"))
private void arclight$entityTarget(ServerLevel level, E entity, long p_23154_, CallbackInfo ci) {
if (entity instanceof Allay) {
Entity target = this.getClosestLovedItem(entity);
var event = CraftEventFactory.callEntityTargetEvent(entity, target, EntityTargetEvent.TargetReason.CLOSEST_ENTITY);
if (event.isCancelled()) {
ci.cancel();
}
target = (event.getTarget() == null) ? null : ((CraftEntity) event.getTarget()).getHandle();
if (target instanceof ItemEntity item) {
entity.getBrain().setMemory(MemoryModuleType.NEAREST_VISIBLE_WANTED_ITEM, Optional.of(item));
BehaviorUtils.setWalkAndLookTargetMemories(entity, target, this.speedModifier, 0);
} else {
entity.getBrain().eraseMemory(MemoryModuleType.NEAREST_VISIBLE_WANTED_ITEM);
}
ci.cancel();
}
}
}

View File

@ -0,0 +1,31 @@
package io.izzel.arclight.common.mixin.core.world.entity.ai.sensing;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.PathfinderMob;
import net.minecraft.world.entity.ai.Brain;
import net.minecraft.world.entity.ai.memory.MemoryModuleType;
import net.minecraft.world.entity.ai.sensing.TemptingSensor;
import net.minecraft.world.entity.player.Player;
import org.bukkit.craftbukkit.v.entity.CraftHumanEntity;
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.bukkit.event.entity.EntityTargetEvent;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(TemptingSensor.class)
public class TemptingSensorMixin {
@Redirect(method = "doTick(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/entity/PathfinderMob;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/ai/Brain;setMemory(Lnet/minecraft/world/entity/ai/memory/MemoryModuleType;Ljava/lang/Object;)V"))
private <U> void arclight$entityTarget(Brain<?> instance, MemoryModuleType<U> memoryModuleType, U value, ServerLevel level, PathfinderMob mob) {
var event = CraftEventFactory.callEntityTargetLivingEvent(mob, (Player) value, EntityTargetEvent.TargetReason.TEMPT);
if (event.isCancelled()) {
return;
}
if (event.getTarget() instanceof Player) {
instance.setMemory(MemoryModuleType.TEMPTING_PLAYER, ((CraftHumanEntity) event.getTarget()).getHandle());
} else {
instance.eraseMemory(MemoryModuleType.TEMPTING_PLAYER);
}
}
}

View File

@ -0,0 +1,78 @@
package io.izzel.arclight.common.mixin.core.world.entity.animal;
import io.izzel.arclight.common.bridge.core.world.WorldBridge;
import io.izzel.arclight.common.mixin.core.world.entity.MobMixin;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.animal.allay.Allay;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.entity.EntityRegainHealthEvent;
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.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(Allay.class)
public abstract class AllayMixin extends MobMixin {
// @formatter:off
@Shadow @Final private static EntityDataAccessor<Boolean> DATA_CAN_DUPLICATE;
@Shadow private void shadow$duplicateAllay() {}
// @formatter:on
public boolean forceDancing = false;
public void setCanDuplicate(boolean canDuplicate) {
this.entityData.set(DATA_CAN_DUPLICATE, canDuplicate);
}
@Inject(method = "aiStep", at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/world/entity/animal/allay/Allay;heal(F)V"))
private void arclight$healReason(CallbackInfo ci) {
this.bridge$pushHealReason(EntityRegainHealthEvent.RegainReason.REGEN);
}
@Inject(method = "mobInteract", cancellable = true, at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/world/entity/animal/allay/Allay;duplicateAllay()V"))
private void arclight$cancelDuplicate(Player p_218361_, InteractionHand p_218362_, CallbackInfoReturnable<InteractionResult> cir) {
var allay = arclight$duplicate;
arclight$duplicate = null;
if (allay == null) {
cir.setReturnValue(InteractionResult.SUCCESS);
}
}
@Inject(method = "shouldStopDancing", cancellable = true, at = @At("HEAD"))
private void arclight$stopDancing(CallbackInfoReturnable<Boolean> cir) {
if (this.forceDancing) {
cir.setReturnValue(false);
}
}
private transient Allay arclight$duplicate;
@Redirect(method = "duplicateAllay", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;addFreshEntity(Lnet/minecraft/world/entity/Entity;)Z"))
private boolean arclight$captureDuplicate(Level instance, Entity entity) {
((WorldBridge) instance).bridge$pushAddEntityReason(CreatureSpawnEvent.SpawnReason.DUPLICATION);
if (instance.addFreshEntity(entity)) {
arclight$duplicate = (Allay) entity;
return true;
}
return false;
}
public Allay duplicateAllay() {
try {
this.shadow$duplicateAllay();
return arclight$duplicate;
} finally {
arclight$duplicate = null;
}
}
}

View File

@ -37,7 +37,7 @@ public interface BucketableMixin {
// entity.playSound(entity.getPickupSound(), 1.0F, 1.0F);
ItemStack itemstack1 = entity.getBucketItemStack();
entity.saveToBucketTag(itemstack1);
PlayerBucketEntityEvent event = CraftEventFactory.callPlayerFishBucketEvent(entity, player, itemstack, itemstack1);
PlayerBucketEntityEvent event = CraftEventFactory.callPlayerFishBucketEvent(entity, player, itemstack, itemstack1, hand);
itemstack1 = CraftItemStack.asNMSCopy(event.getEntityBucket());
if (event.isCancelled()) {
player.containerMenu.sendAllDataToRemote(); // We need to update inventory to resync client's bucket

View File

@ -1,6 +1,5 @@
package io.izzel.arclight.common.mixin.core.world.entity.animal;
import io.izzel.arclight.common.mixin.core.world.entity.animal.AnimalMixin;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.world.InteractionHand;
@ -27,7 +26,7 @@ public abstract class CowMixin extends AnimalMixin {
ItemStack itemstack = playerEntity.getItemInHand(hand);
if (itemstack.getItem() == Items.BUCKET && !this.isBaby()) {
playerEntity.playSound(SoundEvents.COW_MILK, 1.0F, 1.0F);
org.bukkit.event.player.PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) playerEntity.level, playerEntity, this.blockPosition(), this.blockPosition(), null, itemstack, Items.MILK_BUCKET);
org.bukkit.event.player.PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) playerEntity.level, playerEntity, this.blockPosition(), this.blockPosition(), null, itemstack, Items.MILK_BUCKET, hand);
if (event.isCancelled()) {
return InteractionResult.PASS;

View File

@ -3,6 +3,7 @@ package io.izzel.arclight.common.mixin.core.world.entity.animal.goat;
import io.izzel.arclight.common.mixin.core.world.entity.animal.AnimalMixin;
import io.izzel.arclight.mixin.Eject;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.animal.goat.Goat;
import net.minecraft.world.entity.player.Player;
@ -19,8 +20,8 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
public abstract class GoatMixin extends AnimalMixin {
@Eject(method = "mobInteract", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/ItemUtils;createFilledResult(Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/world/item/ItemStack;)Lnet/minecraft/world/item/ItemStack;"))
private ItemStack arclight$bucketFill(ItemStack handItem, Player player, ItemStack p_41816_, CallbackInfoReturnable<InteractionResult> cir) {
org.bukkit.event.player.PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) player.level, player, this.blockPosition(), this.blockPosition(), null, handItem, Items.MILK_BUCKET);
private ItemStack arclight$bucketFill(ItemStack handItem, Player player, ItemStack p_41816_, CallbackInfoReturnable<InteractionResult> cir, Player p_149379_, InteractionHand hand) {
var event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) player.level, player, this.blockPosition(), this.blockPosition(), null, handItem, Items.MILK_BUCKET, hand);
if (event.isCancelled()) {
cir.setReturnValue(InteractionResult.PASS);

View File

@ -151,7 +151,8 @@ public abstract class ArmorStandMixin extends LivingEntityMixin {
ArmorStand self = (ArmorStand) ((EntityBridge) this).bridge$getBukkitEntity();
EquipmentSlot slot = CraftEquipmentSlot.getSlot(slotType);
PlayerArmorStandManipulateEvent event = new PlayerArmorStandManipulateEvent(player, self, playerHeldItem, armorStandItem, slot);
EquipmentSlot bukkitHand = CraftEquipmentSlot.getHand(hand);
PlayerArmorStandManipulateEvent event = new PlayerArmorStandManipulateEvent(player, self, playerHeldItem, armorStandItem, slot, bukkitHand);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {

View File

@ -33,7 +33,7 @@ public abstract class LeashFenceKnotEntityMixin extends HangingEntityMixin {
final List<Mob> list = this.level.getEntitiesOfClass(Mob.class, new AABB(this.getX() - 7.0, this.getY() - 7.0, this.getZ() - 7.0, this.getX() + 7.0, this.getY() + 7.0, this.getZ() + 7.0));
for (final Mob entityinsentient : list) {
if (entityinsentient.getLeashHolder() == entityhuman) {
if (CraftEventFactory.callPlayerLeashEntityEvent(entityinsentient, (LeashFenceKnotEntity) (Object) this, entityhuman).isCancelled()) {
if (CraftEventFactory.callPlayerLeashEntityEvent(entityinsentient, (LeashFenceKnotEntity) (Object) this, entityhuman, enumhand).isCancelled()) {
((ServerPlayer) entityhuman).connection.send(new ClientboundSetEntityLinkPacket(entityinsentient, entityinsentient.getLeashHolder()));
} else {
entityinsentient.setLeashedTo((LeashFenceKnotEntity) (Object) this, true);
@ -45,7 +45,7 @@ public abstract class LeashFenceKnotEntityMixin extends HangingEntityMixin {
boolean die = true;
for (final Mob entityinsentient : list) {
if (entityinsentient.isLeashed() && entityinsentient.getLeashHolder() == (Object) this) {
if (CraftEventFactory.callPlayerUnleashEntityEvent(entityinsentient, entityhuman).isCancelled()) {
if (CraftEventFactory.callPlayerUnleashEntityEvent(entityinsentient, entityhuman, enumhand).isCancelled()) {
die = false;
} else {
entityinsentient.dropLeash(true, !entityhuman.getAbilities().instabuild);

View File

@ -83,7 +83,7 @@ public abstract class BoatItemMixin extends Item {
return new InteractionResultHolder<>(InteractionResult.FAIL, itemstack);
} else {
if (!worldIn.isClientSide) {
if (DistValidate.isValid(worldIn) && CraftEventFactory.callEntityPlaceEvent(worldIn, result.getBlockPos(), result.getDirection(), playerIn, boatentity).isCancelled()) {
if (DistValidate.isValid(worldIn) && CraftEventFactory.callEntityPlaceEvent(worldIn, result.getBlockPos(), result.getDirection(), playerIn, boatentity, handIn).isCancelled()) {
return new InteractionResultHolder<>(InteractionResult.FAIL, itemstack);
}
if (!worldIn.addFreshEntity(boatentity)) {

View File

@ -44,7 +44,7 @@ public abstract class BucketItemMixin {
BlockPos pos = result.getBlockPos();
BlockState state = worldIn.getBlockState(pos);
ItemStack dummyFluid = ((BucketPickup) state.getBlock()).pickupBlock(DummyGeneratorAccess.INSTANCE, pos, state);
PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) worldIn, playerIn, pos, pos, result.getDirection(), stack, dummyFluid.getItem());
PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) worldIn, playerIn, pos, pos, result.getDirection(), stack, dummyFluid.getItem(), handIn);
if (event.isCancelled()) {
((ServerPlayer) playerIn).connection.send(new ClientboundBlockUpdatePacket(worldIn, pos));
((ServerPlayerEntityBridge) playerIn).bridge$getBukkitEntity().updateInventory();
@ -59,6 +59,7 @@ public abstract class BucketItemMixin {
arclight$direction = result.getDirection();
arclight$click = result.getBlockPos();
arclight$stack = stack;
arclight$hand = handIn;
}
@Inject(method = "use", at = @At("RETURN"))
@ -76,10 +77,11 @@ public abstract class BucketItemMixin {
return arclight$captureItem == null ? itemStack : CraftItemStack.asNMSCopy(arclight$captureItem);
}
public boolean emptyContents(Player entity, Level world, BlockPos pos, @Nullable BlockHitResult result, Direction direction, BlockPos clicked, ItemStack itemstack) {
public boolean emptyContents(Player entity, Level world, BlockPos pos, @Nullable BlockHitResult result, Direction direction, BlockPos clicked, ItemStack itemstack, InteractionHand hand) {
arclight$direction = direction;
arclight$click = clicked;
arclight$stack = itemstack;
arclight$hand = hand;
try {
return this.emptyContents(entity, world, pos, result);
} finally {
@ -92,12 +94,13 @@ public abstract class BucketItemMixin {
private transient Direction arclight$direction;
private transient BlockPos arclight$click;
private transient ItemStack arclight$stack;
private transient InteractionHand arclight$hand;
@Inject(method = "emptyContents", cancellable = true, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/dimension/DimensionType;ultraWarm()Z"))
private void arclight$bucketEmpty(Player player, Level worldIn, BlockPos posIn, BlockHitResult rayTrace, CallbackInfoReturnable<Boolean> cir) {
if (!DistValidate.isValid(worldIn)) return;
if (player != null) {
PlayerBucketEmptyEvent event = CraftEventFactory.callPlayerBucketEmptyEvent((ServerLevel) worldIn, player, posIn, arclight$click, arclight$direction, arclight$stack);
PlayerBucketEmptyEvent event = CraftEventFactory.callPlayerBucketEmptyEvent((ServerLevel) worldIn, player, posIn, arclight$click, arclight$direction, arclight$stack, arclight$hand == null ? InteractionHand.MAIN_HAND : arclight$hand);
if (event.isCancelled()) {
((ServerPlayer) player).connection.send(new ClientboundBlockUpdatePacket(worldIn, posIn));
((ServerPlayerEntityBridge) player).bridge$getBukkitEntity().updateInventory();

View File

@ -18,6 +18,7 @@ import net.minecraft.world.item.enchantment.EnchantmentHelper;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.gameevent.GameEvent;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v.CraftEquipmentSlot;
import org.bukkit.entity.FishHook;
import org.bukkit.event.player.PlayerFishEvent;
import org.spongepowered.asm.mixin.Mixin;
@ -55,7 +56,7 @@ public class FishingRodItemMixin extends Item {
FishingHook hook = new FishingHook(playerIn, worldIn, j, k);
if (DistValidate.isValid(worldIn)) {
PlayerFishEvent playerFishEvent = new PlayerFishEvent(((ServerPlayerEntityBridge) playerIn).bridge$getBukkitEntity(), null, (FishHook) ((EntityBridge) hook).bridge$getBukkitEntity(), PlayerFishEvent.State.FISHING);
PlayerFishEvent playerFishEvent = new PlayerFishEvent(((ServerPlayerEntityBridge) playerIn).bridge$getBukkitEntity(), null, (FishHook) ((EntityBridge) hook).bridge$getBukkitEntity(), CraftEquipmentSlot.getHand(handIn), PlayerFishEvent.State.FISHING);
Bukkit.getPluginManager().callEvent(playerFishEvent);
if (playerFishEvent.isCancelled()) {

View File

@ -14,6 +14,7 @@ import net.minecraft.world.level.Level;
import org.bukkit.Bukkit;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.craftbukkit.v.CraftEquipmentSlot;
import org.bukkit.craftbukkit.v.block.CraftBlock;
import org.bukkit.craftbukkit.v.inventory.CraftItemStack;
import org.bukkit.entity.Hanging;
@ -36,7 +37,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, CraftItemStack.asBukkitCopy(itemStack));
HangingPlaceEvent event = new HangingPlaceEvent((Hanging) ((EntityBridge) hangingEntity).bridge$getBukkitEntity(), who, blockClicked, blockFace, CraftEquipmentSlot.getHand(context.getHand()), CraftItemStack.asBukkitCopy(itemStack));
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {

View File

@ -3,14 +3,17 @@ package io.izzel.arclight.common.mixin.core.world.item;
import io.izzel.arclight.common.bridge.core.entity.EntityBridge;
import io.izzel.arclight.common.bridge.core.entity.player.PlayerEntityBridge;
import net.minecraft.core.BlockPos;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.decoration.LeashFenceKnotEntity;
import net.minecraft.world.item.LeadItem;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.AABB;
import org.bukkit.Bukkit;
import org.bukkit.block.BlockFace;
import org.bukkit.craftbukkit.v.CraftEquipmentSlot;
import org.bukkit.craftbukkit.v.block.CraftBlock;
import org.bukkit.craftbukkit.v.event.CraftEventFactory;
import org.bukkit.entity.Hanging;
@ -18,10 +21,25 @@ import org.bukkit.entity.Player;
import org.bukkit.event.hanging.HangingPlaceEvent;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(LeadItem.class)
public class LeadItemMixin {
private static InteractionHand arclight$hand;
@Inject(method = "useOn", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/LeadItem;bindPlayerMobs(Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/InteractionResult;"))
private void arclight$captureHand(UseOnContext p_42834_, CallbackInfoReturnable<InteractionResult> cir) {
arclight$hand = p_42834_.getHand();
}
@Inject(method = "useOn", at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/world/item/LeadItem;bindPlayerMobs(Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/InteractionResult;"))
private void arclight$resetHand(UseOnContext p_42834_, CallbackInfoReturnable<InteractionResult> cir) {
arclight$hand = p_42834_.getHand();
}
/**
* @author IzzelAliz
* @reason
@ -39,7 +57,7 @@ public class LeadItemMixin {
if (mobentity.getLeashHolder() == player) {
if (leashknotentity == null) {
leashknotentity = LeashFenceKnotEntity.getOrCreateKnot(worldIn, fence);
HangingPlaceEvent event = new HangingPlaceEvent((Hanging) ((EntityBridge) leashknotentity).bridge$getBukkitEntity(), player != null ? (Player) ((PlayerEntityBridge) player).bridge$getBukkitEntity() : null, CraftBlock.at(worldIn, fence), BlockFace.SELF);
HangingPlaceEvent event = new HangingPlaceEvent((Hanging) ((EntityBridge) leashknotentity).bridge$getBukkitEntity(), player != null ? (Player) ((PlayerEntityBridge) player).bridge$getBukkitEntity() : null, CraftBlock.at(worldIn, fence), BlockFace.SELF, CraftEquipmentSlot.getHand(arclight$hand));
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
@ -47,7 +65,7 @@ public class LeadItemMixin {
return InteractionResult.PASS;
}
}
if (CraftEventFactory.callPlayerLeashEntityEvent(mobentity, leashknotentity, player).isCancelled()) {
if (CraftEventFactory.callPlayerLeashEntityEvent(mobentity, leashknotentity, player, arclight$hand).isCancelled()) {
continue;
}
mobentity.setLeashedTo(leashknotentity, true);

View File

@ -5,6 +5,7 @@ import net.minecraft.core.BlockPos;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.util.Mth;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
@ -39,7 +40,7 @@ public interface CaveVinesMixin {
}
if (entity instanceof Player) {
PlayerHarvestBlockEvent event = CraftEventFactory.callPlayerHarvestBlockEvent(level, pos, (Player) entity, Collections.singletonList(new ItemStack(Items.GLOW_BERRIES, 1)));
PlayerHarvestBlockEvent event = CraftEventFactory.callPlayerHarvestBlockEvent(level, pos, (Player) entity, InteractionHand.MAIN_HAND, Collections.singletonList(new ItemStack(Items.GLOW_BERRIES, 1)));
if (event.isCancelled()) {
return InteractionResult.SUCCESS; // We need to return a success either way, because making it PASS or FAIL will result in a bug where cancelling while harvesting w/ block in hand places block
}

View File

@ -3,6 +3,7 @@ package io.izzel.arclight.common.mixin.core.world.level.block;
import io.izzel.arclight.mixin.Eject;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
@ -46,8 +47,8 @@ public class SweetBerryBushBlockMixin {
@Eject(method = "use", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/SweetBerryBushBlock;popResource(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/item/ItemStack;)V"))
private void arclight$playerHarvest(Level worldIn, BlockPos pos, ItemStack stack, CallbackInfoReturnable<InteractionResult> cir,
BlockState state, Level worldIn1, BlockPos pos1, Player player) {
PlayerHarvestBlockEvent event = CraftEventFactory.callPlayerHarvestBlockEvent(worldIn, pos, player, Collections.singletonList(stack));
BlockState state, Level worldIn1, BlockPos pos1, Player player, InteractionHand hand) {
PlayerHarvestBlockEvent event = CraftEventFactory.callPlayerHarvestBlockEvent(worldIn, pos, player, hand, Collections.singletonList(stack));
if (!event.isCancelled()) {
for (org.bukkit.inventory.ItemStack itemStack : event.getItemsHarvested()) {
Block.popResource(worldIn, pos, CraftItemStack.asNMSCopy(itemStack));

View File

@ -127,6 +127,7 @@ public class ArclightMixinPlugin implements IMixinConfigPlugin {
.add("net.minecraft.commands.Commands")
.add("net.minecraft.world.level.storage.LevelStorageSource.LevelStorageAccess")
.add("net.minecraft.network.protocol.game.ClientboundSystemChatPacket")
.add("net.minecraft.network.protocol.game.ClientboundSectionBlocksUpdatePacket")
.build();
@Override

View File

@ -531,3 +531,10 @@ public net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemp
public net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager f_230345_
public net.minecraft.world.level.storage.LevelStorageSource$LevelStorageAccess f_230867_
public-f net.minecraft.server.ReloadableServerResources f_206847_
# Bukkit 1.19.2
public net.minecraft.world.entity.animal.allay.Allay f_238682_ # jukeboxPos
public net.minecraft.world.entity.animal.allay.Allay f_238791_ # duplicationCooldown
public net.minecraft.world.entity.animal.allay.Allay m_239811_()V # resetDuplicationCooldown
public net.minecraft.world.entity.animal.allay.Allay m_218324_()Z # canDuplicate
public net.minecraft.world.entity.projectile.FireworkRocketEntity f_37022_ # life
public net.minecraft.world.entity.projectile.FireworkRocketEntity f_37024_ # attachedToEntity

View File

@ -39,6 +39,7 @@
"network.chat.TextColorMixin",
"network.protocol.PacketThreadUtilMixin",
"network.protocol.game.CCloseWindowPacketMixin",
"network.protocol.game.ClientboundSectionBlocksUpdatePacketMixin",
"network.protocol.game.ClientboundSystemChatPacketMixin",
"network.protocol.game.CPlayerTryUseItemOnBlockPacketMixin",
"network.protocol.game.CPlayerTryUseItemPacketMixin",
@ -98,6 +99,8 @@
"world.entity.MobMixin",
"world.entity.PathfinderMobMixin",
"world.entity.ai.behavior.AssignProfessionFromJobSiteMixin",
"world.entity.ai.behavior.BabyFollowAdultMixin",
"world.entity.ai.behavior.GoToWantedItemMixin",
"world.entity.ai.behavior.HarvestFarmlandMixin",
"world.entity.ai.behavior.InteractWithDoorMixin",
"world.entity.ai.behavior.PrepareRamNearestTargetMixin",
@ -119,8 +122,10 @@
"world.entity.ai.goal.SkeletonTrapGoalMixin",
"world.entity.ai.goal.TargetGoalMixin",
"world.entity.ai.goal.TemptGoalMixin",
"world.entity.ai.sensing.TemptingSensorMixin",
"world.entity.ai.village.VillageSiegeMixin",
"world.entity.ambient.BatMixin",
"world.entity.animal.AllayMixin",
"world.entity.animal.AnimalMixin",
"world.entity.animal.Bee_GrowCropGoalMixin",
"world.entity.animal.Bee_HurtByOtherGoalMixin",

View File

@ -42,7 +42,7 @@ repositories {
mavenCentral()
}
def embedLibs = [/*"org.spongepowered:mixin:$mixinVersion", */ 'org.yaml:snakeyaml:1.30',
def embedLibs = [/*"org.spongepowered:mixin:$mixinVersion", */ 'org.yaml:snakeyaml:1.33',
'org.xerial:sqlite-jdbc:3.36.0.3', 'mysql:mysql-connector-java:8.0.29',
/*'commons-lang:commons-lang:2.6',*/ 'com.googlecode.json-simple:json-simple:1.1.1',
'org.apache.logging.log4j:log4j-jul:2.17.2', 'net.md-5:SpecialSource:1.11.0',