Factorio ゲームのコマンド ライン ベースのヘッドレス サーバー用のラッパーを作成しています。私は ProcessBuilder を使用してサーバーの stdout を取得しており、rcon 接続 (長い話、stdin が機能していませんでした) を使用してサーバーと通信しています。jar をパッケージ化して物理サーバーで実行するところまで、ほぼ完成しました。これは、IDE (Intelij) から実行する代わりに jar を実行すると、サーバーからの出力が通過しないことに気付いたときです。さらにスヌーピングを行ったところ、プロセスから .getInputStream() を使用しているときは常に、プログラムがコンソール (java.exe) と一緒に起動された場合にのみサーバーの出力が送信され、プログラムの場合はまったく送信されないことがわかりました。それなしで起動されました(javaw.exe)。
cmd.exe で .getInputStream() をテストしましたが、java.exe と javaw.exe の両方で問題なく動作します。また、コードが IDE の外部で実行されたときに予期していなかったフローに従っているかどうかを確認しますが、入力を待っているが何も受信していないかのように read.readLine() でブロックされます。
プロセスはここで初期化されます。
ProcessBuilder pb = new ProcessBuilder(gameExecutablePath, "--start-server", saveLocation + "\\" + saveName, "--server-settings", serverSettingsLocation + "\\" + serverSettingsName, "-c", serverConfigLocation + "\\" + serverConfigName, "--rcon-port", "" + rconPort, "--rcon-password", "" + rconPasskey);
pb.redirectErrorStream(true);
try
{
myProcess = pb.start();
}catch(Exception e){e.printStackTrace();}
if(myProcess == null) { stop();}
OutputStream serverInput = myProcess.getOutputStream();
write = new BufferedWriter(new OutputStreamWriter(serverInput));
InputStream serverOutput = myProcess.getInputStream();
read = new BufferedReader(new InputStreamReader(serverOutput));
その後、入力は GUI によって処理され、(サーバーが完全に初期化された後) rcon 経由で送信され、出力が読み取られ、GUI のフィードである JTextArea に出力されます。
while(serverRunning)
{
try
{
String line = "" + read.readLine();
if(line == null)
{
continue;
}
line = line.trim();
if(line.contains("Opening socket for broadcast"))
{
serverInitialized = true;
initializeRCONConnection();
}
synchronized(serverFeedStringBuilder)
{
printToServerFeed(line);
}
}catch(Exception e){e.printStackTrace();printToServerFeed(e.getMessage());}
}
アプリケーションは、IDE の場合や java.exe が使用されている場合と同様に、modload に関するすべての初期化テキスト、マッチメイキング サーバーへの接続など、サーバーの出力を出力しているはずです。代わりに、何も出力しませんが、プロセスは引き続き実行され、初期化が完了した後、サーバーはゲーム内で接続できます。