PaintChat.jarのコマンド引数「exit」が効かない問題を修正する

注意

症状

PaintChat(Java版3.66)にて以下のようなコマンドを実行してもPaintChatサーバが落ちない(一見ログは正常だが実はプロセスが生きたまま)
java -cp PaintChat.jar paintchat_server.Server ./cnf/paintchat.cf exit

修正方法

  1. PaintChat.jarのバックアップを取っておく
  2. これをダウンロード
  3. PaintChat.jarを解凍ツール等で開いて、「paintchat_server」ディレクトリにある「TalkerInstance.class」を↑の同名ファイルで上書きする。
    よくわからない場合は拡張子をいったん「.jar」→「.zip」にすれば中身を直接書き換えられます。(Windowsの場合)
以上.

詳細

原因

(PaintChat.jarをデコンパイルしてソースを調べてみました。)
PaintChat.jarは"exit"を指定して実行すると、起動しているサーバに"terminate"コマンドを送って終了します。
paintchat_server.Server#isExecute

… 省略 …
LocalAdmin localLocalAdmin = new LocalAdmin(localRes, InetAddress.getLocalHost(), this.config.getInt("Connection_Port_PaintChat", Config.DEF_PORT));
… 省略 …
str = localLocalAdmin.getString("terminate");
this.debug.log("server got terminated");
System.exit(0);

ですが、サーバ側は"terminate"コマンドを受け取っても何もしません。
代わりに、以下の通り"exit"コマンドならばサーバを終了させるようになっているようです。
paintchat_server.TalkerInstance#switchLocalAdmin

… 省略 …
if (str2.equals("exit"))
{
    localStringBuffer.append("response=exit ok\n");
    byte[] arrayOfByte2 = localStringBuffer.toString().getBytes("UTF8");
    this.Out = this.socket.getOutputStream();
    Io.wShort(this.Out, arrayOfByte2.length);
    this.Out.write(arrayOfByte2);
    this.Out.flush();
    closeSocket();
    this.server.exitServer();
    return;
}

修正

修正するのはServerクラスでもTalkerInstanceクラスでもいいのですが、今回は後者を直しました。
paintchat_server.TalkerInstance#switchLocalAdmin

… 省略 …
if (str2.equals("exit") || str2.equals("terminate"))
{
    localStringBuffer.append("response=exit ok\n");
    byte[] arrayOfByte2 = localStringBuffer.toString().getBytes("UTF8");
    this.Out = this.socket.getOutputStream();
    Io.wShort(this.Out, arrayOfByte2.length);
    this.Out.write(arrayOfByte2);
    this.Out.flush();
    closeSocket();
    this.server.exitServer();
    return;
}

適当にコンパイルして終わり。
javac.exe -encoding UTF-8 -cp PaintChat.jar -Xlint:unchecked paintchat_server\TalkerInstance.java