File size: 4,019 Bytes
d46f4a3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package net.minecraft.server.rcon.thread;

import com.google.common.collect.Lists;
import com.mojang.logging.LogUtils;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.List;
import javax.annotation.Nullable;
import net.minecraft.server.ServerInterface;
import net.minecraft.server.dedicated.DedicatedServerProperties;
import org.slf4j.Logger;

public class RconThread extends GenericThread {
    private static final Logger LOGGER = LogUtils.getLogger();
    private final ServerSocket socket;
    private final String rconPassword;
    private final List<RconClient> clients = Lists.newArrayList();
    private final ServerInterface serverInterface;

    private RconThread(ServerInterface p_11608_, ServerSocket p_11609_, String p_11610_) {
        super("RCON Listener");
        this.serverInterface = p_11608_;
        this.socket = p_11609_;
        this.rconPassword = p_11610_;
    }

    private void clearClients() {
        this.clients.removeIf(p_11612_ -> !p_11612_.isRunning());
    }

    @Override
    public void run() {
        try {
            while (this.running) {
                try {
                    Socket socket = this.socket.accept();
                    RconClient rconclient = new RconClient(this.serverInterface, this.rconPassword, socket);
                    rconclient.start();
                    this.clients.add(rconclient);
                    this.clearClients();
                } catch (SocketTimeoutException sockettimeoutexception) {
                    this.clearClients();
                } catch (IOException ioexception) {
                    if (this.running) {
                        LOGGER.info("IO exception: ", (Throwable)ioexception);
                    }
                }
            }
        } finally {
            this.closeSocket(this.socket);
        }
    }

    @Nullable
    public static RconThread create(ServerInterface p_11616_) {
        DedicatedServerProperties dedicatedserverproperties = p_11616_.getProperties();
        String s = p_11616_.getServerIp();
        if (s.isEmpty()) {
            s = "0.0.0.0";
        }

        int i = dedicatedserverproperties.rconPort;
        if (0 < i && 65535 >= i) {
            String s1 = dedicatedserverproperties.rconPassword;
            if (s1.isEmpty()) {
                LOGGER.warn("No rcon password set in server.properties, rcon disabled!");
                return null;
            } else {
                try {
                    ServerSocket serversocket = new ServerSocket(i, 0, InetAddress.getByName(s));
                    serversocket.setSoTimeout(500);
                    RconThread rconthread = new RconThread(p_11616_, serversocket, s1);
                    if (!rconthread.start()) {
                        return null;
                    } else {
                        LOGGER.info("RCON running on {}:{}", s, i);
                        return rconthread;
                    }
                } catch (IOException ioexception) {
                    LOGGER.warn("Unable to initialise RCON on {}:{}", s, i, ioexception);
                    return null;
                }
            }
        } else {
            LOGGER.warn("Invalid rcon port {} found in server.properties, rcon disabled!", i);
            return null;
        }
    }

    @Override
    public void stop() {
        this.running = false;
        this.closeSocket(this.socket);
        super.stop();

        for (RconClient rconclient : this.clients) {
            if (rconclient.isRunning()) {
                rconclient.stop();
            }
        }

        this.clients.clear();
    }

    private void closeSocket(ServerSocket p_11614_) {
        LOGGER.debug("closeSocket: {}", p_11614_);

        try {
            p_11614_.close();
        } catch (IOException ioexception) {
            LOGGER.warn("Failed to close socket", (Throwable)ioexception);
        }
    }
}