11using System ;
2+ using System . Diagnostics ;
3+ using System . Net ;
24using System . Net . Sockets ;
35using RCONServerLib . Utils ;
46
@@ -9,18 +11,50 @@ namespace RCONServerLib
911 /// </summary>
1012 internal class RemoteConClient
1113 {
14+ /// <summary>
15+ /// The maximum packet size to receive
16+ /// </summary>
1217 private const int MaxAllowedPacketSize = 4096 ;
18+
19+ /// <summary>
20+ /// Used to determine if we're in unit test mode (Means no actual connection)
21+ /// </summary>
22+ private readonly bool _isUnitTest ;
23+
24+ /// <summary>
25+ /// Underlaying NetworkStream
26+ /// </summary>
1327 private readonly NetworkStream _ns ;
28+
29+ /// <summary>
30+ /// Reference to RemoteConServer for getting settings
31+ /// </summary>
1432 private readonly RemoteConServer _remoteConServer ;
33+
34+ /// <summary>
35+ /// The TCP Client
36+ /// </summary>
1537 private readonly TcpClient _tcp ;
16- internal bool Authenticated ;
38+
39+ /// <summary>
40+ /// How many failed login attempts the client has
41+ /// </summary>
1742 private int _authTries ;
1843
44+ /// <summary>
45+ /// A buffer containing the packet
46+ /// </summary>
1947 private byte [ ] _buffer ;
2048
49+ /// <summary>
50+ /// Wether or not the client is connected
51+ /// </summary>
2152 private bool _connected ;
2253
23- private readonly bool _isUnitTest ;
54+ /// <summary>
55+ /// Has the client been successfully authenticated
56+ /// </summary>
57+ internal bool Authenticated ;
2458
2559 public RemoteConClient ( TcpClient tcp , RemoteConServer remoteConServer )
2660 {
@@ -64,7 +98,7 @@ private void CloseConnection()
6498 {
6599 if ( _isUnitTest )
66100 return ;
67-
101+
68102 _connected = false ;
69103
70104 if ( ! _tcp . Connected )
@@ -83,7 +117,7 @@ private void SendPacket(RemoteConPacket packet)
83117 {
84118 if ( _isUnitTest )
85119 return ;
86-
120+
87121 if ( ! _connected )
88122 throw new Exception ( "Not connected." ) ;
89123
@@ -149,86 +183,104 @@ private void OnPacket(IAsyncResult result)
149183 }
150184
151185 /// <summary>
152- /// Parses raw bytes to RemoteConPacket
186+ /// Parses raw bytes to RemoteConPacket
153187 /// </summary>
154188 /// <param name="rawPacket"></param>
155189 internal void ParsePacket ( byte [ ] rawPacket )
156190 {
157- var packet = new RemoteConPacket ( rawPacket ) ;
158-
159- // Do not allow any other packets than auth to be sent when client is not authenticated
160- if ( ! Authenticated )
191+ try
161192 {
162- if ( packet . Type != RemoteConPacket . PacketType . Auth )
193+ var packet = new RemoteConPacket ( rawPacket ) ;
194+
195+ // Do not allow any other packets than auth to be sent when client is not authenticated
196+ if ( ! Authenticated )
163197 {
164- if ( _isUnitTest )
165- throw new NotAuthenticatedException ( ) ;
166- CloseConnection ( ) ;
167- }
198+ if ( packet . Type != RemoteConPacket . PacketType . Auth )
199+ {
200+ if ( _isUnitTest )
201+ throw new NotAuthenticatedException ( ) ;
202+ CloseConnection ( ) ;
203+ }
168204
169- _authTries ++ ;
205+ _authTries ++ ;
170206
171- if ( packet . Payload == _remoteConServer . Password )
172- {
173- Authenticated = true ;
207+ if ( packet . Payload == _remoteConServer . Password )
208+ {
209+ Authenticated = true ;
210+
211+ if ( ! _remoteConServer . SendAuthImmediately )
212+ SendPacket ( new RemoteConPacket ( packet . Id , RemoteConPacket . PacketType . ResponseValue , "" ) ) ;
213+
214+ SendPacket ( new RemoteConPacket ( packet . Id , RemoteConPacket . PacketType . ExecCommand , "" ) ) ;
215+ return ;
216+ }
217+
218+ if ( _authTries >= _remoteConServer . MaxPasswordTries )
219+ {
220+ CloseConnection ( ) ;
221+ return ;
222+ }
174223
175224 if ( ! _remoteConServer . SendAuthImmediately )
176225 SendPacket ( new RemoteConPacket ( packet . Id , RemoteConPacket . PacketType . ResponseValue , "" ) ) ;
177226
178- SendPacket ( new RemoteConPacket ( packet . Id , RemoteConPacket . PacketType . ExecCommand , "" ) ) ;
227+ SendPacket ( new RemoteConPacket ( - 1 , RemoteConPacket . PacketType . ExecCommand , "" ) ) ;
228+
179229 return ;
180230 }
181-
182- if ( _authTries >= _remoteConServer . MaxPasswordTries )
231+
232+ // Invalid packet type.
233+ if ( packet . Type != RemoteConPacket . PacketType . ExecCommand )
183234 {
184- CloseConnection ( ) ;
235+ if ( _isUnitTest )
236+ throw new InvalidPacketTypeException ( ) ;
237+
238+ if ( _remoteConServer . InvalidPacketKick )
239+ CloseConnection ( ) ;
185240 return ;
186241 }
187242
188- if ( ! _remoteConServer . SendAuthImmediately )
189- SendPacket ( new RemoteConPacket ( packet . Id , RemoteConPacket . PacketType . ResponseValue , "" ) ) ;
243+ if ( packet . Payload == "" )
244+ {
245+ if ( _isUnitTest )
246+ throw new EmptyPacketPayloadException ( ) ;
190247
191- SendPacket ( new RemoteConPacket ( - 1 , RemoteConPacket . PacketType . ExecCommand , "" ) ) ;
248+ if ( _remoteConServer . EmptyPayloadKick )
249+ CloseConnection ( ) ;
250+ return ;
251+ }
192252
193- return ;
194- }
253+ var args = ArgumentParser . ParseLine ( packet . Payload ) ;
254+ var cmd = args [ 0 ] ;
255+ args . RemoveAt ( 0 ) ;
195256
196- // Invalid packet type.
197- if ( packet . Type != RemoteConPacket . PacketType . ExecCommand )
198- {
199- if ( _isUnitTest )
200- throw new InvalidPacketTypeException ( ) ;
201-
202- if ( _remoteConServer . InvalidPacketKick )
203- CloseConnection ( ) ;
204- return ;
205- }
206-
207- if ( packet . Payload == "" )
208- {
209- if ( _isUnitTest )
210- throw new EmptyPacketPayloadException ( ) ;
211-
212- if ( _remoteConServer . EmptyPayloadKick )
213- CloseConnection ( ) ;
214- return ;
215- }
257+ if ( _remoteConServer . UseCustomCommandHandler )
258+ {
259+ var result = _remoteConServer . ExecuteCustomCommandHandler ( cmd , args ) ;
260+ SendPacket ( new RemoteConPacket ( packet . Id , RemoteConPacket . PacketType . ResponseValue ,
261+ result ) ) ;
262+ return ;
263+ }
216264
217- var args = ArgumentParser . ParseLine ( packet . Payload ) ;
218- var cmd = args [ 0 ] ;
219- args . RemoveAt ( 0 ) ;
220- var command = _remoteConServer . CommandManager . GetCommand ( cmd ) ;
221- if ( command == null )
222- {
223- SendPacket ( new RemoteConPacket ( packet . Id , RemoteConPacket . PacketType . ResponseValue ,
224- "Invalid command \" " + packet . Payload + "\" " ) ) ;
265+ var command = _remoteConServer . CommandManager . GetCommand ( cmd ) ;
266+ if ( command == null )
267+ {
268+ SendPacket ( new RemoteConPacket ( packet . Id , RemoteConPacket . PacketType . ResponseValue ,
269+ "Invalid command \" " + packet . Payload + "\" " ) ) ;
270+ }
271+ else
272+ {
273+ var commandResult = command . Handler ( cmd , args ) ;
274+ // TODO: Split packets?
275+ SendPacket ( new RemoteConPacket ( packet . Id , RemoteConPacket . PacketType . ResponseValue ,
276+ commandResult ) ) ;
277+ }
225278 }
226- else
279+ catch ( Exception e )
227280 {
228- var commandResult = command . Func ( cmd , args ) ;
229- // TODO: Split packets?
230- SendPacket ( new RemoteConPacket ( packet . Id , RemoteConPacket . PacketType . ResponseValue ,
231- commandResult ) ) ;
281+ Debug . WriteLine ( string . Format ( "Client {0} caused an exception: {1} and was killed." ,
282+ ( ( IPEndPoint ) _tcp . Client . RemoteEndPoint ) . Address , e . Message ) ) ;
283+ CloseConnection ( ) ;
232284 }
233285 }
234286 }
0 commit comments