--- a/net/minecraft/server/rcon/thread/RconClient.java
+++ b/net/minecraft/server/rcon/thread/RconClient.java
@@ -8,11 +8,15 @@
 import java.net.Socket;
 import java.nio.charset.StandardCharsets;
 import java.util.Locale;
+import org.slf4j.Logger;
 import net.minecraft.server.ServerInterface;
+// CraftBukkit start
+import net.minecraft.server.dedicated.DedicatedServer;
 import net.minecraft.server.rcon.PktUtils;
-import org.slf4j.Logger;
+import net.minecraft.server.rcon.RconConsoleSource;
 
 public class RconClient extends GenericThread {
+
     private static final Logger LOGGER = LogUtils.getLogger();
     private static final int SERVERDATA_AUTH = 3;
     private static final int SERVERDATA_EXECCOMMAND = 2;
@@ -23,99 +27,116 @@
     private final Socket client;
     private final byte[] buf = new byte[1460];
     private final String rconPassword;
-    private final ServerInterface serverInterface;
+    // CraftBukkit start
+    private final DedicatedServer serverInterface;
+    private final RconConsoleSource rconConsoleSource;
+    // CraftBukkit end
 
     RconClient(ServerInterface server, String password, Socket socket) {
-        super("RCON Client " + socket.getInetAddress());
-        this.serverInterface = server;
+        super("RCON Client " + String.valueOf(socket.getInetAddress()));
+        this.serverInterface = (DedicatedServer) server; // CraftBukkit
         this.client = socket;
 
         try {
             this.client.setSoTimeout(0);
-        } catch (Exception var5) {
+        } catch (Exception exception) {
             this.running = false;
         }
 
         this.rconPassword = password;
+        this.rconConsoleSource = new net.minecraft.server.rcon.RconConsoleSource(this.serverInterface, socket.getRemoteSocketAddress()); // CraftBukkit
     }
 
-    @Override
     public void run() {
+        // CraftBukkit start - decompile error: switch try / while statement
         try {
-            try {
-                while (this.running) {
-                    BufferedInputStream bufferedInputStream = new BufferedInputStream(this.client.getInputStream());
-                    int i = bufferedInputStream.read(this.buf, 0, 1460);
-                    if (10 > i) {
-                        return;
-                    }
+            while (true) {
+                // CraftBukkit end
+                if (!this.running) {
+                    return;
+                }
 
-                    int j = 0;
-                    int k = PktUtils.intFromByteArray(this.buf, 0, i);
-                    if (k != i - 4) {
-                        return;
-                    }
+                BufferedInputStream bufferedinputstream = new BufferedInputStream(this.client.getInputStream());
+                int i = bufferedinputstream.read(this.buf, 0, 1460);
+
+                if (10 > i) {
+                    return;
+                }
+
+                int j = 0;
+                int k = PktUtils.intFromByteArray(this.buf, 0, i);
 
+                if (k == i - 4) {
                     j += 4;
                     int l = PktUtils.intFromByteArray(this.buf, j, i);
+
                     j += 4;
-                    int m = PktUtils.intFromByteArray(this.buf, j);
+                    int i1 = PktUtils.intFromByteArray(this.buf, j);
+
                     j += 4;
-                    switch (m) {
+                    switch (i1) {
                         case 2:
                             if (this.authed) {
-                                String string2 = PktUtils.stringFromByteArray(this.buf, j, i);
+                                String s = PktUtils.stringFromByteArray(this.buf, j, i);
 
                                 try {
-                                    this.sendCmdResponse(l, this.serverInterface.runCommand(string2));
-                                } catch (Exception var15) {
-                                    this.sendCmdResponse(l, "Error executing: " + string2 + " (" + var15.getMessage() + ")");
+                                    this.sendCmdResponse(l, this.serverInterface.runCommand(this.rconConsoleSource, s)); // CraftBukkit
+                                } catch (Exception exception) {
+                                    this.sendCmdResponse(l, "Error executing: " + s + " (" + exception.getMessage() + ")");
                                 }
-                                break;
+                                continue;
                             }
 
                             this.sendAuthFailure();
-                            break;
+                            continue;
                         case 3:
-                            String string = PktUtils.stringFromByteArray(this.buf, j, i);
-                            j += string.length();
-                            if (!string.isEmpty() && string.equals(this.rconPassword)) {
+                            String s1 = PktUtils.stringFromByteArray(this.buf, j, i);
+                            int j1 = j + s1.length();
+
+                            if (!s1.isEmpty() && s1.equals(this.rconPassword)) {
                                 this.authed = true;
                                 this.send(l, 2, "");
-                                break;
+                                continue;
                             }
 
                             this.authed = false;
                             this.sendAuthFailure();
-                            break;
+                            continue;
                         default:
-                            this.sendCmdResponse(l, String.format(Locale.ROOT, "Unknown request %s", Integer.toHexString(m)));
+                            this.sendCmdResponse(l, String.format(Locale.ROOT, "Unknown request %s", Integer.toHexString(i1)));
+                            continue;
                     }
                 }
-
+        } // CraftBukkit - decompile error: switch try / while statement
+            } catch (IOException ioexception) {
                 return;
-            } catch (IOException var16) {
-            } catch (Exception var17) {
-                LOGGER.error("Exception whilst parsing RCON input", (Throwable)var17);
+            } catch (Exception exception1) {
+                RconClient.LOGGER.error("Exception whilst parsing RCON input", exception1);
+                return;
+            } finally {
+                this.closeSocket();
+                RconClient.LOGGER.info("Thread {} shutting down", this.name);
+                this.running = false;
             }
-        } finally {
-            this.closeSocket();
-            LOGGER.info("Thread {} shutting down", this.name);
-            this.running = false;
-        }
+
+            // CraftBukkit start - decompile error: switch try / while statement
+            // return;
+        // }
+        // CraftBukkit end
     }
 
     private void send(int sessionToken, int responseType, String message) throws IOException {
-        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(1248);
-        DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream);
-        byte[] bs = message.getBytes(StandardCharsets.UTF_8);
-        dataOutputStream.writeInt(Integer.reverseBytes(bs.length + 10));
-        dataOutputStream.writeInt(Integer.reverseBytes(sessionToken));
-        dataOutputStream.writeInt(Integer.reverseBytes(responseType));
-        dataOutputStream.write(bs);
-        dataOutputStream.write(0);
-        dataOutputStream.write(0);
-        this.client.getOutputStream().write(byteArrayOutputStream.toByteArray());
+        ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream(1248);
+        DataOutputStream dataoutputstream = new DataOutputStream(bytearrayoutputstream);
+        byte[] abyte = message.getBytes(StandardCharsets.UTF_8);
+
+        dataoutputstream.writeInt(Integer.reverseBytes(abyte.length + 10));
+        dataoutputstream.writeInt(Integer.reverseBytes(sessionToken));
+        dataoutputstream.writeInt(Integer.reverseBytes(responseType));
+        dataoutputstream.write(abyte);
+        dataoutputstream.write(0);
+        dataoutputstream.write(0);
+        this.client.getOutputStream().write(bytearrayoutputstream.toByteArray());
     }
 
     private void sendAuthFailure() throws IOException {
@@ -123,14 +144,16 @@
     }
 
     private void sendCmdResponse(int sessionToken, String message) throws IOException {
-        int i = message.length();
+        int j = message.length();
 
         do {
-            int j = 4096 <= i ? 4096 : i;
-            this.send(sessionToken, 0, message.substring(0, j));
-            message = message.substring(j);
-            i = message.length();
-        } while (0 != i);
+            int k = 4096 <= j ? 4096 : j;
+
+            this.send(sessionToken, 0, message.substring(0, k));
+            message = message.substring(k);
+            j = message.length();
+        } while (0 != j);
+
     }
 
     @Override
@@ -143,8 +166,9 @@
     private void closeSocket() {
         try {
             this.client.close();
-        } catch (IOException var2) {
-            LOGGER.warn("Failed to close socket", (Throwable)var2);
+        } catch (IOException ioexception) {
+            RconClient.LOGGER.warn("Failed to close socket", ioexception);
         }
+
     }
 }
