Manually prevent clientside prediction for allay pickups, prevent item pickups on protected mobs

This commit is contained in:
fullwall 2022-07-17 02:47:36 +08:00
parent 674a621cf3
commit 34aea6553c
3 changed files with 23 additions and 11 deletions

View File

@ -444,6 +444,13 @@ public class CitizensNPC extends AbstractNPC {
if (isLiving) {
NMS.setKnockbackResistance((LivingEntity) getEntity(), isProtected() ? 1D : 0D);
if (isProtected() && SUPPORT_PICKUP_ITEMS) {
try {
((LivingEntity) getEntity()).setCanPickupItems(false);
} catch (Throwable t) {
SUPPORT_PICKUP_ITEMS = false;
}
}
}
if (isLiving && getEntity() instanceof Player) {
@ -522,11 +529,11 @@ public class CitizensNPC extends AbstractNPC {
}
private static final Location CACHE_LOCATION = new Location(null, 0, 0, 0);
private static final SetMultimap<ChunkCoord, NPC> CHUNK_LOADERS = HashMultimap.create();
private static final String NPC_METADATA_MARKER = "NPC";
private static boolean SUPPORT_GLOWING = true;
private static boolean SUPPORT_NODAMAGE_TICKS = true;
private static boolean SUPPORT_PICKUP_ITEMS = true;
private static boolean SUPPORT_SILENT = true;
private static boolean SUPPORT_USE_ITEM = true;
}

View File

@ -6,6 +6,10 @@ import org.bukkit.craftbukkit.v1_19_R1.entity.CraftAllay;
import org.bukkit.craftbukkit.v1_19_R1.entity.CraftEntity;
import org.bukkit.util.Vector;
import com.google.common.collect.Lists;
import com.mojang.datafixers.util.Pair;
import net.citizensnpcs.api.CitizensAPI;
import net.citizensnpcs.api.event.NPCEnderTeleportEvent;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_19_R1.util.ForwardingNPCHolder;
@ -16,6 +20,7 @@ import net.citizensnpcs.util.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.core.PositionImpl;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.world.InteractionHand;
@ -23,6 +28,7 @@ import net.minecraft.world.InteractionResult;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.animal.allay.Allay;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
@ -62,13 +68,6 @@ public class AllayController extends MobEntityController {
}
}
@Override
public boolean canPickUpLoot() {
if (npc != null && npc.isProtected())
return false;
return super.canPickUpLoot();
}
@Override
protected boolean canRide(Entity entity) {
if (npc != null && (entity instanceof Boat || entity instanceof AbstractMinecart)) {
@ -164,8 +163,15 @@ public class AllayController extends MobEntityController {
@Override
protected InteractionResult mobInteract(Player var0, InteractionHand var1) {
if (npc != null && npc.isProtected())
if (npc != null && npc.isProtected()) {
// prevent clientside prediction
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> {
NMSImpl.sendPacketNearby(null, getBukkitEntity().getLocation(),
new ClientboundSetEquipmentPacket(getId(), Lists.newArrayList(
Pair.of(EquipmentSlot.MAINHAND, this.getItemInHand(InteractionHand.MAIN_HAND)))));
});
return InteractionResult.FAIL;
}
return super.mobInteract(var0, var1);
}

View File

@ -507,13 +507,12 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
}
if (!itemChanged)
return;
Location current = getBukkitEntity().getLocation(packetLocationCache);
List<Pair<EquipmentSlot, ItemStack>> vals = Lists.newArrayList();
for (EquipmentSlot slot : EquipmentSlot.values()) {
vals.add(new Pair<EquipmentSlot, ItemStack>(slot, getItemBySlot(slot)));
}
Packet<?>[] packets = { new ClientboundSetEquipmentPacket(getId(), vals) };
NMSImpl.sendPacketsNearby(getBukkitEntity(), current, packets);
NMSImpl.sendPacketsNearby(getBukkitEntity(), getBukkitEntity().getLocation(packetLocationCache), packets);
}
public void updatePathfindingRange(float pathfindingRange) {