1
    public static void setMOTD(final String motd) throws Exception {
    final Field field = MinecraftServer.class.getDeclaredField("motd");
    final Field server = CraftServer.class.getDeclaredField("console");
    field.setAccessible(true);
    server.setAccessible(true);
    MinecraftServer instance = (MinecraftServer) server.get(CraftServer.class);
    field.set(instance, motd);
}

これでの私の目標は、Minecraft サーバー (craftbukkit を実行している) で今日のメッセージを変更することです。これを行うには、非静的フィールド motd を変更する必要があります。このすべてをプラグインで行っているため、MinecraftServer のインスタンスを取得できません。最後から 2 番目の行は、リフレクションを使用してこれを実行しようとした私の試みでしたが、失敗しました。外部ライブラリにあるため、MinecraftServer クラスまたは CraftServer を変更するアクセス権がありません。

motd と console はどちらも非静的フィールドです。

motd は修飾子 public final を持つ文字列です。

console は、modifiers protected final を持つ MinecraftServer のインスタンスです。

これは私が得ているエラーです(setMOTDの最後の2行目):

2012-07-22 22:16:31 [SEVERE] java.lang.IllegalArgumentException: Can not set final net.minecraft.server.MinecraftServer field org.bukkit.craftbukkit.CraftServer.console to java.lang.Class
4

3 に答える 3

2

CraftServer を拡張する bukkit インスタンスを取得することで解決

    public static void setServerMOTD(final String motd) throws Exception {
    final Field field = MinecraftServer.class.getDeclaredField("motd");
    final Field server = CraftServer.class.getDeclaredField("console");
    Field modifiersField = Field.class.getDeclaredField("modifiers");
    modifiersField.setAccessible(true);
    field.setAccessible(true);
    server.setAccessible(true);
    modifiersField.setInt(server, server.getModifiers() & ~Modifier.FINAL);
    MinecraftServer instance = (MinecraftServer) server.get(Bukkit.getServer());
    field.set(instance, motd);
}
于 2012-07-23T04:22:02.883 に答える
2

エラーメッセージを読み直すと、コードと矛盾しているようです。エラー メッセージは、メンバー変数を無効なオブジェクト型に設定しようとしていることを示しているようです。console実際にテストしているコードを確認してください。

于 2012-07-23T03:30:07.803 に答える
0

エラー メッセージに基づいて、CraftServer クラスでフィールド コンソールが「final」とマークされているようです。

これは、一度設定すると、リフレクションが変更する機会を得る前に変更できないことを意味します。

CraftServer がライブラリの一部である場合、この動作を変更できない場合があります

于 2012-07-23T03:00:27.150 に答える