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 }