001 package net.minecraft.network.rcon; 002 003 import java.io.BufferedInputStream; 004 import java.io.ByteArrayOutputStream; 005 import java.io.DataOutputStream; 006 import java.io.IOException; 007 import java.net.Socket; 008 import java.net.SocketTimeoutException; 009 010 public class RConThreadClient extends RConThreadBase 011 { 012 /** 013 * True if the client has succefssfully logged into the RCon, otherwise false 014 */ 015 private boolean loggedIn = false; 016 017 /** The client's Socket connection */ 018 private Socket clientSocket; 019 020 /** A buffer for incoming Socket data */ 021 private byte[] buffer = new byte[1460]; 022 023 /** The RCon password */ 024 private String rconPassword; 025 026 RConThreadClient(IServer par1IServer, Socket par2Socket) 027 { 028 super(par1IServer); 029 this.clientSocket = par2Socket; 030 031 try 032 { 033 this.clientSocket.setSoTimeout(0); 034 } 035 catch (Exception var4) 036 { 037 this.running = false; 038 } 039 040 this.rconPassword = par1IServer.getStringProperty("rcon.password", ""); 041 this.logInfo("Rcon connection from: " + par2Socket.getInetAddress()); 042 } 043 044 public void run() 045 { 046 while (true) 047 { 048 try 049 { 050 if (!this.running) 051 { 052 break; 053 } 054 055 BufferedInputStream var1 = new BufferedInputStream(this.clientSocket.getInputStream()); 056 int var2 = var1.read(this.buffer, 0, 1460); 057 058 if (10 <= var2) 059 { 060 byte var3 = 0; 061 int var4 = RConUtils.getBytesAsLEInt(this.buffer, 0, var2); 062 063 if (var4 != var2 - 4) 064 { 065 return; 066 } 067 068 int var21 = var3 + 4; 069 int var5 = RConUtils.getBytesAsLEInt(this.buffer, var21, var2); 070 var21 += 4; 071 int var6 = RConUtils.getRemainingBytesAsLEInt(this.buffer, var21); 072 var21 += 4; 073 074 switch (var6) 075 { 076 case 2: 077 if (this.loggedIn) 078 { 079 String var8 = RConUtils.getBytesAsString(this.buffer, var21, var2); 080 081 try 082 { 083 this.sendMultipacketResponse(var5, this.server.executeCommand(var8)); 084 } 085 catch (Exception var16) 086 { 087 this.sendMultipacketResponse(var5, "Error executing: " + var8 + " (" + var16.getMessage() + ")"); 088 } 089 090 continue; 091 } 092 093 this.sendLoginFailedResponse(); 094 continue; 095 case 3: 096 String var7 = RConUtils.getBytesAsString(this.buffer, var21, var2); 097 int var10000 = var21 + var7.length(); 098 099 if (0 != var7.length() && var7.equals(this.rconPassword)) 100 { 101 this.loggedIn = true; 102 this.sendResponse(var5, 2, ""); 103 continue; 104 } 105 106 this.loggedIn = false; 107 this.sendLoginFailedResponse(); 108 continue; 109 default: 110 this.sendMultipacketResponse(var5, String.format("Unknown request %s", new Object[] {Integer.toHexString(var6)})); 111 continue; 112 } 113 } 114 } 115 catch (SocketTimeoutException var17) 116 { 117 break; 118 } 119 catch (IOException var18) 120 { 121 break; 122 } 123 catch (Exception var19) 124 { 125 System.out.println(var19); 126 break; 127 } 128 finally 129 { 130 this.closeSocket(); 131 } 132 133 return; 134 } 135 } 136 137 /** 138 * Sends the given response message to the client 139 */ 140 private void sendResponse(int par1, int par2, String par3Str) throws IOException 141 { 142 ByteArrayOutputStream var4 = new ByteArrayOutputStream(1248); 143 DataOutputStream var5 = new DataOutputStream(var4); 144 var5.writeInt(Integer.reverseBytes(par3Str.length() + 10)); 145 var5.writeInt(Integer.reverseBytes(par1)); 146 var5.writeInt(Integer.reverseBytes(par2)); 147 var5.writeBytes(par3Str); 148 var5.write(0); 149 var5.write(0); 150 this.clientSocket.getOutputStream().write(var4.toByteArray()); 151 } 152 153 /** 154 * Sends the standard RCon 'authorization failed' response packet 155 */ 156 private void sendLoginFailedResponse() throws IOException 157 { 158 this.sendResponse(-1, 2, ""); 159 } 160 161 /** 162 * Splits the response message into individual packets and sends each one 163 */ 164 private void sendMultipacketResponse(int par1, String par2Str) throws IOException 165 { 166 int var3 = par2Str.length(); 167 168 do 169 { 170 int var4 = 4096 <= var3 ? 4096 : var3; 171 this.sendResponse(par1, 0, par2Str.substring(0, var4)); 172 par2Str = par2Str.substring(var4); 173 var3 = par2Str.length(); 174 } 175 while (0 != var3); 176 } 177 178 /** 179 * Closes the client socket 180 */ 181 private void closeSocket() 182 { 183 if (null != this.clientSocket) 184 { 185 try 186 { 187 this.clientSocket.close(); 188 } 189 catch (IOException var2) 190 { 191 this.logWarning("IO: " + var2.getMessage()); 192 } 193 194 this.clientSocket = null; 195 } 196 } 197 }