0

我一生都无法弄清楚如何使用 Java 中的两个按钮来启动和停止游戏 Minecraft 的服务器。

到目前为止我有这个烂摊子..

try
        {
            ProcessBuilder processBuilder = new ProcessBuilder("/Users/UserName/Desktop/servers/test/launch.sh");
            Process server;
            if (event.getSource() == start_Btn)
            {
                server = processBuilder.start();
                //OutputStream out = server.getOutputStream();
                start_Btn.setText("Started");

            }   
            else if (event.getSource() == stop_Btn)
            {

                OutputStream out = server.getOutputStream();
                server.getOutputStream().write(new String("stop").getBytes("utf-8"));

                stop_Btn.setText("Stoped");
                start_Btn.setText("Start");

            }
        }
        catch (IOException exception)
        {

        }
        catch (InterruptedException exception)
        {

        }

今天我在网上搜索了一整天,我决定终于把它带给你们。

我希望能够通过按下“开始”按钮来启动服务器,然后用“停止”按钮停止它我已经设置了 GUI,并且我知道如何设置按钮事件。我可以轻松地让服务器从开始按钮开始,这只是我似乎无法管理的停止功能。

注意:要停止服务器,您必须在启动服务器的命令行中输入“停止”。

非常感谢您的帮助,我非常感谢。

4

2 回答 2

2

好像从来没有一个答案可以解决我的问题,并且好像是我自己想出来的,我想我会把它发布给其他发生在这个问题上的人。

我使用了几个类来实现这个目标,确切地说是两个。一个是容纳服务器的线程,另一个是向服务器发送命令。

首先,启动和容纳服务器流的代码。

这里的第一堂课是魔法发生的地方

public class Sender{

ConsoleWriter cWriter = new ConsoleWriter();
public void execute(){
    this.ui = ui;
    try{
        ProcessBuilder pb = new ProcessBuilder(path_to_server+"launch.bat");
        Process process = pb.start();

        StreamGobbler sgError = new StreamGobbler(process.getErrorStream());

        new Thread( sgError ).start();
        writer = new PrintWriter( process.getOutputStream() );

    } catch ( IOException e ){
        e.printStackTrace();
    }
}

private class StreamGobbler implements Runnable 
{
    private InputStream is;
    public StreamGobbler( InputStream is ){
        this.is = is;
    }
    @Override
    public void run() {
        try {
            InputStreamReader isr = new InputStreamReader( is );
            BufferedReader br = new BufferedReader( isr );
            String line = null;
            while ( ( line = br.readLine() ) != null ){
                cWriter.writer(line, ui);
            }
        } catch ( IOException e ){
            e.printStackTrace();
        }
    }
}

}

你问这是如何工作的?让我们从顶部开始。

  • 控制台编写器

这是我编写的用于将流从 Minecraft 的服务器控制台写入我自己的 GUI 的类,其代码并不重要,因此我将其省略。你可以写那部分。

  • 执行()

此方法使用 Java 的 ProcessBuilder 为服务器构建进程,然后启动该进程。更重要的是,我们拥有 StreamGobbler。这使我们能够访问并“吞噬”来自服务器的输入流。基本上它从服务器接收控制台的所有输出。出于某种原因,不知道为什么,Minecraft 服务器喜欢 ErrorStream,所以我将它绑定到了它。然后我为 gobbler 创建一个新线程,就是这样。这种方法的最后一件事是......

  • 打印机作家

这作为输出绑定到服务器,让我可以向服务器发送命令,例如停止它或任何其他可用的服务器命令。

  • StreamGobbler 类

现在,到 Gobbler 上。这里没有太多。基本上只是将我们从执行方法发送的 inputStream 发送给阅读器,然后对其进行缓冲,最后将其读给我的控制台编写器。

第二课很简单!

public class WriteCommand
{
public void send(String command)
{
    txtA.append("Command:>>"+ command + "\n");
    writer.write(command);
    writer.write("\n");
    writer.flush(); 
}
}

所有这一切都是编写命令并点击“输入”然后刷新它以准备发送下一个!txtA.append 用于添加发送到我自己的控制台输出的命令,只是一个可视项。

你去吧!希望这会帮助其他人。如果您想查看此代码的实际效果,您可以将其视为我使用过的应用程序的一部分。

这是一个链接:Minecraft Server Utility(BETA)1.3.6

于 2014-01-14T02:26:31.943 回答
0

我今天也在做同样的任务。我是java的新手,但我想我找到了你可能缺少的东西。我或多或少跟随你的脚步,但在停止命令中使用斜杠 "/stop"

似乎我需要关闭输出流才能完成操作。

private void stopButtonActionPerformed(java.awt.event.ActionEvent evt) {                                           
    // TODO add your handling code here:
    try {
        oS.write(new String("/stop").getBytes("utf-8"));
        oS.close();
    } catch (IOException e) {
        e.printStackTrace();
    }

}               

我希望这对你有帮助。

于 2013-01-21T03:06:01.430 回答