Workaround protocollib not supported listed boolean, fix dolphins moving while on ground, add /npc bossbar --range, add /npc create --nameplate --temporaryticks

This commit is contained in:
fullwall 2022-12-29 23:26:02 +08:00
parent c11da48fc2
commit a669a8a256
28 changed files with 253 additions and 65 deletions

View File

@ -151,8 +151,7 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
Storage saves = null;
String type = Setting.STORAGE_TYPE.asString();
if (type.equalsIgnoreCase("nbt")) {
saves = new NBTStorage(new File(folder + File.separator + Setting.STORAGE_FILE.asString()),
"Citizens NPC Storage");
saves = new NBTStorage(new File(folder, Setting.STORAGE_FILE.asString()), "Citizens NPC Storage");
}
if (saves == null) {
saves = new YamlStorage(new File(folder, Setting.STORAGE_FILE.asString()), "Citizens NPC Storage");

View File

@ -50,13 +50,16 @@ public class ProtocolLibListener {
} catch (Throwable t) {
VIA_ENABLED = false;
}
manager.addPacketListener(new PacketAdapter(plugin, ListenerPriority.MONITOR, Server.PLAYER_INFO) {
manager.addPacketListener(new PacketAdapter(plugin, ListenerPriority.HIGHEST, Server.PLAYER_INFO) {
@Override
public void onPacketSending(PacketEvent event) {
int version = VIA_ENABLED ? Via.getAPI().getPlayerVersion(event.getPlayer())
: manager.getProtocolVersion(event.getPlayer());
List<PlayerInfoData> list = event.getPacket().getPlayerInfoDataLists()
.readSafely(version < 761 ? 0 : 1);
if (version >= 761) {
NMS.onPlayerInfoAdd(event.getPlayer(), event.getPacket().getHandle());
return;
}
List<PlayerInfoData> list = event.getPacket().getPlayerInfoDataLists().readSafely(0);
if (list == null)
return;
boolean changed = false;
@ -86,7 +89,7 @@ public class ProtocolLibListener {
changed = true;
}
if (changed) {
event.getPacket().getPlayerInfoDataLists().write(version < 761 ? 0 : 1, list);
event.getPacket().getPlayerInfoDataLists().write(0, list);
}
}
});

View File

@ -21,11 +21,11 @@ public class StoredShops {
this.storage = storage;
}
public void deleteShop(String name) {
if (globalShops.containsKey(name)) {
globalShops.remove(name);
public void deleteShop(NPCShop shop) {
if (npcShops.values().contains(shop)) {
npcShops.values().remove(shop);
} else {
npcShops.remove(name);
globalShops.values().remove(shop);
}
}

View File

@ -428,7 +428,8 @@ public class NPCCommands {
min = 1,
flags = "lrpos",
permission = "citizens.npc.command")
public void command(CommandContext args, CommandSender sender, NPC npc, @Flag("permissions") String permissions,
public void command(CommandContext args, CommandSender sender, NPC npc,
@Flag(value = { "permissions", "permission" }) String permissions,
@Flag(value = "cooldown", defValue = "0") int cooldown,
@Flag(value = "gcooldown", defValue = "0") int gcooldown, @Flag(value = "n", defValue = "-1") int n,
@Flag(value = "delay", defValue = "0") int delay,
@ -455,7 +456,7 @@ public class NPCCommands {
if (permissions != null) {
perms.addAll(Arrays.asList(permissions.split(",")));
}
if (command.startsWith("npc select")) {
if (command.toLowerCase().startsWith("npc select")) {
throw new CommandException("npc select not currently supported within commands. Use --id <id> instead");
}
try {
@ -620,7 +621,7 @@ public class NPCCommands {
@Command(
aliases = { "npc" },
usage = "create [name] ((-b(aby),u(nspawned),s(ilent),t(emporary),c(enter)) --at [x:y:z:world] --type [type] --item (item) --trait ['trait1, trait2...'] --registry [registry name])",
usage = "create [name] ((-b(aby),u(nspawned),s(ilent),t(emporary),c(enter)) --at [x:y:z:world] --type [type] --item (item) --trait ['trait1, trait2...'] --nameplate [true|false|hover] --temporaryticks [ticks] --registry [registry name])",
desc = "Create a new NPC",
flags = "bustc",
modifiers = { "create" },
@ -629,8 +630,9 @@ public class NPCCommands {
@Requirements
public void create(CommandContext args, CommandSender sender, NPC npc, @Flag("at") Location at,
@Flag(value = "type", defValue = "PLAYER") EntityType type, @Flag("trait") String traits,
@Flag("item") String item, @Flag("template") String templateName, @Flag("registry") String registryName)
throws CommandException {
@Flag(value = "nameplate", completions = { "true", "false", "hover" }) String nameplate,
@Flag("temporaryticks") Integer temporaryTicks, @Flag("item") String item,
@Flag("template") String templateName, @Flag("registry") String registryName) throws CommandException {
String name = args.getJoinedStrings(1).trim();
if (args.hasValueFlag("type")) {
if (type == null) {
@ -662,7 +664,7 @@ public class NPCCommands {
}
}
if (args.hasFlag('t')) {
if (args.hasFlag('t') || temporaryTicks != null) {
registry = temporaryRegistry;
}
@ -690,11 +692,24 @@ public class NPCCommands {
npc.data().set(NPC.SILENT_METADATA, true);
}
// Initialize necessary traits
if (nameplate != null) {
npc.data().set(NPC.Metadata.NAMEPLATE_VISIBLE,
nameplate.equalsIgnoreCase("hover") ? nameplate.toLowerCase() : Boolean.parseBoolean(nameplate));
}
if (!Setting.SERVER_OWNS_NPCS.asBoolean()) {
npc.getOrAddTrait(Owner.class).setOwner(sender);
}
if (temporaryTicks != null) {
final NPC temp = npc;
Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), () -> {
if (temporaryRegistry.getByUniqueId(temp.getUniqueId()) == temp) {
temp.destroy();
}
}, temporaryTicks);
}
npc.getOrAddTrait(MobType.class).setType(type);
Location spawnLoc = null;
@ -1656,6 +1671,7 @@ public class NPCCommands {
old = old.equals("hover") ? "true" : "" + !Boolean.parseBoolean(old);
}
npc.data().setPersistent(NPC.Metadata.NAMEPLATE_VISIBLE, old);
npc.data().set(NPC.Metadata.FORCE_PACKET_UPDATE, true);
Messaging.sendTr(sender, Messages.NAMEPLATE_VISIBILITY_SET, old);
}
@ -2376,11 +2392,15 @@ public class NPCCommands {
shop = shops.getShop(args.getString(2).toLowerCase());
}
if (action.equalsIgnoreCase("delete")) {
if (args.argsLength() != 3)
if (args.argsLength() != 3 || shop == null)
throw new CommandUsageException();
shops.deleteShop(args.getString(2).toLowerCase());
if (!sender.hasPermission("citizens.admin") && (!sender.hasPermission("citizens.npc.shop.edit")
|| !sender.hasPermission("citizens.npc.shop.edit." + shop.getName())))
throw new NoPermissionsException();
shops.deleteShop(shop);
return;
}
if (shop == null)
throw new CommandUsageException();
if (action.equalsIgnoreCase("edit")) {

View File

@ -464,8 +464,8 @@ public class CitizensNPC extends AbstractNPC {
boolean isLiving = getEntity() instanceof LivingEntity;
int packetUpdateDelay = data().get(NPC.Metadata.PACKET_UPDATE_DELAY, Setting.PACKET_UPDATE_DELAY.asInt());
if (updateCounter++ > packetUpdateDelay) {
if (Setting.KEEP_CHUNKS_LOADED.asBoolean()) {
if (updateCounter++ > packetUpdateDelay || data().has(NPC.Metadata.FORCE_PACKET_UPDATE)) {
if (data().get(NPC.KEEP_CHUNK_LOADED_METADATA, Setting.KEEP_CHUNKS_LOADED.asBoolean())) {
ChunkCoord currentCoord = new ChunkCoord(getStoredLocation());
if (!currentCoord.equals(cachedCoord)) {
resetCachedCoord();
@ -478,6 +478,7 @@ public class CitizensNPC extends AbstractNPC {
updateScoreboard();
}
updateCounter = 0;
data().remove(NPC.Metadata.FORCE_PACKET_UPDATE);
}
updateCustomNameVisibility();

View File

@ -206,7 +206,9 @@ public class CommandTrait extends Trait {
}
private String describe(NPCCommand command) {
String output = "<br> - " + command.command + " [" + StringHelper.wrap(command.cooldown)
String output = "<br> - " + command.command + " ["
+ StringHelper.wrap(
command.cooldown != 0 ? command.cooldown : Setting.NPC_COMMAND_GLOBAL_COMMAND_DELAY.asLong())
+ "s] [<click:run_command:/npc cmd remove " + command.id
+ "><hover:show_text:Remove this command><red>-</hover></click>]";
if (command.globalCooldown > 0) {
@ -649,7 +651,8 @@ public class CommandTrait extends Trait {
long currentTimeSec = System.currentTimeMillis() / 1000;
String commandKey = command.getEncodedKey();
if (lastUsed.containsKey(commandKey)) {
long deadline = ((Number) lastUsed.get(commandKey)).longValue() + command.cooldown + globalDelay;
long deadline = ((Number) lastUsed.get(commandKey)).longValue()
+ (command.cooldown != 0 ? command.cooldown : globalDelay);
if (currentTimeSec < deadline) {
long seconds = deadline - currentTimeSec;
trait.sendErrorMessage(player, CommandTraitError.ON_COOLDOWN,
@ -693,8 +696,8 @@ public class CommandTrait extends Trait {
String commandKey = command.getEncodedKey();
commandKeys.add(commandKey);
Number number = lastUsed.get(commandKey);
if (number != null && number.longValue() + command.cooldown
+ Setting.NPC_COMMAND_GLOBAL_COMMAND_DELAY.asLong() <= currentTimeSec) {
if (number != null && number.longValue() + (command.cooldown != 0 ? command.cooldown
: Setting.NPC_COMMAND_GLOBAL_COMMAND_DELAY.asLong()) <= currentTimeSec) {
lastUsed.remove(commandKey);
}
if (globalCooldowns != null) {

View File

@ -80,7 +80,7 @@ public class ShopTrait extends Trait {
@Override
public void onRemove() {
shops.deleteShop(npc.getUniqueId().toString());
shops.deleteShop(getDefaultShop());
}
public void onRightClick(Player player) {

View File

@ -37,17 +37,19 @@ import net.citizensnpcs.util.Util;
@TraitName("bossbar")
public class BossBarTrait extends Trait {
private BossBar barCache;
@Persist("color")
@Persist
private BarColor color = BarColor.PURPLE;
@Persist("flags")
@Persist
private List<BarFlag> flags = Lists.newArrayList();
@Persist("style")
@Persist
private int range = -1;
@Persist
private BarStyle style = BarStyle.SOLID;
@Persist("title")
@Persist
private String title = "";
@Persist("track")
@Persist
private String track;
@Persist("visible")
@Persist
private boolean visible = true;
public BossBarTrait() {
@ -72,6 +74,10 @@ public class BossBarTrait extends Trait {
return flags;
}
public int getRange() {
return range;
}
public BarStyle getStyle() {
return style;
}
@ -99,11 +105,11 @@ public class BossBarTrait extends Trait {
@Override
public void onDespawn() {
if (barCache != null) {
barCache.removeAll();
barCache.hide();
barCache = null;
}
if (barCache == null)
return;
barCache.removeAll();
barCache.hide();
barCache = null;
}
@Override
@ -159,7 +165,7 @@ public class BossBarTrait extends Trait {
if (barCache != null) {
barCache.removeAll();
for (Player player : CitizensAPI.getLocationLookup().getNearbyPlayers(npc.getEntity().getLocation(),
Setting.BOSSBAR_RANGE.asInt())) {
range > 0 ? range : Setting.BOSSBAR_RANGE.asInt())) {
barCache.addPlayer(player);
}
}
@ -177,6 +183,10 @@ public class BossBarTrait extends Trait {
this.flags = flags;
}
public void setRange(int range) {
this.range = range;
}
public void setStyle(BarStyle style) {
this.style = style;
}
@ -195,7 +205,7 @@ public class BossBarTrait extends Trait {
@Command(
aliases = { "npc" },
usage = "bossbar --style [style] --color [color] --title [title] --visible [visible] --flags [flags] --track [health | placeholder]",
usage = "bossbar --style [style] --color [color] --title [title] --visible [visible] --flags [flags] --track [health | placeholder] --range [range]",
desc = "Edit bossbar properties",
modifiers = { "bossbar" },
min = 1,
@ -203,7 +213,8 @@ public class BossBarTrait extends Trait {
@Requirements(selected = true, ownership = true)
public static void bossbar(CommandContext args, CommandSender sender, NPC npc, @Flag("style") BarStyle style,
@Flag("track") String track, @Flag("color") BarColor color, @Flag("visible") Boolean visible,
@Flag("title") String title, @Flag("flags") String flags) throws CommandException {
@Flag("range") Integer range, @Flag("title") String title, @Flag("flags") String flags)
throws CommandException {
BossBarTrait trait = npc.getOrAddTrait(BossBarTrait.class);
if (style != null) {
trait.setStyle(style);
@ -220,6 +231,9 @@ public class BossBarTrait extends Trait {
if (visible != null) {
trait.setVisible(visible);
}
if (range != null) {
trait.setRange(range);
}
if (flags != null) {
List<BarFlag> parsed = Lists.newArrayList();
for (String s : Splitter.on(',').omitEmptyStrings().trimResults().split(flags)) {

View File

@ -470,6 +470,10 @@ public class NMS {
BRIDGE.mount(entity, passenger);
}
public static void onPlayerInfoAdd(Player player, Object source) {
BRIDGE.onPlayerInfoAdd(player, source);
}
public static InventoryView openAnvilInventory(Player player, Inventory inventory, String title) {
return BRIDGE.openAnvilInventory(player, inventory, title);
}

View File

@ -121,6 +121,9 @@ public interface NMSBridge {
public void mount(Entity entity, Entity passenger);
public default void onPlayerInfoAdd(Player player, Object source) {
}
public InventoryView openAnvilInventory(Player player, Inventory anvil, String title);
public void openHorseScreen(Tameable horse, Player equipper);
@ -145,9 +148,9 @@ public interface NMSBridge {
public void sendRotationNearby(Entity from, float bodyYaw, float headYaw, float pitch);
public boolean sendTabListAdd(Player recipient, Player listPlayer);
public boolean sendTabListAdd(Player recipient, Player listPlayer);;
public void sendTabListRemove(Player recipient, Collection<? extends SkinnableEntity> skinnableNPCs);;
public void sendTabListRemove(Player recipient, Collection<? extends SkinnableEntity> skinnableNPCs);
public void sendTabListRemove(Player recipient, Player listPlayer);
@ -165,13 +168,13 @@ public interface NMSBridge {
public void setCustomName(Entity entity, Object component, String string);
public void setDestination(Entity entity, double x, double y, double z, float speed);
public void setDestination(Entity entity, double x, double y, double z, float speed);;
public void setEndermanAngry(Enderman enderman, boolean angry);;
public void setEndermanAngry(Enderman enderman, boolean angry);
public void setHeadYaw(Entity entity, float yaw);
public void setKnockbackResistance(LivingEntity entity, double d);
public void setKnockbackResistance(LivingEntity entity, double d);;
public default void setLyingDown(Entity cat, boolean lying) {
throw new UnsupportedOperationException();
@ -179,15 +182,15 @@ public interface NMSBridge {
public void setNavigationTarget(Entity handle, Entity target, float speed);;
public void setNoGravity(Entity entity, boolean nogravity);;
public void setNoGravity(Entity entity, boolean nogravity);
public default void setPandaSitting(Entity entity, boolean sitting) {
throw new UnsupportedOperationException();
}
};
public default void setPeekShulker(Entity entity, int peek) {
throw new UnsupportedOperationException();
};
}
public default void setPiglinDancing(Entity entity, boolean dancing) {
throw new UnsupportedOperationException();
@ -233,5 +236,5 @@ public interface NMSBridge {
public void updateNavigationWorld(Entity entity, World world);
public void updatePathfindingRange(NPC npc, float pathfindingRange);
public void updatePathfindingRange(NPC npc, float pathfindingRange);;
}

View File

@ -53,6 +53,8 @@ public class DolphinController extends MobEntityController {
}
public static class EntityDolphinNPC extends EntityDolphin implements NPCHolder {
private boolean inProtectedTick;
private final CitizensNPC npc;
public EntityDolphinNPC(World world) {
@ -97,6 +99,11 @@ public class DolphinController extends MobEntityController {
}
}
@Override
public boolean ap() {
return inProtectedTick ? true : super.ap();
}
@Override
public boolean b(Tag<FluidType> tag) {
double mx = motX;
@ -210,7 +217,11 @@ public class DolphinController extends MobEntityController {
@Override
public void tick() {
if (npc != null && npc.isProtected()) {
inProtectedTick = true;
}
super.tick();
inProtectedTick = false;
if (npc != null) {
npc.update();
}

View File

@ -56,6 +56,8 @@ public class DolphinController extends MobEntityController {
}
public static class EntityDolphinNPC extends EntityDolphin implements NPCHolder {
private boolean inProtectedTick;
private final CitizensNPC npc;
public EntityDolphinNPC(EntityTypes<? extends EntityDolphin> types, World world) {
@ -89,6 +91,11 @@ public class DolphinController extends MobEntityController {
}
}
@Override
public boolean au() {
return inProtectedTick ? true : super.au();
}
@Override
public void b(float f, float f1) {
if (npc == null || !npc.isFlyable()) {
@ -219,7 +226,11 @@ public class DolphinController extends MobEntityController {
@Override
public void tick() {
if (npc != null && npc.isProtected()) {
inProtectedTick = true;
}
super.tick();
inProtectedTick = false;
if (npc != null) {
npc.update();
}

View File

@ -53,7 +53,6 @@ public class TraderLlamaController extends MobEntityController {
public static class EntityTraderLlamaNPC extends EntityLlamaTrader implements NPCHolder {
boolean calledNMSHeight = false;
private final CitizensNPC npc;
public EntityTraderLlamaNPC(EntityTypes<? extends EntityLlamaTrader> types, World world) {

View File

@ -1,5 +1,6 @@
package net.citizensnpcs.nms.v1_14_R1.entity;
import java.lang.invoke.MethodHandle;
import java.util.List;
import java.util.TreeMap;
@ -16,6 +17,7 @@ import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_14_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.server.v1_14_R1.BlockPosition;
import net.minecraft.server.v1_14_R1.DamageSource;
@ -49,9 +51,7 @@ public class WanderingTraderController extends MobEntityController {
public static class EntityWanderingTraderNPC extends EntityVillagerTrader implements NPCHolder {
private TreeMap<?, ?> behaviorMap;
private boolean blockingATrade;
private boolean blockTrades = true;
boolean calledNMSHeight = false;
private final CitizensNPC npc;
@ -249,6 +249,12 @@ public class WanderingTraderController extends MobEntityController {
}
super.mobTick();
if (npc != null) {
try {
if (bB != null) {
bB.invoke(this, 10); // DespawnDelay
}
} catch (Throwable e) {
}
npc.update();
}
}
@ -271,6 +277,8 @@ public class WanderingTraderController extends MobEntityController {
public void setBlockTrades(boolean blocked) {
this.blockTrades = blocked;
}
private static final MethodHandle bB = NMS.getSetter(EntityVillagerTrader.class, "bB");
}
public static class WanderingTraderNPC extends CraftWanderingTrader implements NPCHolder {

View File

@ -50,6 +50,8 @@ public class DolphinController extends MobEntityController {
}
public static class EntityDolphinNPC extends EntityDolphin implements NPCHolder {
private boolean inProtectedTick;
private final CitizensNPC npc;
private ControllerMove oldMoveController;
@ -86,6 +88,11 @@ public class DolphinController extends MobEntityController {
}
}
@Override
public boolean ay() {
return inProtectedTick ? true : super.ay();
}
@Override
public boolean b(float f, float f1) {
if (npc == null || !npc.isFlyable()) {
@ -217,7 +224,11 @@ public class DolphinController extends MobEntityController {
@Override
public void tick() {
if (npc != null && npc.isProtected()) {
inProtectedTick = true;
}
super.tick();
inProtectedTick = false;
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
if (npc.useMinecraftAI() && this.moveController != this.oldMoveController) {

View File

@ -54,7 +54,6 @@ public class TraderLlamaController extends MobEntityController {
public static class EntityTraderLlamaNPC extends EntityLlamaTrader implements NPCHolder {
boolean calledNMSHeight = false;
private final CitizensNPC npc;
public EntityTraderLlamaNPC(EntityTypes<? extends EntityLlamaTrader> types, World world) {

View File

@ -1,5 +1,6 @@
package net.citizensnpcs.nms.v1_15_R1.entity;
import java.lang.invoke.MethodHandle;
import java.util.List;
import org.bukkit.Bukkit;
@ -16,6 +17,7 @@ import net.citizensnpcs.nms.v1_15_R1.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_15_R1.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.server.v1_15_R1.BlockPosition;
import net.minecraft.server.v1_15_R1.DamageSource;
@ -49,9 +51,7 @@ public class WanderingTraderController extends MobEntityController {
public static class EntityWanderingTraderNPC extends EntityVillagerTrader implements NPCHolder {
private boolean blockingATrade;
private boolean blockTrades = true;
boolean calledNMSHeight = false;
private final CitizensNPC npc;
@ -244,6 +244,12 @@ public class WanderingTraderController extends MobEntityController {
}
super.mobTick();
if (npc != null) {
try {
if (by != null) {
by.invoke(this, 10); // DespawnDelay
}
} catch (Throwable e) {
}
npc.update();
}
}
@ -266,6 +272,8 @@ public class WanderingTraderController extends MobEntityController {
public void setBlockTrades(boolean blocked) {
this.blockTrades = blocked;
}
private static final MethodHandle by = NMS.getSetter(EntityVillagerTrader.class, "by");
}
public static class WanderingTraderNPC extends CraftWanderingTrader implements ForwardingNPCHolder {

View File

@ -50,6 +50,8 @@ public class DolphinController extends MobEntityController {
}
public static class EntityDolphinNPC extends EntityDolphin implements NPCHolder {
private boolean inProtectedTick;
private final CitizensNPC npc;
private ControllerMove oldMoveController;
@ -96,6 +98,11 @@ public class DolphinController extends MobEntityController {
return res;
}
@Override
public boolean aG() {
return inProtectedTick ? true : super.aG();
}
@Override
public boolean b(float f, float f1) {
if (npc == null || !npc.isFlyable()) {
@ -217,7 +224,11 @@ public class DolphinController extends MobEntityController {
@Override
public void tick() {
if (npc != null && npc.isProtected()) {
inProtectedTick = true;
}
super.tick();
inProtectedTick = false;
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
if (npc.useMinecraftAI() && this.moveController != this.oldMoveController) {

View File

@ -54,7 +54,6 @@ public class TraderLlamaController extends MobEntityController {
public static class EntityTraderLlamaNPC extends EntityLlamaTrader implements NPCHolder {
boolean calledNMSHeight = false;
private final CitizensNPC npc;
public EntityTraderLlamaNPC(EntityTypes<? extends EntityLlamaTrader> types, World world) {

View File

@ -1,5 +1,6 @@
package net.citizensnpcs.nms.v1_16_R3.entity;
import java.lang.invoke.MethodHandle;
import java.util.List;
import org.bukkit.Bukkit;
@ -16,6 +17,7 @@ import net.citizensnpcs.nms.v1_16_R3.util.ForwardingNPCHolder;
import net.citizensnpcs.nms.v1_16_R3.util.NMSImpl;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.NMS;
import net.citizensnpcs.util.Util;
import net.minecraft.server.v1_16_R3.BlockPosition;
import net.minecraft.server.v1_16_R3.DamageSource;
@ -246,6 +248,12 @@ public class WanderingTraderController extends MobEntityController {
}
super.mobTick();
if (npc != null) {
try {
if (bq != null) {
bq.invoke(this, 10); // DespawnDelay
}
} catch (Throwable e) {
}
npc.update();
}
}
@ -268,6 +276,8 @@ public class WanderingTraderController extends MobEntityController {
public void setBlockTrades(boolean blocked) {
this.blockTrades = blocked;
}
private static final MethodHandle bq = NMS.getSetter(EntityVillagerTrader.class, "bq");
}
public static class WanderingTraderNPC extends CraftWanderingTrader implements ForwardingNPCHolder {

View File

@ -49,8 +49,8 @@ public class DolphinController extends MobEntityController {
}
public static class EntityDolphinNPC extends Dolphin implements NPCHolder {
private boolean inProtectedTick;
private final CitizensNPC npc;
private MoveControl oldMoveController;
public EntityDolphinNPC(EntityType<? extends Dolphin> types, Level level) {
@ -139,6 +139,11 @@ public class DolphinController extends MobEntityController {
return npc;
}
@Override
public boolean isInWaterRainOrBubble() {
return inProtectedTick ? true : super.isInWaterRainOrBubble();
}
@Override
public boolean isLeashed() {
if (npc == null)
@ -195,7 +200,11 @@ public class DolphinController extends MobEntityController {
@Override
public void tick() {
if (npc != null && npc.isProtected()) {
inProtectedTick = true;
}
super.tick();
inProtectedTick = false;
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
if (npc.useMinecraftAI() && this.moveControl != this.oldMoveController) {

View File

@ -51,7 +51,6 @@ public class TraderLlamaController extends MobEntityController {
public static class EntityTraderLlamaNPC extends TraderLlama implements NPCHolder {
boolean calledNMSHeight = false;
private final CitizensNPC npc;
public EntityTraderLlamaNPC(EntityType<? extends TraderLlama> types, Level level) {

View File

@ -100,6 +100,7 @@ public class WanderingTraderController extends MobEntityController {
}
super.customServerAiStep();
if (npc != null) {
setDespawnDelay(10);
npc.update();
}
}

View File

@ -49,8 +49,8 @@ public class DolphinController extends MobEntityController {
}
public static class EntityDolphinNPC extends Dolphin implements NPCHolder {
private boolean inProtectedTick;
private final CitizensNPC npc;
private MoveControl oldMoveController;
public EntityDolphinNPC(EntityType<? extends Dolphin> types, Level level) {
@ -139,6 +139,11 @@ public class DolphinController extends MobEntityController {
return npc;
}
@Override
public boolean isInWaterRainOrBubble() {
return inProtectedTick ? true : super.isInWaterRainOrBubble();
}
@Override
public boolean isLeashed() {
if (npc == null)
@ -203,7 +208,11 @@ public class DolphinController extends MobEntityController {
@Override
public void tick() {
if (npc != null && npc.isProtected()) {
inProtectedTick = true;
}
super.tick();
inProtectedTick = false;
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
if (npc.useMinecraftAI() && this.moveControl != this.oldMoveController) {

View File

@ -48,9 +48,7 @@ public class WanderingTraderController extends MobEntityController {
public static class EntityWanderingTraderNPC extends WanderingTrader implements NPCHolder {
private boolean blockingATrade;
private boolean blockTrades = true;
boolean calledNMSHeight = false;
private final CitizensNPC npc;
@ -100,6 +98,7 @@ public class WanderingTraderController extends MobEntityController {
}
super.customServerAiStep();
if (npc != null) {
setDespawnDelay(10);
npc.update();
}
}

View File

@ -50,8 +50,8 @@ public class DolphinController extends MobEntityController {
}
public static class EntityDolphinNPC extends Dolphin implements NPCHolder {
private boolean inProtectedTick;
private final CitizensNPC npc;
private MoveControl oldMoveController;
public EntityDolphinNPC(EntityType<? extends Dolphin> types, Level level) {
@ -140,6 +140,11 @@ public class DolphinController extends MobEntityController {
return npc;
}
@Override
public boolean isInWaterRainOrBubble() {
return inProtectedTick ? true : super.isInWaterRainOrBubble();
}
@Override
public boolean isLeashed() {
return NMSImpl.isLeashed(this, super.isLeashed());
@ -196,7 +201,11 @@ public class DolphinController extends MobEntityController {
@Override
public void tick() {
if (npc != null && npc.isProtected()) {
inProtectedTick = true;
}
super.tick();
inProtectedTick = false;
if (npc != null) {
NMSImpl.updateMinecraftAIState(npc, this);
if (npc.useMinecraftAI() && this.moveControl != this.oldMoveController) {

View File

@ -49,7 +49,6 @@ public class WanderingTraderController extends MobEntityController {
public static class EntityWanderingTraderNPC extends WanderingTrader implements NPCHolder {
private boolean blockingATrade;
private boolean blockTrades = true;
boolean calledNMSHeight = false;
private final CitizensNPC npc;
@ -100,6 +99,7 @@ public class WanderingTraderController extends MobEntityController {
}
super.customServerAiStep();
if (npc != null) {
setDespawnDelay(10);
npc.update();
}
}

View File

@ -60,6 +60,7 @@ import com.mojang.authlib.GameProfile;
import com.mojang.authlib.GameProfileRepository;
import com.mojang.authlib.HttpAuthenticationService;
import com.mojang.authlib.minecraft.MinecraftSessionService;
import com.mojang.authlib.properties.Property;
import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
import com.mojang.authlib.yggdrasil.YggdrasilMinecraftSessionService;
import com.mojang.authlib.yggdrasil.response.MinecraftProfilePropertiesResponse;
@ -217,6 +218,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.RotationTrait;
import net.citizensnpcs.trait.versioned.AllayTrait;
import net.citizensnpcs.trait.versioned.AxolotlTrait;
@ -1083,6 +1085,50 @@ public class NMSImpl implements NMSBridge {
NMSImpl.getHandle(passenger).startRiding(NMSImpl.getHandle(entity));
}
@Override
public void onPlayerInfoAdd(Player player, Object raw) {
ClientboundPlayerInfoUpdatePacket packet = (ClientboundPlayerInfoUpdatePacket) raw;
List<ClientboundPlayerInfoUpdatePacket.Entry> list = Lists.newArrayList(packet.entries());
boolean changed = false;
for (int i = 0; i < list.size(); i++) {
ClientboundPlayerInfoUpdatePacket.Entry data = list.get(i);
if (data == null)
continue;
if (data.profileId().version() != 2)
continue;
NPC npc = CitizensAPI.getNPCRegistry().getByUniqueIdGlobal(data.profileId());
if (npc == null || !npc.isSpawned())
continue;
if (Setting.DISABLE_TABLIST.asBoolean() != data.listed()) {
list.set(i,
new ClientboundPlayerInfoUpdatePacket.Entry(data.profileId(), data.profile(),
Setting.DISABLE_TABLIST.asBoolean(), data.latency(), data.gameMode(),
Setting.DISABLE_TABLIST.asBoolean() ? data.displayName() : Component.empty(),
data.chatSession()));
changed = true;
}
MirrorTrait trait = npc.getTraitNullable(MirrorTrait.class);
if (trait == null || !trait.isMirroring(player))
continue;
GameProfile profile = NMS.getProfile(player);
Collection<Property> textures = profile.getProperties().get("textures");
if (textures == null || textures.size() == 0)
continue;
data.profile().getProperties().clear();
for (String key : profile.getProperties().keySet()) {
data.profile().getProperties().putAll(key, profile.getProperties().get(key));
}
changed = true;
}
if (changed) {
try {
PLAYER_INFO_ENTRIES_LIST.invoke(packet, list);
} catch (Throwable e) {
e.printStackTrace();
}
}
}
@Override
public InventoryView openAnvilInventory(Player player, Inventory anvil, String title) {
ServerPlayer handle = (ServerPlayer) getHandle(player);
@ -2368,6 +2414,7 @@ public class NMSImpl implements NMSBridge {
private static final MethodHandle BEHAVIOR_TREE_MAP = NMS.getGetter(Brain.class, "f");
private static final MethodHandle BUKKITENTITY_FIELD_SETTER = NMS.getSetter(Entity.class, "bukkitEntity");
private static final MethodHandle CHUNKMAP_UPDATE_PLAYER_STATUS = NMS.getMethodHandle(ChunkMap.class, "a", true,
ServerPlayer.class, boolean.class);
private static final Map<Class<?>, net.minecraft.world.entity.EntityType<?>> CITIZENS_ENTITY_TYPES = Maps
@ -2407,8 +2454,9 @@ public class NMSImpl implements NMSBridge {
public static final Location PACKET_CACHE_LOCATION = new Location(null, 0, 0, 0);
private static final MethodHandle PLAYER_CHUNK_MAP_VIEW_DISTANCE_GETTER = NMS.getGetter(ChunkMap.class, "P");
private static final MethodHandle PLAYER_CHUNK_MAP_VIEW_DISTANCE_SETTER = NMS.getSetter(ChunkMap.class, "P");
private static final MethodHandle PLAYERINFO_ENTRIES = NMS.getFinalSetter(ClientboundPlayerInfoUpdatePacket.class,
"b");
private static final MethodHandle PLAYER_INFO_ENTRIES_LIST = NMS
.getFinalSetter(ClientboundPlayerInfoUpdatePacket.class, "b");
private static final MethodHandle PLAYERINFO_ENTRIES = PLAYER_INFO_ENTRIES_LIST;
private static MethodHandle PORTAL_ENTRANCE_POS_GETTER = NMS.getGetter(Entity.class, "ai");
private static MethodHandle PORTAL_ENTRANCE_POS_SETTER = NMS.getSetter(Entity.class, "ai");
private static final MethodHandle PUFFERFISH_C = NMS.getSetter(Pufferfish.class, "bX");