我正在尝试制作数据包(在bukkit API中)。但是我得到了NoSuchFieldException。
public class PacketPlayOutPlayerInfo {
private static final Class<?> packetClass = Reflections.getCraftClass("PacketPlayOutPlayerInfo");
private static final Class<?>[] typesClass = new Class<?>[]{ String.class, boolean.class, int.class };
private static int type = 0;
static {
try {
if (packetClass.getConstructor(typesClass) == null) {
type = 1;
}
} catch (Exception e) {
type = 1;
}
}
public static Object getPacket(String s, boolean b, int i) {
try {
if (type == 0) {
return packetClass.getConstructor(typesClass).newInstance(s, b, i);
}
else if (type == 1) {
Class<?> clazz = Reflections.getCraftClass("PacketPlayOutPlayerInfo");
Object packet = packetClass.getConstructor().newInstance();
Reflections.getPrivateField(clazz, "username").set(packet, s);
Reflections.getPrivateField(clazz, "gamemode").set(packet, 1);
Reflections.getPrivateField(clazz, "ping").set(packet, i);
Reflections.getPrivateField(clazz, "player").set(packet, new OfflineUser(s).getProfile());
if (!b) {
Reflections.getPrivateField(clazz, "action").set(packet, 4);
}
return packet;
}
} catch (Exception e) {
if (FunnyGuilds.exception(e.getCause())) {
e.printStackTrace();
}
}
return null;
}
}
这是完整的错误:
[20:25:43] [IndependentThread/WARN]: java.lang.NoSuchFieldException: username [20:25:43] [IndependentThread/WARN]: at java.lang.Class.getDeclaredField(Unknown Source) [20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.reflect.Reflections.getPrivateField(Reflections.java:123) [20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.reflect.transition.PacketPlayOutPlayerInfo.getPacket(PacketPlayOutPlayerInfo.java:31) [20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.element.PlayerListManager.packets(PlayerListManager.java:88) [20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.element.PlayerListManager.send(PlayerListManager.java:67) [20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.element.PlayerList.send(PlayerList.java:160) [20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.element.PlayerListManager.updatePlayers(PlayerListManager.java:24) [20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.thread.Action.execute(Action.java:37) [20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.thread.IndependentThread.execute(IndependentThread.java:43) [20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.thread.IndependentThread.run(IndependentThread.java:28) [20:25:43] [IndependentThread/WARN]: java.lang.NullPointerException [20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.reflect.transition.PacketPlayOutPlayerInfo.getPacket(PacketPlayOutPlayerInfo.java:31) [20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.element.PlayerListManager.packets(PlayerListManager.java:88) [20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.element.PlayerListManager.send(PlayerListManager.java:67) [20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.element.PlayerList.send(PlayerList.java:160) [20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.element.PlayerListManager.updatePlayers(PlayerListManager.java:24) [20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.thread.Action.execute(Action.java:37) [20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.thread.IndependentThread.execute(IndependentThread.java:43) [20:25:43] [IndependentThread/WARN]: at net.dzikoysk.funnyguilds.util.thread.IndependentThread.run(IndependentThread.java:28)
PS:抱歉我的英语不好。
答案 0 :(得分:1)
由于PacketPlayOutPlayerInfo
未定义您尝试访问的字段,因此异常似乎是合适的。鉴于字段名称的选择,我认为您可能正在尝试为PacketPlayOutPlayerInfo.PlayerInfoData
设置值;即便如此,它的字段名称也是混淆的,除非你将信息作为构造函数的一部分传递,否则必须这样做。
由于此问题涉及访问反编译的专有代码,我将向您提出以下建议:
work/decompileXXX/net/minecraft/server
目录。此信息将帮助您正确实现反射调用以实例化类和修改的字段。在较旧版本的bukkitapi(1.6-1.7)中,此代码效果很好。
要使用ProtocolLib,我必须编辑许多代码。这个类或其他类引起了异常吗?
PacketPlayOutPlayerInfo
在1.8中已更改并继续更改。我看了1.8(我可以回去的最远)和1.11.2版本,并且有一个不同的世界。这是使用不属于API的类的问题。他们会随意改变,如果代码在Minecraft之外发生,没有人会流下眼泪。
虽然ProtocolLib也可能破解,但其知识渊博且经验丰富的开发人员会快速解决它。他们必须,因为许多插件使用它来避免新Minecraft版本的令人讨厌的意外。如果ProtocolLib不是你的茶,那么我建议你使用BuildTools,检查反编译类并相应地调整你的代码。点击Minecraft Modern也是件好事。
答案 1 :(得分:0)
我认为你应该检查请求对象变量名称(你的变量应该是camel case)。因为在api调用中,您必须使用api doc中的名称进行请求。