diff --git a/pom.xml b/pom.xml
index 816e349..44c58cb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
com.smallaswater
RsNPC
- 2.4.2
+ 2.4.3-SNAPSHOT
RsNPC
RsNPC -- NPC plugin for Nukkit
diff --git a/src/main/java/com/smallaswater/npc/RsNPC.java b/src/main/java/com/smallaswater/npc/RsNPC.java
index f041184..617f488 100644
--- a/src/main/java/com/smallaswater/npc/RsNPC.java
+++ b/src/main/java/com/smallaswater/npc/RsNPC.java
@@ -101,8 +101,6 @@ public void onLoad() {
@Override
public void onEnable() {
- this.loadLanguage();
-
switch (GameCoreDownload.checkAndDownload()) {
case 1:
Server.getInstance().getPluginManager().disablePlugin(this);
@@ -114,6 +112,8 @@ public void onEnable() {
break;
}
+ this.loadLanguage();
+
try {
if (Server.getInstance().getPluginManager().getPlugin("AutoUpData") != null) {
if (AutoData.defaultUpDataByMaven(this, this.getFile(), "com.smallaswater", "RsNPC", null)) {
@@ -224,6 +224,7 @@ private void loadNpcs() {
* 加载内置皮肤
*/
private void loadPrivateSkins() {
+ this.skins.put("private_steve", DEFAULT_SKIN);
String[] skins = { "阳", "糖菲_slim", "玉茗_slim" };
for (String skinName : skins) {
try {
diff --git a/src/main/java/com/smallaswater/npc/command/sub/CreateSubCommand.java b/src/main/java/com/smallaswater/npc/command/sub/CreateSubCommand.java
index b5ed46c..1dd1340 100644
--- a/src/main/java/com/smallaswater/npc/command/sub/CreateSubCommand.java
+++ b/src/main/java/com/smallaswater/npc/command/sub/CreateSubCommand.java
@@ -65,11 +65,9 @@ public boolean execute(CommandSender sender, String label, String[] args) {
}
this.rsNPC.getNpcs().put(name, rsNpcConfig);
rsNpcConfig.checkEntity();
- //玄学解决首次生成不显示的问题
- Server.getInstance().getScheduler().scheduleDelayedTask(this.rsNPC, () -> {
- rsNpcConfig.getEntityRsNpc().close();
- rsNpcConfig.checkEntity();
- }, 20);
+ //修复首次生成不显示的问题 通过重复生成实体解决nk未能及时发送PlayerListPacket的问题
+ Server.getInstance().getScheduler().scheduleDelayedTask(this.rsNPC, () -> rsNpcConfig.getEntityRsNpc().close(), 20);
+ Server.getInstance().getScheduler().scheduleDelayedTask(this.rsNPC, rsNpcConfig::checkEntity, 40);
sender.sendMessage(this.rsNPC.getLanguage().translateString("tips.npcCreateSuccess", name));
} else {
sender.sendMessage(this.rsNPC.getLanguage().translateString("tips.nameRequired"));
diff --git a/src/main/java/com/smallaswater/npc/data/RsNpcConfig.java b/src/main/java/com/smallaswater/npc/data/RsNpcConfig.java
index 9e88743..f63b9bf 100644
--- a/src/main/java/com/smallaswater/npc/data/RsNpcConfig.java
+++ b/src/main/java/com/smallaswater/npc/data/RsNpcConfig.java
@@ -17,7 +17,6 @@
import com.smallaswater.npc.utils.Utils;
import com.smallaswater.npc.utils.exception.RsNpcConfigLoadException;
import com.smallaswater.npc.utils.exception.RsNpcLoadException;
-import com.smallaswater.npc.variable.VariableManage;
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;
@@ -164,7 +163,7 @@ public RsNpcConfig(@NonNull String name, @NonNull Config config) throws RsNpcCon
}
try {
- this.skinName = config.getString("皮肤", "默认");
+ this.skinName = config.getString("皮肤", "private_steve");
if (!RsNPC.getInstance().getSkins().containsKey(this.skinName)) {
RsNPC.getInstance().getLogger().warning("NPC: " + this.name + " 皮肤: " + this.skinName + " 不存在!已切换为默认皮肤!");
}
@@ -386,7 +385,7 @@ public void checkEntity() {
if (!this.lookAtThePlayer) {
this.entityRsNpc.setRotation(this.location.yaw, this.location.pitch);
}
- this.entityRsNpc.setNameTag(VariableManage.stringReplace(null, this.showName, this));
+ this.entityRsNpc.setNameTag(this.showName /*VariableManage.stringReplace(null, this.showName, this)*/);
}
}
diff --git a/src/main/java/com/smallaswater/npc/entitys/EntityRsNPC.java b/src/main/java/com/smallaswater/npc/entitys/EntityRsNPC.java
index 649cf13..ca53112 100644
--- a/src/main/java/com/smallaswater/npc/entitys/EntityRsNPC.java
+++ b/src/main/java/com/smallaswater/npc/entitys/EntityRsNPC.java
@@ -6,26 +6,28 @@
import cn.nukkit.Server;
import cn.nukkit.block.BlockLiquid;
import cn.nukkit.entity.EntityHuman;
+import cn.nukkit.entity.data.EntityMetadata;
+import cn.nukkit.entity.data.Skin;
import cn.nukkit.level.Level;
import cn.nukkit.level.format.FullChunk;
import cn.nukkit.math.Vector3;
import cn.nukkit.nbt.tag.CompoundTag;
-import cn.nukkit.network.protocol.EmotePacket;
-import cn.nukkit.network.protocol.ProtocolInfo;
-import cn.nukkit.network.protocol.RemoveEntityPacket;
-import cn.nukkit.network.protocol.SetEntityLinkPacket;
+import cn.nukkit.network.protocol.*;
import com.smallaswater.npc.RsNPC;
import com.smallaswater.npc.data.RsNpcConfig;
import com.smallaswater.npc.route.Node;
import com.smallaswater.npc.route.RouteFinder;
+import com.smallaswater.npc.variable.VariableManage;
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;
+import java.util.HashSet;
import java.util.LinkedList;
public class EntityRsNPC extends EntityHuman {
+ @Getter
private final RsNpcConfig config;
private int emoteSecond = 0;
private int nextRouteIndex = 0;
@@ -70,14 +72,9 @@ public EntityRsNPC(@NonNull FullChunk chunk, @NonNull CompoundTag nbt, RsNpcConf
this.dataProperties.putFloat(EntityUtils.getEntityField("DATA_BOUNDING_BOX_HEIGHT", DATA_BOUNDING_BOX_HEIGHT), this.getHeight());
this.dataProperties.putFloat(EntityUtils.getEntityField("DATA_BOUNDING_BOX_WIDTH", DATA_BOUNDING_BOX_WIDTH), this.getWidth());
this.dataProperties.putInt(EntityUtils.getEntityField("DATA_HEALTH", DATA_HEALTH), (int) this.getHealth());
- this.sendData(this.getViewers().values().toArray(new Player[0]));
}
}
- public RsNpcConfig getConfig() {
- return this.config;
- }
-
@Override
public float getWidth() {
if (this.config != null && this.config.isEnableCustomCollisionSize()) {
@@ -273,11 +270,13 @@ public void addMovement(double x, double y, double z, double yaw, double pitch,
public void spawnTo(Player player) {
if (this.getNetworkId() == -1) {
super.spawnTo(player);
+ this.sendData(player);
}
if (!this.hasSpawned.containsKey(player.getLoaderId()) && this.chunk != null && player.usedChunks.containsKey(Level.chunkHash(this.chunk.getX(), this.chunk.getZ()))) {
this.hasSpawned.put(player.getLoaderId(), player);
player.dataPacket(this.createAddEntityPacket());
+ this.sendData(player);
}
if (this.riding != null) {
this.riding.spawnTo(player);
@@ -303,4 +302,51 @@ public void despawnFrom(Player player) {
this.hasSpawned.remove(player.getLoaderId());
}
}
+
+ @Override
+ public void setSkin(Skin skin) {
+ Skin oldSkin = this.getSkin();
+ super.setSkin(skin);
+ this.sendSkin(oldSkin);
+ }
+
+ protected void sendSkin(Skin oldSkin) {
+ PlayerSkinPacket packet = new PlayerSkinPacket();
+ packet.skin = this.getSkin();
+ packet.newSkinName = this.getSkin().getSkinId();
+ packet.oldSkinName = oldSkin != null ? oldSkin.getSkinId() : "old";
+ packet.uuid = this.getUniqueId();
+ HashSet players = new HashSet<>(this.getViewers().values());
+ if (!players.isEmpty()) {
+ Server.broadcastPacket(players, packet);
+ }
+ }
+
+ @Override
+ public void sendData(Player player, EntityMetadata data) {
+ SetEntityDataPacket pk = new SetEntityDataPacket();
+ pk.eid = this.getId();
+ pk.metadata = data == null ? this.dataProperties : data;
+ pk.metadata.putString(
+ EntityUtils.getEntityField("DATA_NAMETAG", DATA_NAMETAG),
+ VariableManage.stringReplace(player, this.getNameTag(), this.getConfig())
+ );
+ player.dataPacket(pk);
+ }
+
+ @Override
+ public void sendData(Player[] players, EntityMetadata data) {
+ SetEntityDataPacket pk = new SetEntityDataPacket();
+ pk.eid = this.getId();
+ pk.metadata = data == null ? this.dataProperties : data;
+
+ for(Player player : players) {
+ SetEntityDataPacket clone = (SetEntityDataPacket) pk.clone();
+ clone.metadata.putString(
+ EntityUtils.getEntityField("DATA_NAMETAG", DATA_NAMETAG),
+ VariableManage.stringReplace(player, this.getNameTag(), this.getConfig())
+ );
+ player.dataPacket(clone);
+ }
+ }
}
\ No newline at end of file
diff --git a/src/main/java/com/smallaswater/npc/entitys/EntityRsNPCCustomEntity.java b/src/main/java/com/smallaswater/npc/entitys/EntityRsNPCCustomEntity.java
index 1f628a8..6627b80 100644
--- a/src/main/java/com/smallaswater/npc/entitys/EntityRsNPCCustomEntity.java
+++ b/src/main/java/com/smallaswater/npc/entitys/EntityRsNPCCustomEntity.java
@@ -4,6 +4,7 @@
import cn.lanink.gamecore.utils.EntityUtils;
import cn.nukkit.Player;
import cn.nukkit.entity.data.IntEntityData;
+import cn.nukkit.entity.data.Skin;
import cn.nukkit.level.Level;
import cn.nukkit.level.format.FullChunk;
import cn.nukkit.nbt.tag.CompoundTag;
@@ -12,6 +13,7 @@
import cn.nukkit.network.protocol.SetEntityLinkPacket;
import cn.nukkit.network.protocol.types.EntityLink;
import com.smallaswater.npc.data.RsNpcConfig;
+import com.smallaswater.npc.variable.VariableManage;
import lombok.NonNull;
import static cn.nukkit.network.protocol.SetEntityLinkPacket.TYPE_PASSENGER;
@@ -79,7 +81,7 @@ public void addMovement(double x, double y, double z, double yaw, double pitch,
public void spawnTo(Player player) {
if (!this.hasSpawned.containsKey(player.getLoaderId()) && this.chunk != null && player.usedChunks.containsKey(Level.chunkHash(this.chunk.getX(), this.chunk.getZ()))) {
this.hasSpawned.put(player.getLoaderId(), player);
- player.dataPacket(createAddEntityPacket());
+ player.dataPacket(createAddEntityPacket(player));
}
if (this.riding != null) {
@@ -121,4 +123,18 @@ public DataPacket createAddEntityPacket() {
return addEntity;
}
+ public DataPacket createAddEntityPacket(Player player) {
+ AddEntityPacket pk = (AddEntityPacket) this.createAddEntityPacket();
+ pk.metadata.putString(
+ EntityUtils.getEntityField("DATA_NAMETAG", DATA_NAMETAG),
+ VariableManage.stringReplace(player, this.getNameTag(), this.getConfig())
+ );
+ return pk;
+ }
+
+ @Override
+ public void setSkin(Skin skin) {
+ this.skin = skin;
+ }
+
}
diff --git a/src/main/java/com/smallaswater/npc/utils/FormHelper.java b/src/main/java/com/smallaswater/npc/utils/FormHelper.java
index cda7f2d..18a94b0 100644
--- a/src/main/java/com/smallaswater/npc/utils/FormHelper.java
+++ b/src/main/java/com/smallaswater/npc/utils/FormHelper.java
@@ -134,7 +134,7 @@ public static void sendAdminNpc(@NotNull Player player, @NotNull RsNpcConfig rsN
"\n显示名称一直可见: " + toAdminNpcBooleanShowText(rsNpcConfig.isNameTagAlwaysVisible()) +
"\n坐标:\n x: " + NukkitMath.round(rsNpcConfig.getLocation().getX(), 2) +
"\n y: " + NukkitMath.round(rsNpcConfig.getLocation().getY(), 2) +
- "\n z: " + NukkitMath.round(rsNpcConfig.getLocation().getZ(), 2) + "" +
+ "\n z: " + NukkitMath.round(rsNpcConfig.getLocation().getZ(), 2) +
"\n yaw: " + NukkitMath.round(rsNpcConfig.getLocation().getYaw(), 3) +
"\n 世界: " + rsNpcConfig.getLocation().getLevel().getName() +
"\n物品:\n 手持: " + hand.getId() + ":" + hand.getDamage() +
@@ -233,7 +233,7 @@ public static void sendAdminNpcConfig(@NotNull Player player, @NotNull RsNpcConf
custom.onResponded((formResponseCustom, cp) -> {
try {
String showName = formResponseCustom.getInputResponse(0);
- if ("".equals(showName.trim())) {
+ if (showName.trim().isEmpty()) {
cp.sendMessage(language.translateString("gui.adminNPCConfig.responded.showNameNull"));
return;
}
@@ -324,7 +324,7 @@ public static void sendAdminNpcConfigEmote(@NotNull Player player, @NotNull RsNp
rsNpcConfig.getEmoteIDs().clear();
String[] emoteIDs = formResponseCustom.getInputResponse(2).split(";");
for (String id : emoteIDs) {
- if (!"".equals(id.trim())) {
+ if (!id.trim().isEmpty()) {
rsNpcConfig.getEmoteIDs().add(id);
}
}
@@ -393,7 +393,7 @@ public static void sendAdminNpcConfigCommandAdd(@NotNull Player player, @NotNull
custom.onResponded((formResponseCustom, cp) -> {
String cmd = formResponseCustom.getInputResponse(1).replace("&", "");
- if ("".equals(cmd.trim())) {
+ if (cmd.trim().isEmpty()) {
cp.sendMessage("命令不能为空!");
return;
}
@@ -483,7 +483,7 @@ public static void sendAdminNpcConfigMessageAdd(@NotNull Player player, @NotNull
custom.onResponded((formResponseCustom, cp) -> {
String message = formResponseCustom.getInputResponse(1);
- if ("".equals(message.trim())) {
+ if (message.trim().isEmpty()) {
cp.sendMessage(language.translateString("gui.adminNPCConfigMessageAdd.responded.messageNull"));
return;
}
diff --git a/src/main/resources/Npc.yml b/src/main/resources/Npc.yml
index 8de77a8..b26309a 100644
--- a/src/main/resources/Npc.yml
+++ b/src/main/resources/Npc.yml
@@ -14,7 +14,7 @@ nameTagAlwaysVisible: true
胸部: ""
腿部: ""
脚部: ""
-皮肤: "默认"
+皮肤: "private_steve"
实体NetworkId: -1
实体大小: 1.0
看向玩家: true
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index c8e9047..e570bed 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -1,6 +1,6 @@
name: RsNPC
main: com.smallaswater.npc.RsNPC
-version: "2.4.2"
+version: "2.4.3-SNAPSHOT"
api:
- "1.0.9"
- "1.0.11"