Tweak how equipment updates are detected

This commit is contained in:
fullwall 2023-04-11 00:10:45 +08:00
parent 155ffe522e
commit fcb0c7d953
24 changed files with 310 additions and 149 deletions

View File

@ -94,6 +94,7 @@ import net.citizensnpcs.api.npc.NPCRegistry;
import net.citizensnpcs.api.trait.trait.Owner;
import net.citizensnpcs.api.util.Messaging;
import net.citizensnpcs.editor.Editor;
import net.citizensnpcs.model.ModelTrait;
import net.citizensnpcs.npc.skin.SkinUpdateTracker;
import net.citizensnpcs.trait.ClickRedirectTrait;
import net.citizensnpcs.trait.CommandTrait;
@ -257,7 +258,9 @@ public class EventListen implements Listener {
if (event instanceof EntityDamageByEntityEvent) {
NPCDamageByEntityEvent damageEvent = new NPCDamageByEntityEvent(npc, (EntityDamageByEntityEvent) event);
Bukkit.getPluginManager().callEvent(damageEvent);
if (npc.hasTrait(ModelTrait.class) && !damageEvent.isCancelled()) {
npc.getOrAddTrait(ModelTrait.class).onDamage(damageEvent);
}
if (!damageEvent.isCancelled() || !(damageEvent.getDamager() instanceof Player))
return;

View File

@ -2,7 +2,6 @@ package net.citizensnpcs.nms.v1_10_R1.entity;
import java.io.IOException;
import java.net.Socket;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@ -58,7 +57,6 @@ import net.minecraft.server.v1_10_R1.NavigationAbstract;
import net.minecraft.server.v1_10_R1.NetworkManager;
import net.minecraft.server.v1_10_R1.Packet;
import net.minecraft.server.v1_10_R1.PacketPlayOutEntityEquipment;
import net.minecraft.server.v1_10_R1.PacketPlayOutUpdateAttributes;
import net.minecraft.server.v1_10_R1.PathType;
import net.minecraft.server.v1_10_R1.PlayerInteractManager;
import net.minecraft.server.v1_10_R1.SoundEffect;
@ -410,6 +408,13 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable
if (!(cache == null && equipment == null)
&& (cache == null ^ equipment == null || !ItemStack.equals(cache, equipment))) {
itemChanged = true;
if (cache != null) {
this.getAttributeMap().a(cache.a(slot));
}
if (equipment != null) {
this.getAttributeMap().b(equipment.a(slot));
}
}
equipmentCache.put(slot, equipment);
}

View File

@ -222,8 +222,10 @@ import net.minecraft.server.v1_10_R1.EntityTracker;
import net.minecraft.server.v1_10_R1.EntityTrackerEntry;
import net.minecraft.server.v1_10_R1.EntityTypes;
import net.minecraft.server.v1_10_R1.EntityWither;
import net.minecraft.server.v1_10_R1.EnumItemSlot;
import net.minecraft.server.v1_10_R1.GenericAttributes;
import net.minecraft.server.v1_10_R1.IInventory;
import net.minecraft.server.v1_10_R1.ItemStack;
import net.minecraft.server.v1_10_R1.MathHelper;
import net.minecraft.server.v1_10_R1.MinecraftKey;
import net.minecraft.server.v1_10_R1.MobEffects;
@ -232,6 +234,7 @@ import net.minecraft.server.v1_10_R1.NetworkManager;
import net.minecraft.server.v1_10_R1.Packet;
import net.minecraft.server.v1_10_R1.PacketPlayOutAnimation;
import net.minecraft.server.v1_10_R1.PacketPlayOutBed;
import net.minecraft.server.v1_10_R1.PacketPlayOutEntityEquipment;
import net.minecraft.server.v1_10_R1.PacketPlayOutEntityHeadRotation;
import net.minecraft.server.v1_10_R1.PacketPlayOutEntityTeleport;
import net.minecraft.server.v1_10_R1.PacketPlayOutOpenWindow;
@ -327,6 +330,7 @@ public class NMSImpl implements NMSBridge {
boolean deltaTracking = handle instanceof EntityPlayer ? false : true;
EntityTrackerEntry tracker = new EntityTrackerEntry(handle, visibleDistance,
handle.world.getMinecraftServer().getPlayerList().d(), updateInterval, deltaTracking);
Map<EnumItemSlot, ItemStack> equipment = Maps.newEnumMap(EnumItemSlot.class);
return new EntityPacketTracker() {
@Override
public void link(Player player) {
@ -339,6 +343,23 @@ public class NMSImpl implements NMSBridge {
@Override
public void run() {
if (handle instanceof EntityLiving) {
boolean changed = false;
EntityLiving entity = (EntityLiving) handle;
for (EnumItemSlot slot : EnumItemSlot.values()) {
ItemStack old = equipment.get(slot);
ItemStack curr = entity.getEquipment(slot);
if (!changed && !ItemStack.matches(old, curr)) {
changed = true;
}
equipment.put(slot, curr);
}
if (changed) {
for (EnumItemSlot slot : EnumItemSlot.values()) {
agg.send(new PacketPlayOutEntityEquipment(handle.getId(), slot, equipment.get(slot)));
}
}
}
tracker.a();
}

View File

@ -2,7 +2,6 @@ package net.citizensnpcs.nms.v1_11_R1.entity;
import java.io.IOException;
import java.net.Socket;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@ -60,7 +59,6 @@ import net.minecraft.server.v1_11_R1.NavigationAbstract;
import net.minecraft.server.v1_11_R1.NetworkManager;
import net.minecraft.server.v1_11_R1.Packet;
import net.minecraft.server.v1_11_R1.PacketPlayOutEntityEquipment;
import net.minecraft.server.v1_11_R1.PacketPlayOutUpdateAttributes;
import net.minecraft.server.v1_11_R1.PathType;
import net.minecraft.server.v1_11_R1.PlayerInteractManager;
import net.minecraft.server.v1_11_R1.SoundEffect;
@ -421,6 +419,13 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable
if (!(cache == null && equipment == null)
&& (cache == null ^ equipment == null || !ItemStack.equals(cache, equipment))) {
itemChanged = true;
if (!cache.isEmpty()) {
this.getAttributeMap().a(cache.a(slot));
}
if (!equipment.isEmpty()) {
this.getAttributeMap().b(equipment.a(slot));
}
}
equipmentCache.put(slot, equipment);
}

View File

@ -241,9 +241,11 @@ import net.minecraft.server.v1_11_R1.EntityTracker;
import net.minecraft.server.v1_11_R1.EntityTrackerEntry;
import net.minecraft.server.v1_11_R1.EntityTypes;
import net.minecraft.server.v1_11_R1.EntityWither;
import net.minecraft.server.v1_11_R1.EnumItemSlot;
import net.minecraft.server.v1_11_R1.EnumMoveType;
import net.minecraft.server.v1_11_R1.GenericAttributes;
import net.minecraft.server.v1_11_R1.IInventory;
import net.minecraft.server.v1_11_R1.ItemStack;
import net.minecraft.server.v1_11_R1.MathHelper;
import net.minecraft.server.v1_11_R1.MinecraftKey;
import net.minecraft.server.v1_11_R1.MobEffects;
@ -252,6 +254,7 @@ import net.minecraft.server.v1_11_R1.NetworkManager;
import net.minecraft.server.v1_11_R1.Packet;
import net.minecraft.server.v1_11_R1.PacketPlayOutAnimation;
import net.minecraft.server.v1_11_R1.PacketPlayOutBed;
import net.minecraft.server.v1_11_R1.PacketPlayOutEntityEquipment;
import net.minecraft.server.v1_11_R1.PacketPlayOutEntityHeadRotation;
import net.minecraft.server.v1_11_R1.PacketPlayOutEntityTeleport;
import net.minecraft.server.v1_11_R1.PacketPlayOutOpenWindow;
@ -348,6 +351,7 @@ public class NMSImpl implements NMSBridge {
boolean deltaTracking = handle instanceof EntityPlayer ? false : true;
EntityTrackerEntry tracker = new EntityTrackerEntry(handle, visibleDistance,
handle.world.getMinecraftServer().getPlayerList().d(), updateInterval, deltaTracking);
Map<EnumItemSlot, ItemStack> equipment = Maps.newEnumMap(EnumItemSlot.class);
return new EntityPacketTracker() {
@Override
public void link(Player player) {
@ -360,6 +364,23 @@ public class NMSImpl implements NMSBridge {
@Override
public void run() {
if (handle instanceof EntityLiving) {
boolean changed = false;
EntityLiving entity = (EntityLiving) handle;
for (EnumItemSlot slot : EnumItemSlot.values()) {
ItemStack old = equipment.get(slot);
ItemStack curr = entity.getEquipment(slot);
if (!changed && !ItemStack.matches(old, curr)) {
changed = true;
}
equipment.put(slot, curr);
}
if (changed) {
for (EnumItemSlot slot : EnumItemSlot.values()) {
agg.send(new PacketPlayOutEntityEquipment(handle.getId(), slot, equipment.get(slot)));
}
}
}
tracker.a();
}

View File

@ -3,7 +3,6 @@ package net.citizensnpcs.nms.v1_12_R1.entity;
import java.io.IOException;
import java.lang.invoke.MethodHandle;
import java.net.Socket;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@ -64,7 +63,6 @@ import net.minecraft.server.v1_12_R1.NavigationAbstract;
import net.minecraft.server.v1_12_R1.NetworkManager;
import net.minecraft.server.v1_12_R1.Packet;
import net.minecraft.server.v1_12_R1.PacketPlayOutEntityEquipment;
import net.minecraft.server.v1_12_R1.PacketPlayOutUpdateAttributes;
import net.minecraft.server.v1_12_R1.PathType;
import net.minecraft.server.v1_12_R1.PlayerInteractManager;
import net.minecraft.server.v1_12_R1.SoundEffect;
@ -447,6 +445,13 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable
if (!(cache == null && equipment == null)
&& (cache == null ^ equipment == null || !ItemStack.equals(cache, equipment))) {
itemChanged = true;
if (!cache.isEmpty()) {
this.getAttributeMap().a(cache.a(slot));
}
if (!equipment.isEmpty()) {
this.getAttributeMap().b(equipment.a(slot));
}
}
equipmentCache.put(slot, equipment);
}

View File

@ -245,9 +245,11 @@ import net.minecraft.server.v1_12_R1.EntityTracker;
import net.minecraft.server.v1_12_R1.EntityTrackerEntry;
import net.minecraft.server.v1_12_R1.EntityTypes;
import net.minecraft.server.v1_12_R1.EntityWither;
import net.minecraft.server.v1_12_R1.EnumItemSlot;
import net.minecraft.server.v1_12_R1.EnumMoveType;
import net.minecraft.server.v1_12_R1.GenericAttributes;
import net.minecraft.server.v1_12_R1.IInventory;
import net.minecraft.server.v1_12_R1.ItemStack;
import net.minecraft.server.v1_12_R1.MathHelper;
import net.minecraft.server.v1_12_R1.MinecraftKey;
import net.minecraft.server.v1_12_R1.MobEffects;
@ -256,6 +258,7 @@ import net.minecraft.server.v1_12_R1.NetworkManager;
import net.minecraft.server.v1_12_R1.Packet;
import net.minecraft.server.v1_12_R1.PacketPlayOutAnimation;
import net.minecraft.server.v1_12_R1.PacketPlayOutBed;
import net.minecraft.server.v1_12_R1.PacketPlayOutEntityEquipment;
import net.minecraft.server.v1_12_R1.PacketPlayOutEntityHeadRotation;
import net.minecraft.server.v1_12_R1.PacketPlayOutEntityTeleport;
import net.minecraft.server.v1_12_R1.PacketPlayOutOpenWindow;
@ -353,6 +356,7 @@ public class NMSImpl implements NMSBridge {
boolean deltaTracking = handle instanceof EntityPlayer ? false : true;
EntityTrackerEntry tracker = new EntityTrackerEntry(handle, visibleDistance,
handle.world.getMinecraftServer().getPlayerList().d(), updateInterval, deltaTracking);
Map<EnumItemSlot, ItemStack> equipment = Maps.newEnumMap(EnumItemSlot.class);
return new EntityPacketTracker() {
@Override
public void link(Player player) {
@ -365,6 +369,23 @@ public class NMSImpl implements NMSBridge {
@Override
public void run() {
if (handle instanceof EntityLiving) {
boolean changed = false;
EntityLiving entity = (EntityLiving) handle;
for (EnumItemSlot slot : EnumItemSlot.values()) {
ItemStack old = equipment.get(slot);
ItemStack curr = entity.getEquipment(slot);
if (!changed && !ItemStack.matches(old, curr)) {
changed = true;
}
equipment.put(slot, curr);
}
if (changed) {
for (EnumItemSlot slot : EnumItemSlot.values()) {
agg.send(new PacketPlayOutEntityEquipment(handle.getId(), slot, equipment.get(slot)));
}
}
}
tracker.a();
}

View File

@ -3,7 +3,6 @@ package net.citizensnpcs.nms.v1_13_R2.entity;
import java.io.IOException;
import java.lang.invoke.MethodHandle;
import java.net.Socket;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@ -64,7 +63,6 @@ import net.minecraft.server.v1_13_R2.NavigationAbstract;
import net.minecraft.server.v1_13_R2.NetworkManager;
import net.minecraft.server.v1_13_R2.Packet;
import net.minecraft.server.v1_13_R2.PacketPlayOutEntityEquipment;
import net.minecraft.server.v1_13_R2.PacketPlayOutUpdateAttributes;
import net.minecraft.server.v1_13_R2.PathType;
import net.minecraft.server.v1_13_R2.PlayerInteractManager;
import net.minecraft.server.v1_13_R2.SoundEffect;
@ -430,7 +428,6 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable
if (!npc.isUpdating(NPCUpdate.PACKET))
return;
updateEffects = true;
boolean itemChanged = false;
for (EnumItemSlot slot : EnumItemSlot.values()) {
@ -439,6 +436,13 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable
if (!(cache == null && equipment == null)
&& (cache == null ^ equipment == null || !ItemStack.equals(cache, equipment))) {
itemChanged = true;
if (!cache.isEmpty()) {
this.getAttributeMap().a(cache.a(slot));
}
if (!equipment.isEmpty()) {
this.getAttributeMap().b(equipment.a(slot));
}
}
equipmentCache.put(slot, equipment);
}

View File

@ -260,12 +260,14 @@ import net.minecraft.server.v1_13_R2.EntityTrackerEntry;
import net.minecraft.server.v1_13_R2.EntityTurtle;
import net.minecraft.server.v1_13_R2.EntityTypes;
import net.minecraft.server.v1_13_R2.EntityWither;
import net.minecraft.server.v1_13_R2.EnumItemSlot;
import net.minecraft.server.v1_13_R2.EnumMoveType;
import net.minecraft.server.v1_13_R2.GenericAttributes;
import net.minecraft.server.v1_13_R2.IBlockData;
import net.minecraft.server.v1_13_R2.IChatBaseComponent;
import net.minecraft.server.v1_13_R2.IInventory;
import net.minecraft.server.v1_13_R2.IRegistry;
import net.minecraft.server.v1_13_R2.ItemStack;
import net.minecraft.server.v1_13_R2.MathHelper;
import net.minecraft.server.v1_13_R2.MinecraftKey;
import net.minecraft.server.v1_13_R2.MobEffects;
@ -275,6 +277,7 @@ import net.minecraft.server.v1_13_R2.Packet;
import net.minecraft.server.v1_13_R2.PacketPlayOutAnimation;
import net.minecraft.server.v1_13_R2.PacketPlayOutBed;
import net.minecraft.server.v1_13_R2.PacketPlayOutEntity.PacketPlayOutEntityLook;
import net.minecraft.server.v1_13_R2.PacketPlayOutEntityEquipment;
import net.minecraft.server.v1_13_R2.PacketPlayOutEntityHeadRotation;
import net.minecraft.server.v1_13_R2.PacketPlayOutEntityTeleport;
import net.minecraft.server.v1_13_R2.PacketPlayOutOpenWindow;
@ -374,6 +377,7 @@ public class NMSImpl implements NMSBridge {
EntityTrackerEntry tracker = new EntityTrackerEntry(handle, visibleDistance,
handle.world.getMinecraftServer().getPlayerList().getFurthestViewableBlock(), updateInterval,
deltaTracking);
Map<EnumItemSlot, ItemStack> equipment = Maps.newEnumMap(EnumItemSlot.class);
return new EntityPacketTracker() {
@Override
public void link(Player player) {
@ -386,6 +390,23 @@ public class NMSImpl implements NMSBridge {
@Override
public void run() {
if (handle instanceof EntityLiving) {
boolean changed = false;
EntityLiving entity = (EntityLiving) handle;
for (EnumItemSlot slot : EnumItemSlot.values()) {
ItemStack old = equipment.get(slot);
ItemStack curr = entity.getEquipment(slot);
if (!changed && !ItemStack.matches(old, curr)) {
changed = true;
}
equipment.put(slot, curr);
}
if (changed) {
for (EnumItemSlot slot : EnumItemSlot.values()) {
agg.send(new PacketPlayOutEntityEquipment(handle.getId(), slot, equipment.get(slot)));
}
}
}
tracker.a();
}

View File

@ -2,7 +2,6 @@ package net.citizensnpcs.nms.v1_14_R1.entity;
import java.io.IOException;
import java.net.Socket;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@ -62,7 +61,6 @@ import net.minecraft.server.v1_14_R1.NavigationAbstract;
import net.minecraft.server.v1_14_R1.NetworkManager;
import net.minecraft.server.v1_14_R1.Packet;
import net.minecraft.server.v1_14_R1.PacketPlayOutEntityEquipment;
import net.minecraft.server.v1_14_R1.PacketPlayOutUpdateAttributes;
import net.minecraft.server.v1_14_R1.PathType;
import net.minecraft.server.v1_14_R1.PlayerInteractManager;
import net.minecraft.server.v1_14_R1.SoundEffect;
@ -435,7 +433,6 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable
if (!npc.isUpdating(NPCUpdate.PACKET))
return;
updateEffects = true;
boolean itemChanged = false;
for (EnumItemSlot slot : EnumItemSlot.values()) {
@ -444,6 +441,13 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable
if (!(cache == null && equipment == null)
&& (cache == null ^ equipment == null || !ItemStack.equals(cache, equipment))) {
itemChanged = true;
if (!cache.isEmpty()) {
this.getAttributeMap().a(cache.a(slot));
}
if (!equipment.isEmpty()) {
this.getAttributeMap().b(equipment.a(slot));
}
}
equipmentCache.put(slot, equipment);
}

View File

@ -277,18 +277,21 @@ import net.minecraft.server.v1_14_R1.EntityTrackerEntry;
import net.minecraft.server.v1_14_R1.EntityTurtle;
import net.minecraft.server.v1_14_R1.EntityTypes;
import net.minecraft.server.v1_14_R1.EntityWither;
import net.minecraft.server.v1_14_R1.EnumItemSlot;
import net.minecraft.server.v1_14_R1.EnumMoveType;
import net.minecraft.server.v1_14_R1.GenericAttributes;
import net.minecraft.server.v1_14_R1.IBlockData;
import net.minecraft.server.v1_14_R1.IChatBaseComponent;
import net.minecraft.server.v1_14_R1.IInventory;
import net.minecraft.server.v1_14_R1.IRegistry;
import net.minecraft.server.v1_14_R1.ItemStack;
import net.minecraft.server.v1_14_R1.MathHelper;
import net.minecraft.server.v1_14_R1.MinecraftKey;
import net.minecraft.server.v1_14_R1.MobEffects;
import net.minecraft.server.v1_14_R1.NavigationAbstract;
import net.minecraft.server.v1_14_R1.NetworkManager;
import net.minecraft.server.v1_14_R1.Packet;
import net.minecraft.server.v1_14_R1.PacketPlayOutEntityEquipment;
import net.minecraft.server.v1_14_R1.PacketPlayOutEntityHeadRotation;
import net.minecraft.server.v1_14_R1.PacketPlayOutEntityTeleport;
import net.minecraft.server.v1_14_R1.PacketPlayOutOpenWindow;
@ -410,6 +413,7 @@ public class NMSImpl implements NMSBridge {
EntityTrackerEntry tracker = new EntityTrackerEntry((WorldServer) handle.world, handle,
handle.getEntityType().getUpdateInterval(), handle.getEntityType().isDeltaTracking(), agg::send,
linked);
Map<EnumItemSlot, ItemStack> equipment = Maps.newEnumMap(EnumItemSlot.class);
return new EntityPacketTracker() {
@Override
public void link(Player player) {
@ -423,6 +427,23 @@ public class NMSImpl implements NMSBridge {
@Override
public void run() {
if (handle instanceof EntityLiving) {
boolean changed = false;
EntityLiving entity = (EntityLiving) handle;
for (EnumItemSlot slot : EnumItemSlot.values()) {
ItemStack old = equipment.get(slot);
ItemStack curr = entity.getEquipment(slot);
if (!changed && !ItemStack.matches(old, curr)) {
changed = true;
}
equipment.put(slot, curr);
}
if (changed) {
for (EnumItemSlot slot : EnumItemSlot.values()) {
agg.send(new PacketPlayOutEntityEquipment(handle.getId(), slot, equipment.get(slot)));
}
}
}
tracker.a();
}

View File

@ -2,7 +2,6 @@ package net.citizensnpcs.nms.v1_15_R1.entity;
import java.io.IOException;
import java.net.Socket;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@ -61,7 +60,6 @@ import net.minecraft.server.v1_15_R1.NavigationAbstract;
import net.minecraft.server.v1_15_R1.NetworkManager;
import net.minecraft.server.v1_15_R1.Packet;
import net.minecraft.server.v1_15_R1.PacketPlayOutEntityEquipment;
import net.minecraft.server.v1_15_R1.PacketPlayOutUpdateAttributes;
import net.minecraft.server.v1_15_R1.PathType;
import net.minecraft.server.v1_15_R1.PlayerInteractManager;
import net.minecraft.server.v1_15_R1.SoundEffect;
@ -441,6 +439,14 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable
ItemStack cache = equipmentCache.get(slot);
if (!(cache == null && equipment == null)
&& (cache == null ^ equipment == null || !ItemStack.equals(cache, equipment))) {
if (!cache.isEmpty()) {
this.getAttributeMap().a(cache.a(slot));
}
if (!equipment.isEmpty()) {
this.getAttributeMap().b(equipment.a(slot));
}
itemChanged = true;
}
equipmentCache.put(slot, equipment);

View File

@ -281,12 +281,14 @@ import net.minecraft.server.v1_15_R1.EntityTrackerEntry;
import net.minecraft.server.v1_15_R1.EntityTurtle;
import net.minecraft.server.v1_15_R1.EntityTypes;
import net.minecraft.server.v1_15_R1.EntityWither;
import net.minecraft.server.v1_15_R1.EnumItemSlot;
import net.minecraft.server.v1_15_R1.EnumMoveType;
import net.minecraft.server.v1_15_R1.GenericAttributes;
import net.minecraft.server.v1_15_R1.IBlockData;
import net.minecraft.server.v1_15_R1.IChatBaseComponent;
import net.minecraft.server.v1_15_R1.IInventory;
import net.minecraft.server.v1_15_R1.IRegistry;
import net.minecraft.server.v1_15_R1.ItemStack;
import net.minecraft.server.v1_15_R1.MathHelper;
import net.minecraft.server.v1_15_R1.MinecraftKey;
import net.minecraft.server.v1_15_R1.MinecraftServer;
@ -294,6 +296,7 @@ import net.minecraft.server.v1_15_R1.MobEffects;
import net.minecraft.server.v1_15_R1.NavigationAbstract;
import net.minecraft.server.v1_15_R1.NetworkManager;
import net.minecraft.server.v1_15_R1.Packet;
import net.minecraft.server.v1_15_R1.PacketPlayOutEntityEquipment;
import net.minecraft.server.v1_15_R1.PacketPlayOutEntityHeadRotation;
import net.minecraft.server.v1_15_R1.PacketPlayOutEntityTeleport;
import net.minecraft.server.v1_15_R1.PacketPlayOutOpenWindow;
@ -425,6 +428,7 @@ public class NMSImpl implements NMSBridge {
EntityTrackerEntry tracker = new EntityTrackerEntry((WorldServer) handle.world, handle,
handle.getEntityType().getUpdateInterval(), handle.getEntityType().isDeltaTracking(), agg::send,
linked);
Map<EnumItemSlot, ItemStack> equipment = Maps.newEnumMap(EnumItemSlot.class);
return new EntityPacketTracker() {
@Override
public void link(Player player) {
@ -438,6 +442,23 @@ public class NMSImpl implements NMSBridge {
@Override
public void run() {
if (handle instanceof EntityLiving) {
boolean changed = false;
EntityLiving entity = (EntityLiving) handle;
for (EnumItemSlot slot : EnumItemSlot.values()) {
ItemStack old = equipment.get(slot);
ItemStack curr = entity.getEquipment(slot);
if (!changed && !ItemStack.matches(old, curr)) {
changed = true;
}
equipment.put(slot, curr);
}
if (changed) {
for (EnumItemSlot slot : EnumItemSlot.values()) {
agg.send(new PacketPlayOutEntityEquipment(handle.getId(), slot, equipment.get(slot)));
}
}
}
tracker.a();
}

View File

@ -1,9 +1,9 @@
package net.citizensnpcs.nms.v1_16_R3.entity;
import java.io.IOException;
import java.lang.invoke.MethodHandle;
import java.net.Socket;
import java.util.List;
import java.util.Map;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@ -14,10 +14,7 @@ import org.bukkit.metadata.MetadataValue;
import org.bukkit.plugin.Plugin;
import org.bukkit.util.Vector;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.mojang.authlib.GameProfile;
import com.mojang.datafixers.util.Pair;
import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.api.CitizensAPI;
@ -47,17 +44,15 @@ import net.minecraft.server.v1_16_R3.ChatComponentText;
import net.minecraft.server.v1_16_R3.DamageSource;
import net.minecraft.server.v1_16_R3.Entity;
import net.minecraft.server.v1_16_R3.EntityHuman;
import net.minecraft.server.v1_16_R3.EntityLiving;
import net.minecraft.server.v1_16_R3.EntityPlayer;
import net.minecraft.server.v1_16_R3.EnumGamemode;
import net.minecraft.server.v1_16_R3.EnumItemSlot;
import net.minecraft.server.v1_16_R3.EnumProtocolDirection;
import net.minecraft.server.v1_16_R3.IBlockData;
import net.minecraft.server.v1_16_R3.IChatBaseComponent;
import net.minecraft.server.v1_16_R3.ItemStack;
import net.minecraft.server.v1_16_R3.MinecraftServer;
import net.minecraft.server.v1_16_R3.NetworkManager;
import net.minecraft.server.v1_16_R3.Packet;
import net.minecraft.server.v1_16_R3.PacketPlayOutEntityEquipment;
import net.minecraft.server.v1_16_R3.PlayerInteractManager;
import net.minecraft.server.v1_16_R3.SoundEffect;
import net.minecraft.server.v1_16_R3.Vec3D;
@ -65,10 +60,8 @@ import net.minecraft.server.v1_16_R3.WorldServer;
public class EntityHumanNPC extends EntityPlayer implements NPCHolder, SkinnableEntity, ForwardingMobAI {
private MobAI ai;
private final Map<EnumItemSlot, ItemStack> equipmentCache = Maps.newEnumMap(EnumItemSlot.class);
private int jumpTicks = 0;
private final CitizensNPC npc;
private final Location packetLocationCache = new Location(null, 0, 0, 0);
private PlayerlistTracker playerlistTracker;
private final SkinPacketTracker skinTracker;
@ -367,6 +360,11 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable
return;
noclip = isSpectator();
Bukkit.getServer().getPluginManager().unsubscribeFromPermission("bukkit.broadcast.user", getBukkitEntity());
try {
DETECT_EQUIPMENT_UPDATES.invoke(this);
} catch (Throwable e) {
e.printStackTrace();
}
boolean navigating = npc.getNavigator().isNavigating();
updatePackets(navigating);
npc.update();
@ -400,26 +398,6 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable
return;
updateEffects = true;
boolean itemChanged = false;
for (EnumItemSlot slot : EnumItemSlot.values()) {
ItemStack equipment = getEquipment(slot);
ItemStack cache = equipmentCache.get(slot);
if (!(cache == null && equipment == null)
&& (cache == null ^ equipment == null || !ItemStack.equals(cache, equipment))) {
itemChanged = true;
}
equipmentCache.put(slot, equipment);
}
if (!itemChanged)
return;
Location current = getBukkitEntity().getLocation(packetLocationCache);
Packet<?>[] packets = new Packet[1];
List<Pair<EnumItemSlot, ItemStack>> vals = Lists.newArrayList();
for (EnumItemSlot slot : EnumItemSlot.values()) {
vals.add(new Pair<EnumItemSlot, ItemStack>(slot, getEquipment(slot)));
}
packets[0] = new PacketPlayOutEntityEquipment(getId(), vals);
NMSImpl.sendPacketsNearby(getBukkitEntity(), current, packets);
}
public static class PlayerNPC extends CraftPlayer implements NPCHolder, SkinnableEntity {
@ -499,6 +477,7 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable
}
}
private static final MethodHandle DETECT_EQUIPMENT_UPDATES = NMS.getMethodHandle(EntityLiving.class, "p", true);
private static final float EPSILON = 0.003F;
private static final Location LOADED_LOCATION = new Location(null, 0, 0, 0);
}

View File

@ -293,6 +293,7 @@ import net.minecraft.server.v1_16_R3.EntityTrackerEntry;
import net.minecraft.server.v1_16_R3.EntityTurtle;
import net.minecraft.server.v1_16_R3.EntityTypes;
import net.minecraft.server.v1_16_R3.EntityWither;
import net.minecraft.server.v1_16_R3.EnumItemSlot;
import net.minecraft.server.v1_16_R3.EnumMoveType;
import net.minecraft.server.v1_16_R3.Fluid;
import net.minecraft.server.v1_16_R3.GenericAttributes;
@ -300,6 +301,7 @@ import net.minecraft.server.v1_16_R3.IBlockData;
import net.minecraft.server.v1_16_R3.IChatBaseComponent;
import net.minecraft.server.v1_16_R3.IInventory;
import net.minecraft.server.v1_16_R3.IRegistry;
import net.minecraft.server.v1_16_R3.ItemStack;
import net.minecraft.server.v1_16_R3.MathHelper;
import net.minecraft.server.v1_16_R3.MinecraftKey;
import net.minecraft.server.v1_16_R3.MinecraftServer;
@ -307,6 +309,7 @@ import net.minecraft.server.v1_16_R3.MobEffects;
import net.minecraft.server.v1_16_R3.NavigationAbstract;
import net.minecraft.server.v1_16_R3.NetworkManager;
import net.minecraft.server.v1_16_R3.Packet;
import net.minecraft.server.v1_16_R3.PacketPlayOutEntityEquipment;
import net.minecraft.server.v1_16_R3.PacketPlayOutEntityHeadRotation;
import net.minecraft.server.v1_16_R3.PacketPlayOutEntityTeleport;
import net.minecraft.server.v1_16_R3.PacketPlayOutOpenWindow;
@ -439,6 +442,7 @@ public class NMSImpl implements NMSBridge {
EntityTrackerEntry tracker = new EntityTrackerEntry((WorldServer) handle.world, handle,
handle.getEntityType().getUpdateInterval(), handle.getEntityType().isDeltaTracking(), agg::send,
linked);
Map<EnumItemSlot, ItemStack> equipment = Maps.newEnumMap(EnumItemSlot.class);
return new EntityPacketTracker() {
@Override
public void link(Player player) {
@ -452,6 +456,25 @@ public class NMSImpl implements NMSBridge {
@Override
public void run() {
if (handle instanceof EntityLiving) {
boolean changed = false;
EntityLiving entity = (EntityLiving) handle;
for (EnumItemSlot slot : EnumItemSlot.values()) {
ItemStack old = equipment.get(slot);
ItemStack curr = entity.getEquipment(slot);
if (!changed && !ItemStack.matches(old, curr)) {
changed = true;
}
equipment.put(slot, curr);
}
if (changed) {
List<com.mojang.datafixers.util.Pair<EnumItemSlot, ItemStack>> vals = Lists.newArrayList();
for (EnumItemSlot slot : EnumItemSlot.values()) {
vals.add(com.mojang.datafixers.util.Pair.of(slot, equipment.get(slot)));
}
agg.send(new PacketPlayOutEntityEquipment(handle.getId(), vals));
}
}
tracker.a();
}

View File

@ -4,8 +4,6 @@ import java.io.IOException;
import java.lang.invoke.MethodHandle;
import java.net.Socket;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@ -16,10 +14,7 @@ import org.bukkit.metadata.MetadataValue;
import org.bukkit.plugin.Plugin;
import org.bukkit.util.Vector;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.mojang.authlib.GameProfile;
import com.mojang.datafixers.util.Pair;
import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.api.CitizensAPI;
@ -49,8 +44,6 @@ import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.PacketFlow;
import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket;
import net.minecraft.network.protocol.game.ClientboundUpdateAttributesPacket;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
@ -59,9 +52,6 @@ import net.minecraft.sounds.SoundEvent;
import net.minecraft.stats.ServerStatsCounter;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.ai.attributes.AttributeInstance;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.GameType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
@ -69,10 +59,8 @@ import net.minecraft.world.phys.Vec3;
public class EntityHumanNPC extends ServerPlayer implements NPCHolder, SkinnableEntity, ForwardingMobAI {
private MobAI ai;
private final Map<EquipmentSlot, ItemStack> equipmentCache = Maps.newEnumMap(EquipmentSlot.class);
private int jumpTicks = 0;
private final CitizensNPC npc;
private final Location packetLocationCache = new Location(null, 0, 0, 0);
private PlayerlistTracker playerlistTracker;
private final SkinPacketTracker skinTracker;
private EmptyServerStatsCounter statsCache;
@ -160,8 +148,9 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
}
ai.getJumpControl().tick();
ai.getMoveControl().tick();
detectEquipmentUpdates();
this.noPhysics = isSpectator();
if (isSpectator()) {
this.noPhysics = true;
this.onGround = false;
}
if (npc.data().get(NPC.Metadata.COLLIDABLE, !npc.isProtected())) {
@ -408,27 +397,7 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
if (!npc.isUpdating(NPCUpdate.PACKET))
return;
effectsDirty = true;
boolean itemChanged = false;
for (EquipmentSlot slot : EquipmentSlot.values()) {
ItemStack equipment = getItemBySlot(slot);
ItemStack cache = equipmentCache.get(slot);
if (!(cache == null && equipment == null)
&& (cache == null ^ equipment == null || !ItemStack.isSame(cache, equipment))) {
itemChanged = true;
}
equipmentCache.put(slot, equipment);
}
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);
}
public static class PlayerNPC extends CraftPlayer implements NPCHolder, SkinnableEntity {

View File

@ -251,6 +251,7 @@ import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.ClientboundOpenScreenPacket;
import net.minecraft.network.protocol.game.ClientboundPlayerInfoPacket;
import net.minecraft.network.protocol.game.ClientboundRotateHeadPacket;
import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket;
import net.minecraft.network.protocol.game.ClientboundSetPlayerTeamPacket;
import net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket;
import net.minecraft.network.syncher.EntityDataAccessor;
@ -274,6 +275,7 @@ import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.Entity.RemovalReason;
import net.minecraft.world.entity.EntityDimensions;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.MoverType;
@ -452,6 +454,7 @@ public class NMSImpl implements NMSBridge {
Set<ServerPlayerConnection> linked = Sets.newIdentityHashSet();
ServerEntity tracker = new ServerEntity((ServerLevel) handle.level, handle, handle.getType().updateInterval(),
handle.getType().trackDeltas(), agg::send, linked);
Map<EquipmentSlot, ItemStack> equipment = Maps.newEnumMap(EquipmentSlot.class);
return new EntityPacketTracker() {
@Override
public void link(Player player) {
@ -464,6 +467,25 @@ public class NMSImpl implements NMSBridge {
@Override
public void run() {
if (handle instanceof LivingEntity) {
boolean changed = false;
LivingEntity entity = (LivingEntity) handle;
for (EquipmentSlot slot : EquipmentSlot.values()) {
ItemStack old = equipment.get(slot);
ItemStack curr = entity.getItemBySlot(slot);
if (!changed && !ItemStack.matches(old, curr)) {
changed = true;
}
equipment.put(slot, curr);
}
if (changed) {
List<com.mojang.datafixers.util.Pair<EquipmentSlot, ItemStack>> vals = Lists.newArrayList();
for (EquipmentSlot slot : EquipmentSlot.values()) {
vals.add(com.mojang.datafixers.util.Pair.of(slot, equipment.get(slot)));
}
agg.send(new ClientboundSetEquipmentPacket(handle.getId(), vals));
}
}
tracker.sendChanges();
}
@ -1342,6 +1364,7 @@ public class NMSImpl implements NMSBridge {
@Override
public void setLocationDirectly(org.bukkit.entity.Entity entity, Location location) {
getHandle(entity).setPos(location.getX(), location.getY(), location.getZ());
getHandle(entity).moveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(),
location.getPitch());
}

View File

@ -4,8 +4,6 @@ import java.io.IOException;
import java.lang.invoke.MethodHandle;
import java.net.Socket;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@ -17,10 +15,7 @@ import org.bukkit.metadata.MetadataValue;
import org.bukkit.plugin.Plugin;
import org.bukkit.util.Vector;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.mojang.authlib.GameProfile;
import com.mojang.datafixers.util.Pair;
import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.api.CitizensAPI;
@ -50,8 +45,6 @@ import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.PacketFlow;
import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket;
import net.minecraft.network.protocol.game.ClientboundUpdateAttributesPacket;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
@ -60,9 +53,6 @@ import net.minecraft.sounds.SoundEvent;
import net.minecraft.stats.ServerStatsCounter;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.ai.attributes.AttributeInstance;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.GameType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
@ -70,10 +60,8 @@ import net.minecraft.world.phys.Vec3;
public class EntityHumanNPC extends ServerPlayer implements NPCHolder, SkinnableEntity, ForwardingMobAI {
private MobAI ai;
private final Map<EquipmentSlot, ItemStack> equipmentCache = Maps.newEnumMap(EquipmentSlot.class);
private int jumpTicks = 0;
private final CitizensNPC npc;
private final Location packetLocationCache = new Location(null, 0, 0, 0);
private PlayerlistTracker playerlistTracker;
private final SkinPacketTracker skinTracker;
private EmptyServerStatsCounter statsCache;
@ -161,8 +149,9 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
}
ai.getJumpControl().tick();
ai.getMoveControl().tick();
detectEquipmentUpdates();
this.noPhysics = isSpectator();
if (isSpectator()) {
this.noPhysics = true;
this.onGround = false;
}
if (npc.data().get(NPC.Metadata.COLLIDABLE, !npc.isProtected())) {
@ -388,7 +377,6 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
super.tick();
if (npc == null)
return;
noPhysics = isSpectator();
Bukkit.getServer().getPluginManager().unsubscribeFromPermission("bukkit.broadcast.user", getBukkitEntity());
updatePackets(npc.getNavigator().isNavigating());
npc.update();
@ -407,27 +395,7 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
if (!npc.isUpdating(NPCUpdate.PACKET))
return;
effectsDirty = true;
boolean itemChanged = false;
for (EquipmentSlot slot : EquipmentSlot.values()) {
ItemStack equipment = getItemBySlot(slot);
ItemStack cache = equipmentCache.get(slot);
if (!(cache == null && equipment == null)
&& (cache == null ^ equipment == null || !ItemStack.isSame(cache, equipment))) {
itemChanged = true;
}
equipmentCache.put(slot, equipment);
}
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);
}
public static class PlayerNPC extends CraftPlayer implements NPCHolder, SkinnableEntity {

View File

@ -252,6 +252,7 @@ import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.ClientboundOpenScreenPacket;
import net.minecraft.network.protocol.game.ClientboundPlayerInfoPacket;
import net.minecraft.network.protocol.game.ClientboundRotateHeadPacket;
import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket;
import net.minecraft.network.protocol.game.ClientboundSetPlayerTeamPacket;
import net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket;
import net.minecraft.network.syncher.EntityDataAccessor;
@ -275,6 +276,7 @@ import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.Entity.RemovalReason;
import net.minecraft.world.entity.EntityDimensions;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.MoverType;
@ -458,6 +460,7 @@ public class NMSImpl implements NMSBridge {
Set<ServerPlayerConnection> linked = Sets.newIdentityHashSet();
ServerEntity tracker = new ServerEntity((ServerLevel) handle.level, handle, handle.getType().updateInterval(),
handle.getType().trackDeltas(), agg::send, linked);
Map<EquipmentSlot, ItemStack> equipment = Maps.newEnumMap(EquipmentSlot.class);
return new EntityPacketTracker() {
@Override
public void link(Player player) {
@ -470,6 +473,25 @@ public class NMSImpl implements NMSBridge {
@Override
public void run() {
if (handle instanceof LivingEntity) {
boolean changed = false;
LivingEntity entity = (LivingEntity) handle;
for (EquipmentSlot slot : EquipmentSlot.values()) {
ItemStack old = equipment.get(slot);
ItemStack curr = entity.getItemBySlot(slot);
if (!changed && !ItemStack.matches(old, curr)) {
changed = true;
}
equipment.put(slot, curr);
}
if (changed) {
List<com.mojang.datafixers.util.Pair<EquipmentSlot, ItemStack>> vals = Lists.newArrayList();
for (EquipmentSlot slot : EquipmentSlot.values()) {
vals.add(com.mojang.datafixers.util.Pair.of(slot, equipment.get(slot)));
}
agg.send(new ClientboundSetEquipmentPacket(handle.getId(), vals));
}
}
tracker.sendChanges();
}
@ -1350,6 +1372,7 @@ public class NMSImpl implements NMSBridge {
@Override
public void setLocationDirectly(org.bukkit.entity.Entity entity, Location location) {
getHandle(entity).setPos(location.getX(), location.getY(), location.getZ());
getHandle(entity).moveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(),
location.getPitch());
}

View File

@ -4,7 +4,6 @@ import java.io.IOException;
import java.lang.invoke.MethodHandle;
import java.net.Socket;
import java.util.List;
import java.util.Map;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@ -15,10 +14,7 @@ import org.bukkit.metadata.MetadataValue;
import org.bukkit.plugin.Plugin;
import org.bukkit.util.Vector;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.mojang.authlib.GameProfile;
import com.mojang.datafixers.util.Pair;
import net.citizensnpcs.Settings.Setting;
import net.citizensnpcs.api.CitizensAPI;
@ -47,9 +43,7 @@ import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.network.chat.contents.LiteralContents;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.PacketFlow;
import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
@ -59,8 +53,6 @@ import net.minecraft.stats.ServerStatsCounter;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.GameType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
@ -69,10 +61,8 @@ import net.minecraft.world.phys.Vec3;
public class EntityHumanNPC extends ServerPlayer implements NPCHolder, SkinnableEntity, ForwardingMobAI {
private MobAI ai;
private final Map<EquipmentSlot, ItemStack> equipmentCache = Maps.newEnumMap(EquipmentSlot.class);
private int jumpTicks = 0;
private final CitizensNPC npc;
private final Location packetLocationCache = new Location(null, 0, 0, 0);
private boolean setBukkitEntity;
private final SkinPacketTracker skinTracker;
private EmptyServerStatsCounter statsCache;
@ -148,8 +138,9 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
moveOnCurrentHeading();
}
tickAI();
detectEquipmentUpdates();
noPhysics = isSpectator();
if (isSpectator()) {
this.noPhysics = true;
this.onGround = false;
}
if (npc.data().get(NPC.Metadata.COLLIDABLE, !npc.isProtected())) {
@ -374,7 +365,6 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
super.tick();
if (npc == null)
return;
noPhysics = isSpectator();
Bukkit.getServer().getPluginManager().unsubscribeFromPermission("bukkit.broadcast.user", getBukkitEntity());
updatePackets(npc.getNavigator().isNavigating());
npc.update();
@ -410,25 +400,6 @@ public class EntityHumanNPC extends ServerPlayer implements NPCHolder, Skinnable
return;
effectsDirty = true;
boolean itemChanged = false;
for (EquipmentSlot slot : EquipmentSlot.values()) {
ItemStack equipment = getItemBySlot(slot);
ItemStack cache = equipmentCache.get(slot);
if (!(cache == null && equipment == null)
&& (cache == null ^ equipment == null || !ItemStack.isSame(cache, equipment))) {
itemChanged = true;
}
equipmentCache.put(slot, equipment);
}
if (!itemChanged)
return;
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(), getBukkitEntity().getLocation(packetLocationCache), packets);
}
public static class PlayerNPC extends CraftPlayer implements NPCHolder, SkinnableEntity {

View File

@ -86,12 +86,12 @@ public class EntityMoveControl extends MoveControl {
}
private boolean shouldJump() {
if (!(this.entity instanceof Slime)) {
if (!(this.entity instanceof Slime))
return false;
}
if (this.jumpTicks-- <= 0) {
if (this.jumpTicks-- <= 0)
return true;
}
return false;
}

View File

@ -277,6 +277,7 @@ import net.minecraft.network.protocol.game.ClientboundOpenScreenPacket;
import net.minecraft.network.protocol.game.ClientboundPlayerInfoRemovePacket;
import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket;
import net.minecraft.network.protocol.game.ClientboundRotateHeadPacket;
import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket;
import net.minecraft.network.protocol.game.ClientboundSetPlayerTeamPacket;
import net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket;
import net.minecraft.network.syncher.EntityDataAccessor;
@ -299,6 +300,7 @@ import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.Entity.RemovalReason;
import net.minecraft.world.entity.EntityDimensions;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.MoverType;
@ -490,6 +492,7 @@ public class NMSImpl implements NMSBridge {
Set<ServerPlayerConnection> linked = Sets.newIdentityHashSet();
ServerEntity tracker = new ServerEntity((ServerLevel) handle.level, handle, handle.getType().updateInterval(),
handle.getType().trackDeltas(), agg::send, linked);
Map<EquipmentSlot, ItemStack> equipment = Maps.newEnumMap(EquipmentSlot.class);
return new EntityPacketTracker() {
@Override
public void link(Player player) {
@ -502,6 +505,25 @@ public class NMSImpl implements NMSBridge {
@Override
public void run() {
if (handle instanceof LivingEntity) {
boolean changed = false;
LivingEntity entity = (LivingEntity) handle;
for (EquipmentSlot slot : EquipmentSlot.values()) {
ItemStack old = equipment.get(slot);
ItemStack curr = entity.getItemBySlot(slot);
if (!changed && entity.equipmentHasChanged(old, curr)) {
changed = true;
}
equipment.put(slot, curr);
}
if (changed) {
List<com.mojang.datafixers.util.Pair<EquipmentSlot, ItemStack>> vals = Lists.newArrayList();
for (EquipmentSlot slot : EquipmentSlot.values()) {
vals.add(com.mojang.datafixers.util.Pair.of(slot, equipment.get(slot)));
}
agg.send(new ClientboundSetEquipmentPacket(handle.getId(), vals));
}
}
tracker.sendChanges();
}
@ -1486,6 +1508,7 @@ public class NMSImpl implements NMSBridge {
@Override
public void setLocationDirectly(org.bukkit.entity.Entity entity, Location location) {
getHandle(entity).setPos(location.getX(), location.getY(), location.getZ());
getHandle(entity).moveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(),
location.getPitch());
}

View File

@ -2,7 +2,6 @@ package net.citizensnpcs.nms.v1_8_R3.entity;
import java.io.IOException;
import java.net.Socket;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -56,7 +55,6 @@ import net.minecraft.server.v1_8_R3.NavigationAbstract;
import net.minecraft.server.v1_8_R3.NetworkManager;
import net.minecraft.server.v1_8_R3.Packet;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityEquipment;
import net.minecraft.server.v1_8_R3.PacketPlayOutUpdateAttributes;
import net.minecraft.server.v1_8_R3.PlayerInteractManager;
import net.minecraft.server.v1_8_R3.WorldServer;
import net.minecraft.server.v1_8_R3.WorldSettings;
@ -395,7 +393,6 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable
if (!npc.isUpdating(NPCUpdate.PACKET))
return;
updateEffects = true;
boolean itemChanged = false;
for (int slot = 0; slot < this.inventory.armor.length; slot++) {
@ -404,6 +401,13 @@ public class EntityHumanNPC extends EntityPlayer implements NPCHolder, Skinnable
if (!(cache == null && equipment == null)
&& (cache == null ^ equipment == null || !ItemStack.equals(cache, equipment))) {
itemChanged = true;
if (cache != null) {
this.getAttributeMap().a(cache.B());
}
if (equipment != null) {
this.getAttributeMap().b(equipment.B());
}
}
equipmentCache.put(slot, equipment);
}

View File

@ -201,6 +201,7 @@ import net.minecraft.server.v1_8_R3.EntityTypes;
import net.minecraft.server.v1_8_R3.EntityWither;
import net.minecraft.server.v1_8_R3.GenericAttributes;
import net.minecraft.server.v1_8_R3.IInventory;
import net.minecraft.server.v1_8_R3.ItemStack;
import net.minecraft.server.v1_8_R3.MathHelper;
import net.minecraft.server.v1_8_R3.Navigation;
import net.minecraft.server.v1_8_R3.NavigationAbstract;
@ -208,6 +209,7 @@ import net.minecraft.server.v1_8_R3.NetworkManager;
import net.minecraft.server.v1_8_R3.Packet;
import net.minecraft.server.v1_8_R3.PacketPlayOutAnimation;
import net.minecraft.server.v1_8_R3.PacketPlayOutBed;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityEquipment;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityHeadRotation;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityTeleport;
import net.minecraft.server.v1_8_R3.PacketPlayOutOpenWindow;
@ -307,6 +309,7 @@ public class NMSImpl implements NMSBridge {
boolean deltaTracking = handle instanceof EntityPlayer ? false : true;
EntityTrackerEntry tracker = new EntityTrackerEntry(handle, visibleDistance,
((WorldServer) handle.world).getMinecraftServer().getPlayerList().d(), deltaTracking);
Map<Integer, ItemStack> equipment = Maps.newHashMap();
return new EntityPacketTracker() {
@Override
public void link(Player player) {
@ -319,6 +322,23 @@ public class NMSImpl implements NMSBridge {
@Override
public void run() {
if (handle instanceof EntityLiving) {
boolean changed = false;
EntityLiving entity = (EntityLiving) handle;
for (int i = 0; i < entity.getEquipment().length; i++) {
ItemStack old = equipment.get(i);
ItemStack curr = entity.getEquipment()[i];
if (!changed && !ItemStack.matches(old, curr)) {
changed = true;
}
equipment.put(i, curr);
}
if (changed) {
for (int i = 0; i < entity.getEquipment().length; i++) {
agg.send(new PacketPlayOutEntityEquipment(handle.getId(), i, equipment.get(i)));
}
}
}
tracker.a();
}