diff options
Diffstat (limited to '')
-rw-r--r-- | src/OpenSimClient.cs | 510 |
1 files changed, 0 insertions, 510 deletions
diff --git a/src/OpenSimClient.cs b/src/OpenSimClient.cs deleted file mode 100644 index 497df00..0000000 --- a/src/OpenSimClient.cs +++ /dev/null | |||
@@ -1,510 +0,0 @@ | |||
1 | /* | ||
2 | Copyright (c) OpenSim project, http://osgrid.org/ | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions are met: | ||
6 | * * Redistributions of source code must retain the above copyright | ||
7 | * notice, this list of conditions and the following disclaimer. | ||
8 | * * Redistributions in binary form must reproduce the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer in the | ||
10 | * documentation and/or other materials provided with the distribution. | ||
11 | * * Neither the name of the <organization> nor the | ||
12 | * names of its contributors may be used to endorse or promote products | ||
13 | * derived from this software without specific prior written permission. | ||
14 | * | ||
15 | * THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY | ||
16 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
17 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
18 | * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY | ||
19 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
20 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
22 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
24 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
25 | */ | ||
26 | |||
27 | using System; | ||
28 | using System.Collections; | ||
29 | using System.Collections.Generic; | ||
30 | using libsecondlife; | ||
31 | using libsecondlife.Packets; | ||
32 | using System.Net; | ||
33 | using System.Net.Sockets; | ||
34 | using System.IO; | ||
35 | using System.Threading; | ||
36 | using System.Timers; | ||
37 | |||
38 | namespace OpenSim | ||
39 | { | ||
40 | /// <summary> | ||
41 | /// Handles new client connections | ||
42 | /// Constructor takes a single Packet and authenticates everything | ||
43 | /// </summary> | ||
44 | public class OpenSimClient | ||
45 | { | ||
46 | |||
47 | public LLUUID AgentID; | ||
48 | public LLUUID SessionID; | ||
49 | public uint CircuitCode; | ||
50 | public world.Avatar ClientAvatar; | ||
51 | private UseCircuitCodePacket cirpack; | ||
52 | private Thread ClientThread; | ||
53 | public EndPoint userEP; | ||
54 | private BlockingQueue<QueItem> PacketQueue; | ||
55 | private BlockingQueue<TransferRequestPacket> AssetRequests; | ||
56 | private Dictionary<uint, uint> PendingAcks = new Dictionary<uint, uint>(); | ||
57 | private Dictionary<uint, Packet> NeedAck = new Dictionary<uint, Packet>(); | ||
58 | private System.Timers.Timer AckTimer; | ||
59 | private uint Sequence = 0; | ||
60 | private object SequenceLock = new object(); | ||
61 | private const int MAX_APPENDED_ACKS = 10; | ||
62 | private const int RESEND_TIMEOUT = 4000; | ||
63 | private const int MAX_SEQUENCE = 0xFFFFFF; | ||
64 | //private Queue<uint> Inbox; | ||
65 | |||
66 | public void ack_pack(Packet Pack) | ||
67 | { | ||
68 | //libsecondlife.Packets.PacketAckPacket ack_it = new PacketAckPacket(); | ||
69 | //ack_it.Packets = new PacketAckPacket.PacketsBlock[1]; | ||
70 | //ack_it.Packets[0] = new PacketAckPacket.PacketsBlock(); | ||
71 | //ack_it.Packets[0].ID = Pack.Header.ID; | ||
72 | //ack_it.Header.Reliable = false; | ||
73 | |||
74 | //OutPacket(ack_it); | ||
75 | |||
76 | if (Pack.Header.Reliable) | ||
77 | { | ||
78 | lock (PendingAcks) | ||
79 | { | ||
80 | uint sequence = (uint)Pack.Header.Sequence; | ||
81 | if (!PendingAcks.ContainsKey(sequence)) { PendingAcks[sequence] = sequence; } | ||
82 | } | ||
83 | } | ||
84 | } | ||
85 | |||
86 | public void AssetLoader() | ||
87 | { | ||
88 | if (OpenSim_Main.cfg.sandbox == false) | ||
89 | { | ||
90 | WebResponse AssetResponse; | ||
91 | byte[] idata; | ||
92 | |||
93 | OpenSim_Main.localcons.WriteLine("OpenSimClient.cs:AssetLoader() - Starting new thread"); | ||
94 | TransferRequestPacket reqPacket = AssetRequests.Dequeue(); | ||
95 | OpenSim_Main.localcons.WriteLine("OpenSimClient.cs:AssetLoader() - Got a request, processing it"); | ||
96 | LLUUID AssetID = new LLUUID(reqPacket.TransferInfo.Params, 0); | ||
97 | |||
98 | try | ||
99 | { | ||
100 | WebRequest AssetLoad = WebRequest.Create(OpenSim_Main.cfg.AssetURL + "getasset/" + OpenSim_Main.cfg.AssetSendKey + "/" + AssetID + "/data"); | ||
101 | AssetResponse = AssetLoad.GetResponse(); | ||
102 | idata = new byte[(int)AssetResponse.ContentLength]; | ||
103 | BinaryReader br = new BinaryReader(AssetResponse.GetResponseStream()); | ||
104 | idata = br.ReadBytes((int)AssetResponse.ContentLength); | ||
105 | br.Close(); | ||
106 | } | ||
107 | catch (Exception e) | ||
108 | { | ||
109 | Console.WriteLine(e.ToString()); | ||
110 | return; | ||
111 | } | ||
112 | |||
113 | TransferInfoPacket Transfer = new TransferInfoPacket(); | ||
114 | Transfer.TransferInfo.ChannelType = 2; | ||
115 | Transfer.TransferInfo.Status = 0; | ||
116 | Transfer.TransferInfo.TargetType = 0; | ||
117 | Transfer.TransferInfo.Params = reqPacket.TransferInfo.Params; | ||
118 | Transfer.TransferInfo.Size = (int)AssetResponse.ContentLength; | ||
119 | Transfer.TransferInfo.TransferID = reqPacket.TransferInfo.TransferID; | ||
120 | |||
121 | OutPacket(Transfer); | ||
122 | |||
123 | TransferPacketPacket TransferPacket = new TransferPacketPacket(); | ||
124 | TransferPacket.TransferData.Packet = 0; | ||
125 | TransferPacket.TransferData.ChannelType = 2; | ||
126 | TransferPacket.TransferData.TransferID = reqPacket.TransferInfo.TransferID; | ||
127 | |||
128 | if (AssetResponse.ContentLength > 1000) | ||
129 | { | ||
130 | byte[] chunk = new byte[1000]; | ||
131 | Array.Copy(idata, chunk, 1000); | ||
132 | TransferPacket.TransferData.Data = chunk; | ||
133 | TransferPacket.TransferData.Status = 0; | ||
134 | OutPacket(TransferPacket); | ||
135 | |||
136 | TransferPacket = new TransferPacketPacket(); | ||
137 | TransferPacket.TransferData.Packet = 1; | ||
138 | TransferPacket.TransferData.ChannelType = 2; | ||
139 | TransferPacket.TransferData.TransferID = reqPacket.TransferInfo.TransferID; | ||
140 | byte[] chunk1 = new byte[(idata.Length - 1000)]; | ||
141 | Array.Copy(idata, 1000, chunk1, 0, chunk1.Length); | ||
142 | TransferPacket.TransferData.Data = chunk1; | ||
143 | TransferPacket.TransferData.Status = 1; | ||
144 | OutPacket(TransferPacket); | ||
145 | } | ||
146 | else | ||
147 | { | ||
148 | TransferPacket.TransferData.Status = 1; | ||
149 | TransferPacket.TransferData.Data = idata; | ||
150 | OutPacket(TransferPacket); | ||
151 | } | ||
152 | AssetResponse.Close(); | ||
153 | } | ||
154 | } | ||
155 | |||
156 | public void Logout() | ||
157 | { | ||
158 | // TODO - kill any AssetLoaders | ||
159 | ClientThread.Abort(); | ||
160 | } | ||
161 | |||
162 | public void ProcessInPacket(Packet Pack) | ||
163 | { | ||
164 | ack_pack(Pack); | ||
165 | switch (Pack.Type) | ||
166 | { | ||
167 | case PacketType.CompleteAgentMovement: | ||
168 | ClientAvatar.CompleteMovement(OpenSim_Main.local_world); | ||
169 | ClientAvatar.SendInitialPosition(); | ||
170 | break; | ||
171 | case PacketType.RegionHandshakeReply: | ||
172 | OpenSim_Main.local_world.SendLayerData(this); | ||
173 | break; | ||
174 | case PacketType.AgentWearablesRequest: | ||
175 | ClientAvatar.SendInitialAppearance(); | ||
176 | break; | ||
177 | case PacketType.TransferRequest: | ||
178 | OpenSim_Main.localcons.WriteLine("OpenSimClient.cs:ProcessInPacket() - Got transfer request"); | ||
179 | // We put transfer requests into a big queue and then spawn a thread for each new one | ||
180 | TransferRequestPacket transfer = (TransferRequestPacket)Pack; | ||
181 | AssetRequests.Enqueue(transfer); | ||
182 | Thread AssetLoaderThread = new Thread(new ThreadStart(AssetLoader)); | ||
183 | AssetLoaderThread.Start(); | ||
184 | break; | ||
185 | case PacketType.LogoutRequest: | ||
186 | OpenSim_Main.localcons.WriteLine("OpenSimClient.cs:ProcessInPacket() - Got a logout request"); | ||
187 | lock (OpenSim_Main.local_world.Entities) | ||
188 | { | ||
189 | OpenSim_Main.local_world.Entities.Remove(this.AgentID); | ||
190 | } | ||
191 | |||
192 | if (OpenSim_Main.cfg.sandbox == false) | ||
193 | { | ||
194 | WebRequest DeleteSession = WebRequest.Create(OpenSim_Main.cfg.GridURL + "/usersessions/" + OpenSim_Main.cfg.GridSendKey + "/" + this.AgentID.ToString() + this.CircuitCode.ToString() + "/delete"); | ||
195 | WebResponse GridResponse = DeleteSession.GetResponse(); | ||
196 | StreamReader sr = new StreamReader(GridResponse.GetResponseStream()); | ||
197 | String grTest = sr.ReadLine(); | ||
198 | sr.Close(); | ||
199 | GridResponse.Close(); | ||
200 | OpenSim_Main.localcons.WriteLine("DEBUG: " + grTest); | ||
201 | } | ||
202 | this.ClientThread.Abort(); | ||
203 | break; | ||
204 | case PacketType.AgentUpdate: | ||
205 | ClientAvatar.HandleAgentUpdate((AgentUpdatePacket)Pack); | ||
206 | break; | ||
207 | case PacketType.ChatFromViewer: | ||
208 | ChatFromViewerPacket inchatpack = (ChatFromViewerPacket)Pack; | ||
209 | if (Helpers.FieldToString(inchatpack.ChatData.Message) == "") break; | ||
210 | |||
211 | System.Text.Encoding _enc = System.Text.Encoding.ASCII; | ||
212 | libsecondlife.Packets.ChatFromSimulatorPacket reply = new ChatFromSimulatorPacket(); | ||
213 | reply.ChatData.Audible = 1; | ||
214 | reply.ChatData.Message = inchatpack.ChatData.Message; | ||
215 | reply.ChatData.ChatType = 1; | ||
216 | reply.ChatData.SourceType = 1; | ||
217 | reply.ChatData.Position = this.ClientAvatar.position; | ||
218 | reply.ChatData.FromName = _enc.GetBytes(this.ClientAvatar.firstname + " " + this.ClientAvatar.lastname + "\0"); | ||
219 | reply.ChatData.OwnerID = this.AgentID; | ||
220 | reply.ChatData.SourceID = this.AgentID; | ||
221 | |||
222 | |||
223 | |||
224 | foreach (OpenSimClient client in OpenSim_Main.sim.ClientThreads.Values) | ||
225 | { | ||
226 | client.OutPacket(reply); | ||
227 | } | ||
228 | break; | ||
229 | } | ||
230 | } | ||
231 | |||
232 | private void ResendUnacked() | ||
233 | { | ||
234 | int now = Environment.TickCount; | ||
235 | |||
236 | lock (NeedAck) | ||
237 | { | ||
238 | foreach (Packet packet in NeedAck.Values) | ||
239 | { | ||
240 | if (now - packet.TickCount > RESEND_TIMEOUT) | ||
241 | { | ||
242 | |||
243 | packet.Header.Resent = true; | ||
244 | OutPacket(packet); | ||
245 | } | ||
246 | } | ||
247 | } | ||
248 | } | ||
249 | |||
250 | private void SendAcks() | ||
251 | { | ||
252 | lock (PendingAcks) | ||
253 | { | ||
254 | if (PendingAcks.Count > 0) | ||
255 | { | ||
256 | if (PendingAcks.Count > 250) | ||
257 | { | ||
258 | return; | ||
259 | } | ||
260 | |||
261 | |||
262 | |||
263 | int i = 0; | ||
264 | PacketAckPacket acks = new PacketAckPacket(); | ||
265 | acks.Packets = new PacketAckPacket.PacketsBlock[PendingAcks.Count]; | ||
266 | |||
267 | foreach (uint ack in PendingAcks.Values) | ||
268 | { | ||
269 | acks.Packets[i] = new PacketAckPacket.PacketsBlock(); | ||
270 | acks.Packets[i].ID = ack; | ||
271 | i++; | ||
272 | } | ||
273 | |||
274 | acks.Header.Reliable = false; | ||
275 | OutPacket(acks); | ||
276 | |||
277 | PendingAcks.Clear(); | ||
278 | } | ||
279 | } | ||
280 | } | ||
281 | |||
282 | private void AckTimer_Elapsed(object sender, ElapsedEventArgs ea) | ||
283 | { | ||
284 | SendAcks(); | ||
285 | ResendUnacked(); | ||
286 | } | ||
287 | |||
288 | public void ProcessOutPacket(Packet Pack) | ||
289 | { | ||
290 | |||
291 | // Keep track of when this packet was sent out | ||
292 | Pack.TickCount = Environment.TickCount; | ||
293 | |||
294 | if (!Pack.Header.Resent) | ||
295 | { | ||
296 | // Set the sequence number | ||
297 | lock (SequenceLock) | ||
298 | { | ||
299 | if (Sequence >= MAX_SEQUENCE) | ||
300 | Sequence = 1; | ||
301 | else | ||
302 | Sequence++; | ||
303 | Pack.Header.Sequence = Sequence; | ||
304 | } | ||
305 | |||
306 | if (Pack.Header.Reliable) //DIRTY HACK | ||
307 | { | ||
308 | lock (NeedAck) | ||
309 | { | ||
310 | if (!NeedAck.ContainsKey(Pack.Header.Sequence)) | ||
311 | { | ||
312 | NeedAck.Add(Pack.Header.Sequence, Pack); | ||
313 | } | ||
314 | else | ||
315 | { | ||
316 | // Client.Log("Attempted to add a duplicate sequence number (" + | ||
317 | // packet.Header.Sequence + ") to the NeedAck dictionary for packet type " + | ||
318 | // packet.Type.ToString(), Helpers.LogLevel.Warning); | ||
319 | } | ||
320 | } | ||
321 | |||
322 | // Don't append ACKs to resent packets, in case that's what was causing the | ||
323 | // delivery to fail | ||
324 | if (!Pack.Header.Resent) | ||
325 | { | ||
326 | // Append any ACKs that need to be sent out to this packet | ||
327 | lock (PendingAcks) | ||
328 | { | ||
329 | if (PendingAcks.Count > 0 && PendingAcks.Count < MAX_APPENDED_ACKS && | ||
330 | Pack.Type != PacketType.PacketAck && | ||
331 | Pack.Type != PacketType.LogoutRequest) | ||
332 | { | ||
333 | Pack.Header.AckList = new uint[PendingAcks.Count]; | ||
334 | int i = 0; | ||
335 | |||
336 | foreach (uint ack in PendingAcks.Values) | ||
337 | { | ||
338 | Pack.Header.AckList[i] = ack; | ||
339 | i++; | ||
340 | } | ||
341 | |||
342 | PendingAcks.Clear(); | ||
343 | Pack.Header.AppendedAcks = true; | ||
344 | } | ||
345 | } | ||
346 | } | ||
347 | } | ||
348 | } | ||
349 | |||
350 | |||
351 | byte[] ZeroOutBuffer = new byte[4096]; | ||
352 | byte[] sendbuffer; | ||
353 | sendbuffer = Pack.ToBytes(); | ||
354 | |||
355 | try | ||
356 | { | ||
357 | if (Pack.Header.Zerocoded) | ||
358 | { | ||
359 | int packetsize = Helpers.ZeroEncode(sendbuffer, sendbuffer.Length, ZeroOutBuffer); | ||
360 | OpenSim_Main.Server.SendTo(ZeroOutBuffer, packetsize, SocketFlags.None, userEP); | ||
361 | } | ||
362 | else | ||
363 | { | ||
364 | OpenSim_Main.Server.SendTo(sendbuffer, sendbuffer.Length, SocketFlags.None, userEP); | ||
365 | } | ||
366 | } | ||
367 | catch (Exception) | ||
368 | { | ||
369 | OpenSim_Main.localcons.WriteLine("OpenSimClient.cs:ProcessOutPacket() - WARNING: Socket exception occurred on connection " + userEP.ToString() + " - killing thread"); | ||
370 | ClientThread.Abort(); | ||
371 | } | ||
372 | |||
373 | } | ||
374 | |||
375 | public void InPacket(Packet NewPack) | ||
376 | { | ||
377 | // Handle appended ACKs | ||
378 | if (NewPack.Header.AppendedAcks) | ||
379 | { | ||
380 | lock (NeedAck) | ||
381 | { | ||
382 | foreach (uint ack in NewPack.Header.AckList) | ||
383 | { | ||
384 | OpenSim_Main.localcons.WriteLine("Got appended ack: " + ack); | ||
385 | NeedAck.Remove(ack); | ||
386 | } | ||
387 | } | ||
388 | } | ||
389 | |||
390 | // Handle PacketAck packets | ||
391 | if (NewPack.Type == PacketType.PacketAck) | ||
392 | { | ||
393 | PacketAckPacket ackPacket = (PacketAckPacket)NewPack; | ||
394 | |||
395 | lock (NeedAck) | ||
396 | { | ||
397 | foreach (PacketAckPacket.PacketsBlock block in ackPacket.Packets) | ||
398 | { | ||
399 | NeedAck.Remove(block.ID); | ||
400 | } | ||
401 | } | ||
402 | } | ||
403 | else if ((NewPack.Type == PacketType.StartPingCheck)) | ||
404 | { | ||
405 | //reply to pingcheck | ||
406 | libsecondlife.Packets.StartPingCheckPacket startPing = (libsecondlife.Packets.StartPingCheckPacket)NewPack; | ||
407 | libsecondlife.Packets.CompletePingCheckPacket endPing = new CompletePingCheckPacket(); | ||
408 | endPing.PingID.PingID = startPing.PingID.PingID; | ||
409 | OutPacket(endPing); | ||
410 | } | ||
411 | else | ||
412 | { | ||
413 | QueItem item = new QueItem(); | ||
414 | item.Packet = NewPack; | ||
415 | item.Incoming = true; | ||
416 | this.PacketQueue.Enqueue(item); | ||
417 | } | ||
418 | |||
419 | } | ||
420 | |||
421 | public void OutPacket(Packet NewPack) | ||
422 | { | ||
423 | QueItem item = new QueItem(); | ||
424 | item.Packet = NewPack; | ||
425 | item.Incoming = false; | ||
426 | this.PacketQueue.Enqueue(item); | ||
427 | } | ||
428 | |||
429 | public OpenSimClient(EndPoint remoteEP, UseCircuitCodePacket initialcirpack) | ||
430 | { | ||
431 | OpenSim_Main.localcons.WriteLine("OpenSimClient.cs - Started up new client thread to handle incoming request"); | ||
432 | cirpack = initialcirpack; | ||
433 | userEP = remoteEP; | ||
434 | PacketQueue = new BlockingQueue<QueItem>(); | ||
435 | AssetRequests = new BlockingQueue<TransferRequestPacket>(); | ||
436 | AckTimer = new System.Timers.Timer(500); | ||
437 | AckTimer.Elapsed += new ElapsedEventHandler(AckTimer_Elapsed); | ||
438 | AckTimer.Start(); | ||
439 | |||
440 | ClientThread = new Thread(new ThreadStart(AuthUser)); | ||
441 | ClientThread.IsBackground = true; | ||
442 | ClientThread.Start(); | ||
443 | } | ||
444 | |||
445 | private void ClientLoop() | ||
446 | { | ||
447 | OpenSim_Main.localcons.WriteLine("OpenSimClient.cs:ClientLoop() - Entered loop"); | ||
448 | while (true) | ||
449 | { | ||
450 | QueItem nextPacket = PacketQueue.Dequeue(); | ||
451 | if (nextPacket.Incoming) | ||
452 | { | ||
453 | //is a incoming packet | ||
454 | ProcessInPacket(nextPacket.Packet); | ||
455 | } | ||
456 | else | ||
457 | { | ||
458 | //is a out going packet | ||
459 | ProcessOutPacket(nextPacket.Packet); | ||
460 | } | ||
461 | } | ||
462 | } | ||
463 | |||
464 | private void InitNewClient() | ||
465 | { | ||
466 | OpenSim_Main.localcons.WriteLine("OpenSimClient.cs:InitNewClient() - Adding viewer agent to world"); | ||
467 | OpenSim_Main.local_world.AddViewerAgent(this); | ||
468 | world.Entity tempent = OpenSim_Main.local_world.Entities[this.AgentID]; | ||
469 | this.ClientAvatar = (world.Avatar)tempent; | ||
470 | } | ||
471 | |||
472 | private void AuthUser() | ||
473 | { | ||
474 | if (OpenSim_Main.cfg.sandbox == false) | ||
475 | { | ||
476 | OpenSim_Main.localcons.WriteLine("OpenSimClient.cs:AuthUser() - Authenticating new user request with grid"); | ||
477 | WebRequest CheckSession = WebRequest.Create(OpenSim_Main.cfg.GridURL + "/usersessions/" + OpenSim_Main.cfg.GridSendKey + "/" + cirpack.CircuitCode.ID.ToString() + "/" + cirpack.CircuitCode.Code.ToString() + "/exists"); | ||
478 | OpenSim_Main.localcons.WriteLine(OpenSim_Main.cfg.GridURL); | ||
479 | WebResponse GridResponse = CheckSession.GetResponse(); | ||
480 | StreamReader sr = new StreamReader(GridResponse.GetResponseStream()); | ||
481 | String grTest = sr.ReadLine(); | ||
482 | sr.Close(); | ||
483 | GridResponse.Close(); | ||
484 | if (String.IsNullOrEmpty(grTest) || grTest.Equals("1")) | ||
485 | { // YAY! Valid login | ||
486 | OpenSim_Main.localcons.WriteLine("OpenSimClient.cs:AuthUser() - Got authenticated connection from " + userEP.ToString()); | ||
487 | this.AgentID = cirpack.CircuitCode.ID; | ||
488 | this.SessionID = cirpack.CircuitCode.SessionID; | ||
489 | this.CircuitCode = cirpack.CircuitCode.Code; | ||
490 | InitNewClient(); | ||
491 | ClientLoop(); | ||
492 | } | ||
493 | else | ||
494 | { // Invalid | ||
495 | OpenSim_Main.localcons.WriteLine("OpenSimClient.cs:AuthUser() - New user request denied to " + userEP.ToString()); | ||
496 | ClientThread.Abort(); | ||
497 | } | ||
498 | } | ||
499 | else | ||
500 | { | ||
501 | this.AgentID = cirpack.CircuitCode.ID; | ||
502 | this.SessionID = cirpack.CircuitCode.SessionID; | ||
503 | this.CircuitCode = cirpack.CircuitCode.Code; | ||
504 | InitNewClient(); | ||
505 | ClientLoop(); | ||
506 | } | ||
507 | } | ||
508 | } | ||
509 | |||
510 | } | ||