mirror of
https://github.com/CitizensDev/Citizens2.git
synced 2024-12-23 17:47:35 +01:00
Send an extra headrotation packet since spigot resets head rotation now, make some protocollib methods async, bump avoid-water costs by one block
This commit is contained in:
parent
5b5811cfea
commit
c0be235538
@ -1,18 +1,26 @@
|
||||
package net.citizensnpcs;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.PacketType.Play.Server;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.ProtocolManager;
|
||||
import com.comphenix.protocol.events.ListenerOptions;
|
||||
import com.comphenix.protocol.events.ListenerPriority;
|
||||
import com.comphenix.protocol.events.PacketAdapter;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
@ -28,11 +36,16 @@ import com.comphenix.protocol.wrappers.WrappedGameProfile;
|
||||
import com.comphenix.protocol.wrappers.WrappedSignedProperty;
|
||||
import com.comphenix.protocol.wrappers.WrappedWatchableObject;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.authlib.properties.Property;
|
||||
|
||||
import net.citizensnpcs.api.CitizensAPI;
|
||||
import net.citizensnpcs.api.event.NPCAddTraitEvent;
|
||||
import net.citizensnpcs.api.event.NPCDespawnEvent;
|
||||
import net.citizensnpcs.api.event.NPCEvent;
|
||||
import net.citizensnpcs.api.event.NPCSpawnEvent;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.trait.trait.MobType;
|
||||
import net.citizensnpcs.api.util.Messaging;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.citizensnpcs.trait.MirrorTrait;
|
||||
@ -40,10 +53,12 @@ import net.citizensnpcs.trait.RotationTrait;
|
||||
import net.citizensnpcs.trait.RotationTrait.PacketRotationSession;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
|
||||
public class ProtocolLibListener {
|
||||
public class ProtocolLibListener implements Listener {
|
||||
private final Class<?> flagsClass;
|
||||
private final ProtocolManager manager;
|
||||
private final Map<UUID, MirrorTrait> mirrorTraits = Maps.newConcurrentMap();
|
||||
private final Citizens plugin;
|
||||
private final Map<Integer, RotationTrait> rotationTraits = Maps.newConcurrentMap();
|
||||
|
||||
public ProtocolLibListener(Citizens plugin) {
|
||||
this.plugin = plugin;
|
||||
@ -51,6 +66,7 @@ public class ProtocolLibListener {
|
||||
flagsClass = MinecraftReflection.getMinecraftClass("RelativeMovement", "world.entity.RelativeMovement",
|
||||
"EnumPlayerTeleportFlags", "PacketPlayOutPosition$EnumPlayerTeleportFlags",
|
||||
"network.protocol.game.PacketPlayOutPosition$EnumPlayerTeleportFlags");
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
manager.addPacketListener(new PacketAdapter(plugin, ListenerPriority.HIGHEST, Server.ENTITY_METADATA) {
|
||||
@Override
|
||||
public void onPacketSending(PacketEvent event) {
|
||||
@ -98,12 +114,14 @@ public class ProtocolLibListener {
|
||||
}
|
||||
}
|
||||
});
|
||||
manager.addPacketListener(new PacketAdapter(plugin, ListenerPriority.HIGHEST, Server.PLAYER_INFO) {
|
||||
manager.addPacketListener(new PacketAdapter(plugin, ListenerPriority.HIGHEST, Arrays.asList(Server.PLAYER_INFO),
|
||||
ListenerOptions.ASYNC) {
|
||||
@Override
|
||||
public void onPacketSending(PacketEvent event) {
|
||||
int version = manager.getProtocolVersion(event.getPlayer());
|
||||
if (version >= 761) {
|
||||
NMS.onPlayerInfoAdd(event.getPlayer(), event.getPacket().getHandle());
|
||||
NMS.onPlayerInfoAdd(event.getPlayer(), event.getPacket().getHandle(),
|
||||
uuid -> mirrorTraits.get(uuid));
|
||||
return;
|
||||
}
|
||||
List<PlayerInfoData> list = event.getPacket().getPlayerInfoDataLists().readSafely(0);
|
||||
@ -114,10 +132,7 @@ public class ProtocolLibListener {
|
||||
PlayerInfoData npcInfo = list.get(i);
|
||||
if (npcInfo == null)
|
||||
continue;
|
||||
NPC npc = CitizensAPI.getNPCRegistry().getByUniqueIdGlobal(npcInfo.getProfile().getUUID());
|
||||
if (npc == null || !npc.isSpawned())
|
||||
continue;
|
||||
MirrorTrait trait = npc.getTraitNullable(MirrorTrait.class);
|
||||
MirrorTrait trait = mirrorTraits.get(npcInfo.getProfile().getUUID());
|
||||
if (trait == null || !trait.isMirroring(event.getPlayer())) {
|
||||
continue;
|
||||
}
|
||||
@ -148,46 +163,45 @@ public class ProtocolLibListener {
|
||||
}
|
||||
}
|
||||
});
|
||||
manager.addPacketListener(
|
||||
new PacketAdapter(plugin, ListenerPriority.MONITOR, Server.ENTITY_HEAD_ROTATION, Server.ENTITY_LOOK) {
|
||||
@Override
|
||||
public void onPacketSending(PacketEvent event) {
|
||||
NPC npc = getNPCFromPacket(event);
|
||||
if (npc == null)
|
||||
return;
|
||||
manager.addPacketListener(new PacketAdapter(
|
||||
plugin, ListenerPriority.MONITOR, Arrays.asList(Server.ENTITY_HEAD_ROTATION, Server.ENTITY_LOOK,
|
||||
Server.REL_ENTITY_MOVE_LOOK, Server.ENTITY_MOVE_LOOK, Server.POSITION, Server.ENTITY_TELEPORT),
|
||||
ListenerOptions.ASYNC) {
|
||||
@Override
|
||||
public void onPacketSending(PacketEvent event) {
|
||||
RotationTrait trait = rotationTraits.get(event.getPacket().getIntegers().readSafely(0));
|
||||
if (trait == null)
|
||||
return;
|
||||
|
||||
RotationTrait trait = npc.getTraitNullable(RotationTrait.class);
|
||||
if (trait == null)
|
||||
return;
|
||||
PacketRotationSession session = trait.getPacketSession(event.getPlayer());
|
||||
if (session == null || !session.isActive())
|
||||
return;
|
||||
|
||||
PacketRotationSession session = trait.getPacketSession(event.getPlayer());
|
||||
if (session == null || !session.isActive())
|
||||
return;
|
||||
PacketContainer packet = event.getPacket();
|
||||
PacketType type = event.getPacketType();
|
||||
if (type == Server.ENTITY_HEAD_ROTATION) {
|
||||
packet.getBytes().write(0, degToByte(session.getHeadYaw()));
|
||||
} else if (type == Server.ENTITY_LOOK) {
|
||||
packet.getBytes().write(0, degToByte(session.getBodyYaw()));
|
||||
packet.getBytes().write(1, degToByte(session.getPitch()));
|
||||
} else if (type == Server.ENTITY_MOVE_LOOK || type == Server.REL_ENTITY_MOVE_LOOK) {
|
||||
packet.getBytes().write(0, degToByte(session.getBodyYaw()));
|
||||
packet.getBytes().write(1, degToByte(session.getPitch()));
|
||||
} else if (type == Server.POSITION) {
|
||||
StructureModifier<Set<PlayerTeleportFlag>> flagsModifier = packet
|
||||
.getSets(EnumWrappers.getGenericConverter(flagsClass, PlayerTeleportFlag.class));
|
||||
Set<PlayerTeleportFlag> rel = flagsModifier.read(0);
|
||||
rel.remove(PlayerTeleportFlag.ZYAW);
|
||||
rel.remove(PlayerTeleportFlag.ZPITCH);
|
||||
flagsModifier.write(0, rel);
|
||||
packet.getFloat().write(0, session.getBodyYaw());
|
||||
packet.getFloat().write(1, session.getPitch());
|
||||
}
|
||||
|
||||
PacketContainer packet = event.getPacket();
|
||||
PacketType type = event.getPacketType();
|
||||
if (type == Server.ENTITY_HEAD_ROTATION) {
|
||||
packet.getBytes().write(0, degToByte(session.getHeadYaw()));
|
||||
} else if (type == Server.ENTITY_LOOK) {
|
||||
packet.getBytes().write(0, degToByte(session.getBodyYaw()));
|
||||
packet.getBytes().write(1, degToByte(session.getPitch()));
|
||||
} else if (type == Server.ENTITY_MOVE_LOOK || type == Server.REL_ENTITY_MOVE_LOOK) {
|
||||
packet.getBytes().write(0, degToByte(session.getBodyYaw()));
|
||||
packet.getBytes().write(1, degToByte(session.getPitch()));
|
||||
} else if (type == Server.POSITION) {
|
||||
StructureModifier<Set<PlayerTeleportFlag>> flagsModifier = packet
|
||||
.getSets(EnumWrappers.getGenericConverter(flagsClass, PlayerTeleportFlag.class));
|
||||
Set<PlayerTeleportFlag> rel = flagsModifier.read(0);
|
||||
rel.remove(PlayerTeleportFlag.ZYAW);
|
||||
rel.remove(PlayerTeleportFlag.ZPITCH);
|
||||
flagsModifier.write(0, rel);
|
||||
packet.getFloat().write(0, session.getBodyYaw());
|
||||
packet.getFloat().write(1, session.getPitch());
|
||||
}
|
||||
|
||||
session.onPacketOverwritten();
|
||||
}
|
||||
});
|
||||
session.onPacketOverwritten();
|
||||
Messaging.log("OVERWRITTEN " + type + " " + packet.getHandle());
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@ -214,6 +228,36 @@ public class ProtocolLibListener {
|
||||
return entity instanceof NPCHolder ? ((NPCHolder) entity).getNPC() : null;
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onNPCDespawn(NPCDespawnEvent event) {
|
||||
rotationTraits.remove(event.getNPC().getEntity().getEntityId());
|
||||
mirrorTraits.remove(event.getNPC().getEntity().getUniqueId());
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onNPCSpawn(NPCSpawnEvent event) {
|
||||
onSpawn(event);
|
||||
}
|
||||
|
||||
private void onSpawn(NPCEvent event) {
|
||||
if (event.getNPC().hasTrait(RotationTrait.class)) {
|
||||
rotationTraits.put(event.getNPC().getEntity().getEntityId(),
|
||||
event.getNPC().getTraitNullable(RotationTrait.class));
|
||||
}
|
||||
if (event.getNPC().hasTrait(MirrorTrait.class)
|
||||
&& event.getNPC().getOrAddTrait(MobType.class).getType() == EntityType.PLAYER) {
|
||||
mirrorTraits.put(event.getNPC().getEntity().getUniqueId(),
|
||||
event.getNPC().getTraitNullable(MirrorTrait.class));
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onTraitAdd(NPCAddTraitEvent event) {
|
||||
if (!event.getNPC().isSpawned())
|
||||
return;
|
||||
onSpawn(event);
|
||||
}
|
||||
|
||||
public enum PlayerTeleportFlag {
|
||||
X,
|
||||
Y,
|
||||
|
@ -158,10 +158,10 @@ public class AStarNavigationStrategy extends AbstractPathStrategy {
|
||||
@Override
|
||||
public float getCost(BlockSource source, PathPoint point) {
|
||||
Vector pos = point.getVector();
|
||||
Material above = source.getMaterialAt(pos.setY(pos.getY() + 1));
|
||||
Material above = source.getMaterialAt(pos.getBlockX(), pos.getBlockY() + 1, pos.getBlockZ());
|
||||
return params.avoidWater() && (MinecraftBlockExaminer.isLiquid(above)
|
||||
|| MinecraftBlockExaminer.isLiquidOrInLiquid(pos.toLocation(source.getWorld()).getBlock()))
|
||||
? 1F
|
||||
? 2F
|
||||
: 0F;
|
||||
}
|
||||
|
||||
|
@ -11,9 +11,9 @@ import net.citizensnpcs.api.trait.TraitName;
|
||||
@TraitName("mirrortrait")
|
||||
public class MirrorTrait extends Trait {
|
||||
@Persist
|
||||
private boolean enabled;
|
||||
private volatile boolean enabled;
|
||||
@Persist
|
||||
private boolean mirrorName;
|
||||
private volatile boolean mirrorName;
|
||||
|
||||
public MirrorTrait() {
|
||||
super("mirrortrait");
|
||||
|
@ -18,6 +18,7 @@ import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.persistence.Persist;
|
||||
import net.citizensnpcs.api.persistence.Persistable;
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
@ -32,7 +33,7 @@ public class RotationTrait extends Trait {
|
||||
private final RotationParams globalParameters = new RotationParams();
|
||||
private final RotationSession globalSession = new RotationSession(globalParameters);
|
||||
private final List<PacketRotationSession> packetSessions = Lists.newArrayList();
|
||||
private final Map<UUID, PacketRotationSession> packetSessionsByUUID = Maps.newHashMap();
|
||||
private final Map<UUID, PacketRotationSession> packetSessionsByUUID = Maps.newConcurrentMap();
|
||||
|
||||
public RotationTrait() {
|
||||
super("rotationtrait");
|
||||
@ -104,6 +105,9 @@ public class RotationTrait extends Trait {
|
||||
public void run() {
|
||||
if (!npc.isSpawned())
|
||||
return;
|
||||
if (npc.data().get(NPC.Metadata.RESET_PITCH_ON_TICK, false)) {
|
||||
NMS.setPitch(npc.getEntity(), 0);
|
||||
}
|
||||
|
||||
Set<PacketRotationSession> ran = Sets.newHashSet();
|
||||
for (Iterator<PacketRotationSession> itr = Iterables.concat(packetSessions, packetSessionsByUUID.values())
|
||||
@ -146,9 +150,9 @@ public class RotationTrait extends Trait {
|
||||
}
|
||||
|
||||
public static class PacketRotationSession {
|
||||
private boolean ended;
|
||||
private volatile boolean ended;
|
||||
private final RotationSession session;
|
||||
private PacketRotationTriple triple;
|
||||
private volatile PacketRotationTriple triple;
|
||||
|
||||
public PacketRotationSession(RotationSession session) {
|
||||
this.session = session;
|
||||
@ -201,9 +205,9 @@ public class RotationTrait extends Trait {
|
||||
}
|
||||
|
||||
private static class PacketRotationTriple extends EntityRotation {
|
||||
private float lastBodyYaw;
|
||||
private float lastHeadYaw;
|
||||
private float lastPitch;
|
||||
private volatile float lastBodyYaw;
|
||||
private volatile float lastHeadYaw;
|
||||
private volatile float lastPitch;
|
||||
|
||||
public PacketRotationTriple(Entity entity) {
|
||||
super(entity);
|
||||
|
@ -410,7 +410,8 @@ public class LinearWaypointProvider implements EnumerableWaypointProvider {
|
||||
if (showingMarkers) {
|
||||
markers.createMarker(element, element.getLocation().clone());
|
||||
}
|
||||
Messaging.sendTr(player, Messages.LINEAR_WAYPOINT_EDITOR_ADDED_WAYPOINT, formatLoc(at), idx);
|
||||
Messaging.sendTr(player, Messages.LINEAR_WAYPOINT_EDITOR_ADDED_WAYPOINT, formatLoc(at),
|
||||
waypoints.size());
|
||||
} else if (waypoints.size() > 0 && !event.getPlayer().isSneaking()) {
|
||||
event.setCancelled(true);
|
||||
|
||||
|
@ -7,7 +7,9 @@ import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -57,6 +59,7 @@ import net.citizensnpcs.npc.ai.MCNavigationStrategy.MCNavigator;
|
||||
import net.citizensnpcs.npc.ai.MCTargetStrategy.TargetNavigator;
|
||||
import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.citizensnpcs.npc.skin.SkinnableEntity;
|
||||
import net.citizensnpcs.trait.MirrorTrait;
|
||||
import net.citizensnpcs.trait.PacketNPC;
|
||||
import net.citizensnpcs.trait.versioned.CamelTrait.CamelPose;
|
||||
import net.citizensnpcs.trait.versioned.SnifferTrait.SnifferState;
|
||||
@ -640,8 +643,8 @@ public class NMS {
|
||||
BRIDGE.mount(entity, passenger);
|
||||
}
|
||||
|
||||
public static void onPlayerInfoAdd(Player player, Object source) {
|
||||
BRIDGE.onPlayerInfoAdd(player, source);
|
||||
public static void onPlayerInfoAdd(Player player, Object source, Function<UUID, MirrorTrait> mirrorTraits) {
|
||||
BRIDGE.onPlayerInfoAdd(player, source, mirrorTraits);
|
||||
}
|
||||
|
||||
public static InventoryView openAnvilInventory(Player player, Inventory inventory, String title) {
|
||||
|
@ -2,6 +2,8 @@ package net.citizensnpcs.util;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Sound;
|
||||
@ -40,6 +42,7 @@ import net.citizensnpcs.api.util.EntityDim;
|
||||
import net.citizensnpcs.npc.ai.MCNavigationStrategy.MCNavigator;
|
||||
import net.citizensnpcs.npc.ai.MCTargetStrategy.TargetNavigator;
|
||||
import net.citizensnpcs.npc.skin.SkinnableEntity;
|
||||
import net.citizensnpcs.trait.MirrorTrait;
|
||||
import net.citizensnpcs.trait.versioned.CamelTrait.CamelPose;
|
||||
import net.citizensnpcs.trait.versioned.SnifferTrait.SnifferState;
|
||||
import net.citizensnpcs.util.EntityPacketTracker.PacketAggregator;
|
||||
@ -134,7 +137,7 @@ public interface NMSBridge {
|
||||
|
||||
public void mount(Entity entity, Entity passenger);
|
||||
|
||||
public default void onPlayerInfoAdd(Player player, Object source) {
|
||||
public default void onPlayerInfoAdd(Player player, Object source, Function<UUID, MirrorTrait> mirrorTraits) {
|
||||
}
|
||||
|
||||
public InventoryView openAnvilInventory(Player player, Inventory anvil, String title);
|
||||
|
@ -15,7 +15,9 @@ import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -54,7 +56,6 @@ import org.bukkit.inventory.meta.SkullMeta;
|
||||
import org.bukkit.scoreboard.Team;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
@ -705,12 +706,7 @@ public class NMSImpl implements NMSBridge {
|
||||
Entity handle = getHandle(entity);
|
||||
if (handle == null || handle.passengers == null)
|
||||
return Lists.newArrayList();
|
||||
return Lists.transform(handle.passengers, new Function<Entity, org.bukkit.entity.Entity>() {
|
||||
@Override
|
||||
public org.bukkit.entity.Entity apply(Entity input) {
|
||||
return input.getBukkitEntity();
|
||||
}
|
||||
});
|
||||
return Lists.transform(handle.passengers, input -> input.getBukkitEntity());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -777,7 +773,7 @@ public class NMSImpl implements NMSBridge {
|
||||
}));
|
||||
Node last = list.size() > 0 ? list.get(list.size() - 1) : null;
|
||||
final Path path = new Path(list, last != null ? new BlockPos(last.x, last.y, last.z) : null, true);
|
||||
return getTargetNavigator(entity, params, (input) -> {
|
||||
return getTargetNavigator(entity, params, input -> {
|
||||
return input.moveTo(path, params.speed());
|
||||
});
|
||||
}
|
||||
@ -1177,7 +1173,7 @@ public class NMSImpl implements NMSBridge {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerInfoAdd(Player player, Object raw) {
|
||||
public void onPlayerInfoAdd(Player player, Object raw, Function<UUID, MirrorTrait> mirrorTraits) {
|
||||
ClientboundPlayerInfoUpdatePacket packet = (ClientboundPlayerInfoUpdatePacket) raw;
|
||||
List<ClientboundPlayerInfoUpdatePacket.Entry> list = Lists.newArrayList(packet.entries());
|
||||
boolean changed = false;
|
||||
@ -1185,9 +1181,10 @@ public class NMSImpl implements NMSBridge {
|
||||
ClientboundPlayerInfoUpdatePacket.Entry npcInfo = list.get(i);
|
||||
if (npcInfo == null)
|
||||
continue;
|
||||
NPC npc = CitizensAPI.getNPCRegistry().getByUniqueIdGlobal(npcInfo.profileId());
|
||||
if (npc == null || !npc.isSpawned())
|
||||
MirrorTrait trait = mirrorTraits.apply(npcInfo.profileId());
|
||||
if (trait == null || !trait.isMirroring(player)) {
|
||||
continue;
|
||||
}
|
||||
if (Setting.DISABLE_TABLIST.asBoolean() != npcInfo.listed()) {
|
||||
list.set(i,
|
||||
new ClientboundPlayerInfoUpdatePacket.Entry(npcInfo.profileId(), npcInfo.profile(),
|
||||
@ -1196,10 +1193,6 @@ public class NMSImpl implements NMSBridge {
|
||||
npcInfo.chatSession()));
|
||||
changed = true;
|
||||
}
|
||||
MirrorTrait trait = npc.getTraitNullable(MirrorTrait.class);
|
||||
if (trait == null || !trait.isMirroring(player)) {
|
||||
continue;
|
||||
}
|
||||
GameProfile playerProfile = NMS.getProfile(player);
|
||||
if (trait.mirrorName()) {
|
||||
list.set(i,
|
||||
|
@ -56,9 +56,9 @@ public class HorseSkeletonController extends MobEntityController {
|
||||
|
||||
public static class EntityHorseSkeletonNPC extends SkeletonHorse implements NPCHolder {
|
||||
private double baseMovementSpeed;
|
||||
|
||||
private final CitizensNPC npc;
|
||||
private boolean riding;
|
||||
|
||||
public EntityHorseSkeletonNPC(EntityType<? extends SkeletonHorse> types, Level level) {
|
||||
this(types, level, null);
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ import net.citizensnpcs.npc.ai.NPCHolder;
|
||||
import net.citizensnpcs.util.NMS;
|
||||
import net.citizensnpcs.util.Util;
|
||||
import net.minecraft.network.protocol.game.ClientboundAnimatePacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundRotateHeadPacket;
|
||||
import net.minecraft.server.level.ChunkMap;
|
||||
import net.minecraft.server.level.ChunkMap.TrackedEntity;
|
||||
import net.minecraft.server.level.ServerEntity;
|
||||
@ -69,6 +70,8 @@ public class CitizensEntityTracker extends ChunkMap.TrackedEntity {
|
||||
return;
|
||||
}
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> {
|
||||
NMSImpl.sendPacket(entityplayer.getBukkitEntity(),
|
||||
new ClientboundRotateHeadPacket(tracker, (byte) (tracker.getYHeadRot() * 256.0F / 360.0F)));
|
||||
NMSImpl.sendPacket(entityplayer.getBukkitEntity(), new ClientboundAnimatePacket(tracker, 0));
|
||||
NMS.sendTabListRemove(entityplayer.getBukkitEntity(), (Player) tracker.getBukkitEntity());
|
||||
}, Setting.TABLIST_REMOVE_PACKET_DELAY.asTicks());
|
||||
|
@ -14,7 +14,9 @@ import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -53,7 +55,6 @@ import org.bukkit.inventory.meta.SkullMeta;
|
||||
import org.bukkit.scoreboard.Team;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
@ -704,12 +705,7 @@ public class NMSImpl implements NMSBridge {
|
||||
Entity handle = getHandle(entity);
|
||||
if (handle == null || handle.passengers == null)
|
||||
return Lists.newArrayList();
|
||||
return Lists.transform(handle.passengers, new Function<Entity, org.bukkit.entity.Entity>() {
|
||||
@Override
|
||||
public org.bukkit.entity.Entity apply(Entity input) {
|
||||
return input.getBukkitEntity();
|
||||
}
|
||||
});
|
||||
return Lists.transform(handle.passengers, input -> input.getBukkitEntity());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1176,7 +1172,7 @@ public class NMSImpl implements NMSBridge {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerInfoAdd(Player player, Object raw) {
|
||||
public void onPlayerInfoAdd(Player player, Object raw, Function<UUID, MirrorTrait> mirrorTraits) {
|
||||
ClientboundPlayerInfoUpdatePacket packet = (ClientboundPlayerInfoUpdatePacket) raw;
|
||||
List<ClientboundPlayerInfoUpdatePacket.Entry> list = Lists.newArrayList(packet.entries());
|
||||
boolean changed = false;
|
||||
@ -1184,9 +1180,11 @@ public class NMSImpl implements NMSBridge {
|
||||
ClientboundPlayerInfoUpdatePacket.Entry npcInfo = list.get(i);
|
||||
if (npcInfo == null)
|
||||
continue;
|
||||
NPC npc = CitizensAPI.getNPCRegistry().getByUniqueIdGlobal(npcInfo.profileId());
|
||||
if (npc == null || !npc.isSpawned())
|
||||
|
||||
MirrorTrait trait = mirrorTraits.apply(npcInfo.profileId());
|
||||
if (trait == null || !trait.isMirroring(player)) {
|
||||
continue;
|
||||
}
|
||||
if (Setting.DISABLE_TABLIST.asBoolean() != npcInfo.listed()) {
|
||||
list.set(i,
|
||||
new ClientboundPlayerInfoUpdatePacket.Entry(npcInfo.profileId(), npcInfo.profile(),
|
||||
@ -1195,10 +1193,6 @@ public class NMSImpl implements NMSBridge {
|
||||
npcInfo.chatSession()));
|
||||
changed = true;
|
||||
}
|
||||
MirrorTrait trait = npc.getTraitNullable(MirrorTrait.class);
|
||||
if (trait == null || !trait.isMirroring(player)) {
|
||||
continue;
|
||||
}
|
||||
GameProfile playerProfile = NMS.getProfile(player);
|
||||
if (trait.mirrorName()) {
|
||||
list.set(i,
|
||||
|
Loading…
Reference in New Issue
Block a user