1
1
using System ;
2
+ using System . Diagnostics ;
3
+ using System . Net ;
2
4
using System . Net . Sockets ;
3
5
using RCONServerLib . Utils ;
4
6
@@ -9,18 +11,50 @@ namespace RCONServerLib
9
11
/// </summary>
10
12
internal class RemoteConClient
11
13
{
14
+ /// <summary>
15
+ /// The maximum packet size to receive
16
+ /// </summary>
12
17
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>
13
27
private readonly NetworkStream _ns ;
28
+
29
+ /// <summary>
30
+ /// Reference to RemoteConServer for getting settings
31
+ /// </summary>
14
32
private readonly RemoteConServer _remoteConServer ;
33
+
34
+ /// <summary>
35
+ /// The TCP Client
36
+ /// </summary>
15
37
private readonly TcpClient _tcp ;
16
- internal bool Authenticated ;
38
+
39
+ /// <summary>
40
+ /// How many failed login attempts the client has
41
+ /// </summary>
17
42
private int _authTries ;
18
43
44
+ /// <summary>
45
+ /// A buffer containing the packet
46
+ /// </summary>
19
47
private byte [ ] _buffer ;
20
48
49
+ /// <summary>
50
+ /// Wether or not the client is connected
51
+ /// </summary>
21
52
private bool _connected ;
22
53
23
- private readonly bool _isUnitTest ;
54
+ /// <summary>
55
+ /// Has the client been successfully authenticated
56
+ /// </summary>
57
+ internal bool Authenticated ;
24
58
25
59
public RemoteConClient ( TcpClient tcp , RemoteConServer remoteConServer )
26
60
{
@@ -64,7 +98,7 @@ private void CloseConnection()
64
98
{
65
99
if ( _isUnitTest )
66
100
return ;
67
-
101
+
68
102
_connected = false ;
69
103
70
104
if ( ! _tcp . Connected )
@@ -83,7 +117,7 @@ private void SendPacket(RemoteConPacket packet)
83
117
{
84
118
if ( _isUnitTest )
85
119
return ;
86
-
120
+
87
121
if ( ! _connected )
88
122
throw new Exception ( "Not connected." ) ;
89
123
@@ -149,86 +183,104 @@ private void OnPacket(IAsyncResult result)
149
183
}
150
184
151
185
/// <summary>
152
- /// Parses raw bytes to RemoteConPacket
186
+ /// Parses raw bytes to RemoteConPacket
153
187
/// </summary>
154
188
/// <param name="rawPacket"></param>
155
189
internal void ParsePacket ( byte [ ] rawPacket )
156
190
{
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
161
192
{
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 )
163
197
{
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
+ }
168
204
169
- _authTries ++ ;
205
+ _authTries ++ ;
170
206
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
+ }
174
223
175
224
if ( ! _remoteConServer . SendAuthImmediately )
176
225
SendPacket ( new RemoteConPacket ( packet . Id , RemoteConPacket . PacketType . ResponseValue , "" ) ) ;
177
226
178
- SendPacket ( new RemoteConPacket ( packet . Id , RemoteConPacket . PacketType . ExecCommand , "" ) ) ;
227
+ SendPacket ( new RemoteConPacket ( - 1 , RemoteConPacket . PacketType . ExecCommand , "" ) ) ;
228
+
179
229
return ;
180
230
}
181
-
182
- if ( _authTries >= _remoteConServer . MaxPasswordTries )
231
+
232
+ // Invalid packet type.
233
+ if ( packet . Type != RemoteConPacket . PacketType . ExecCommand )
183
234
{
184
- CloseConnection ( ) ;
235
+ if ( _isUnitTest )
236
+ throw new InvalidPacketTypeException ( ) ;
237
+
238
+ if ( _remoteConServer . InvalidPacketKick )
239
+ CloseConnection ( ) ;
185
240
return ;
186
241
}
187
242
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 ( ) ;
190
247
191
- SendPacket ( new RemoteConPacket ( - 1 , RemoteConPacket . PacketType . ExecCommand , "" ) ) ;
248
+ if ( _remoteConServer . EmptyPayloadKick )
249
+ CloseConnection ( ) ;
250
+ return ;
251
+ }
192
252
193
- return ;
194
- }
253
+ var args = ArgumentParser . ParseLine ( packet . Payload ) ;
254
+ var cmd = args [ 0 ] ;
255
+ args . RemoveAt ( 0 ) ;
195
256
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
+ }
216
264
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
+ }
225
278
}
226
- else
279
+ catch ( Exception e )
227
280
{
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 ( ) ;
232
284
}
233
285
}
234
286
}
0 commit comments