aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim.RegionServer/ClientView.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim.RegionServer/ClientView.cs (renamed from OpenSim.RegionServer/SimClient.cs)303
1 files changed, 31 insertions, 272 deletions
diff --git a/OpenSim.RegionServer/SimClient.cs b/OpenSim.RegionServer/ClientView.cs
index 3b243cf..a97049d 100644
--- a/OpenSim.RegionServer/SimClient.cs
+++ b/OpenSim.RegionServer/ClientView.cs
@@ -44,43 +44,31 @@ using OpenSim.Assets;
44 44
45namespace OpenSim 45namespace OpenSim
46{ 46{
47 public delegate bool PacketMethod(SimClient simClient, Packet packet); 47 public delegate bool PacketMethod(ClientView simClient, Packet packet);
48 48
49 /// <summary> 49 /// <summary>
50 /// Handles new client connections 50 /// Handles new client connections
51 /// Constructor takes a single Packet and authenticates everything 51 /// Constructor takes a single Packet and authenticates everything
52 /// </summary> 52 /// </summary>
53 public partial class SimClient 53 public partial class ClientView : ClientViewBase
54 { 54 {
55 public LLUUID AgentID; 55 public LLUUID AgentID;
56 public LLUUID SessionID; 56 public LLUUID SessionID;
57 public LLUUID SecureSessionID = LLUUID.Zero; 57 public LLUUID SecureSessionID = LLUUID.Zero;
58 public bool m_child; 58 public bool m_child;
59 public uint CircuitCode;
60 public world.Avatar ClientAvatar; 59 public world.Avatar ClientAvatar;
61 private UseCircuitCodePacket cirpack; 60 private UseCircuitCodePacket cirpack;
62 public Thread ClientThread; 61 public Thread ClientThread;
63 public EndPoint userEP;
64 public LLVector3 startpos; 62 public LLVector3 startpos;
65 private BlockingQueue<QueItem> PacketQueue; 63
66 private Dictionary<uint, uint> PendingAcks = new Dictionary<uint, uint>();
67 private Dictionary<uint, Packet> NeedAck = new Dictionary<uint, Packet>();
68 //private Dictionary<LLUUID, AssetBase> UploadedAssets = new Dictionary<LLUUID, AssetBase>();
69 private System.Timers.Timer AckTimer;
70 private uint Sequence = 0;
71 private object SequenceLock = new object();
72 private const int MAX_APPENDED_ACKS = 10;
73 private const int RESEND_TIMEOUT = 4000;
74 private const int MAX_SEQUENCE = 0xFFFFFF;
75 private AgentAssetUpload UploadAssets; 64 private AgentAssetUpload UploadAssets;
76 private LLUUID newAssetFolder = LLUUID.Zero; 65 private LLUUID newAssetFolder = LLUUID.Zero;
77 private bool debug = false; 66 private bool debug = false;
78 private World m_world; 67 private World m_world;
79 private Dictionary<uint, SimClient> m_clientThreads; 68 private Dictionary<uint, ClientView> m_clientThreads;
80 private AssetCache m_assetCache; 69 private AssetCache m_assetCache;
81 private IGridServer m_gridServer; 70 private IGridServer m_gridServer;
82 private IUserServer m_userServer = null; 71 private IUserServer m_userServer = null;
83 private OpenSimNetworkHandler m_networkServer;
84 private InventoryCache m_inventoryCache; 72 private InventoryCache m_inventoryCache;
85 public bool m_sandboxMode; 73 public bool m_sandboxMode;
86 private int cachedtextureserial = 0; 74 private int cachedtextureserial = 0;
@@ -99,7 +87,7 @@ namespace OpenSim
99 } 87 }
100 } 88 }
101 89
102 public SimClient(EndPoint remoteEP, UseCircuitCodePacket initialcirpack, World world, Dictionary<uint, SimClient> clientThreads, AssetCache assetCache, IGridServer gridServer, OpenSimNetworkHandler application, InventoryCache inventoryCache, bool sandboxMode, bool child, RegionInfo regionDat, AuthenticateSessionsBase authenSessions) 90 public ClientView(EndPoint remoteEP, UseCircuitCodePacket initialcirpack, World world, Dictionary<uint, ClientView> clientThreads, AssetCache assetCache, IGridServer gridServer, OpenSimNetworkHandler application, InventoryCache inventoryCache, bool sandboxMode, bool child, RegionInfo regionDat, AuthenticateSessionsBase authenSessions)
103 { 91 {
104 m_world = world; 92 m_world = world;
105 m_clientThreads = clientThreads; 93 m_clientThreads = clientThreads;
@@ -170,7 +158,7 @@ namespace OpenSim
170 kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1]; 158 kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1];
171 kill.ObjectData[0] = new KillObjectPacket.ObjectDataBlock(); 159 kill.ObjectData[0] = new KillObjectPacket.ObjectDataBlock();
172 kill.ObjectData[0].ID = this.ClientAvatar.localid; 160 kill.ObjectData[0].ID = this.ClientAvatar.localid;
173 foreach (SimClient client in m_clientThreads.Values) 161 foreach (ClientView client in m_clientThreads.Values)
174 { 162 {
175 client.OutPacket(kill); 163 client.OutPacket(kill);
176 } 164 }
@@ -247,246 +235,6 @@ namespace OpenSim
247 235
248 # endregion 236 # endregion
249 237
250 # region Low Level Packet Methods
251
252 private void ack_pack(Packet Pack)
253 {
254 if (Pack.Header.Reliable)
255 {
256 libsecondlife.Packets.PacketAckPacket ack_it = new PacketAckPacket();
257 ack_it.Packets = new PacketAckPacket.PacketsBlock[1];
258 ack_it.Packets[0] = new PacketAckPacket.PacketsBlock();
259 ack_it.Packets[0].ID = Pack.Header.Sequence;
260 ack_it.Header.Reliable = false;
261
262 OutPacket(ack_it);
263
264 }
265 /*
266 if (Pack.Header.Reliable)
267 {
268 lock (PendingAcks)
269 {
270 uint sequence = (uint)Pack.Header.Sequence;
271 if (!PendingAcks.ContainsKey(sequence)) { PendingAcks[sequence] = sequence; }
272 }
273 }*/
274 }
275
276 private void ResendUnacked()
277 {
278 int now = Environment.TickCount;
279
280 lock (NeedAck)
281 {
282 foreach (Packet packet in NeedAck.Values)
283 {
284 if ((now - packet.TickCount > RESEND_TIMEOUT) && (!packet.Header.Resent))
285 {
286 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.VERBOSE, "Resending " + packet.Type.ToString() + " packet, " +
287 (now - packet.TickCount) + "ms have passed");
288
289 packet.Header.Resent = true;
290 OutPacket(packet);
291 }
292 }
293 }
294 }
295
296 private void SendAcks()
297 {
298 lock (PendingAcks)
299 {
300 if (PendingAcks.Count > 0)
301 {
302 if (PendingAcks.Count > 250)
303 {
304 // FIXME: Handle the odd case where we have too many pending ACKs queued up
305 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.VERBOSE, "Too many ACKs queued up!");
306 return;
307 }
308
309 //OpenSim.Framework.Console.MainConsole.Instance.WriteLine("Sending PacketAck");
310
311
312 int i = 0;
313 PacketAckPacket acks = new PacketAckPacket();
314 acks.Packets = new PacketAckPacket.PacketsBlock[PendingAcks.Count];
315
316 foreach (uint ack in PendingAcks.Values)
317 {
318 acks.Packets[i] = new PacketAckPacket.PacketsBlock();
319 acks.Packets[i].ID = ack;
320 i++;
321 }
322
323 acks.Header.Reliable = false;
324 OutPacket(acks);
325
326 PendingAcks.Clear();
327 }
328 }
329 }
330
331 private void AckTimer_Elapsed(object sender, ElapsedEventArgs ea)
332 {
333 SendAcks();
334 ResendUnacked();
335 }
336
337 # endregion
338
339 #region Packet Queue Processing
340
341 protected virtual void ProcessOutPacket(Packet Pack)
342 {
343 // Keep track of when this packet was sent out
344 Pack.TickCount = Environment.TickCount;
345
346 if (!Pack.Header.Resent)
347 {
348 // Set the sequence number
349 lock (SequenceLock)
350 {
351 if (Sequence >= MAX_SEQUENCE)
352 Sequence = 1;
353 else
354 Sequence++;
355 Pack.Header.Sequence = Sequence;
356 }
357
358 if (Pack.Header.Reliable) //DIRTY HACK
359 {
360 lock (NeedAck)
361 {
362 if (!NeedAck.ContainsKey(Pack.Header.Sequence))
363 {
364 try
365 {
366 NeedAck.Add(Pack.Header.Sequence, Pack);
367 }
368 catch (Exception e) // HACKY
369 {
370 e.ToString();
371 // Ignore
372 // Seems to throw a exception here occasionally
373 // of 'duplicate key' despite being locked.
374 // !?!?!?
375 }
376 }
377 else
378 {
379 // Client.Log("Attempted to add a duplicate sequence number (" +
380 // packet.Header.Sequence + ") to the NeedAck dictionary for packet type " +
381 // packet.Type.ToString(), Helpers.LogLevel.Warning);
382 }
383 }
384
385 // Don't append ACKs to resent packets, in case that's what was causing the
386 // delivery to fail
387 if (!Pack.Header.Resent)
388 {
389 // Append any ACKs that need to be sent out to this packet
390 lock (PendingAcks)
391 {
392 if (PendingAcks.Count > 0 && PendingAcks.Count < MAX_APPENDED_ACKS &&
393 Pack.Type != PacketType.PacketAck &&
394 Pack.Type != PacketType.LogoutRequest)
395 {
396 Pack.Header.AckList = new uint[PendingAcks.Count];
397 int i = 0;
398
399 foreach (uint ack in PendingAcks.Values)
400 {
401 Pack.Header.AckList[i] = ack;
402 i++;
403 }
404
405 PendingAcks.Clear();
406 Pack.Header.AppendedAcks = true;
407 }
408 }
409 }
410 }
411 }
412
413 byte[] ZeroOutBuffer = new byte[4096];
414 byte[] sendbuffer;
415 sendbuffer = Pack.ToBytes();
416
417 try
418 {
419 if (Pack.Header.Zerocoded)
420 {
421 int packetsize = Helpers.ZeroEncode(sendbuffer, sendbuffer.Length, ZeroOutBuffer);
422 m_networkServer.SendPacketTo(ZeroOutBuffer, packetsize, SocketFlags.None, CircuitCode);//userEP);
423 }
424 else
425 {
426 m_networkServer.SendPacketTo(sendbuffer, sendbuffer.Length, SocketFlags.None, CircuitCode); //userEP);
427 }
428 }
429 catch (Exception)
430 {
431 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM, "OpenSimClient.cs:ProcessOutPacket() - WARNING: Socket exception occurred on connection " + userEP.ToString() + " - killing thread");
432 ClientThread.Abort();
433 }
434
435 }
436
437 public virtual void InPacket(Packet NewPack)
438 {
439 // Handle appended ACKs
440 if (NewPack.Header.AppendedAcks)
441 {
442 lock (NeedAck)
443 {
444 foreach (uint ack in NewPack.Header.AckList)
445 {
446 NeedAck.Remove(ack);
447 }
448 }
449 }
450
451 // Handle PacketAck packets
452 if (NewPack.Type == PacketType.PacketAck)
453 {
454 PacketAckPacket ackPacket = (PacketAckPacket)NewPack;
455
456 lock (NeedAck)
457 {
458 foreach (PacketAckPacket.PacketsBlock block in ackPacket.Packets)
459 {
460 NeedAck.Remove(block.ID);
461 }
462 }
463 }
464 else if ((NewPack.Type == PacketType.StartPingCheck))
465 {
466 //reply to pingcheck
467 libsecondlife.Packets.StartPingCheckPacket startPing = (libsecondlife.Packets.StartPingCheckPacket)NewPack;
468 libsecondlife.Packets.CompletePingCheckPacket endPing = new CompletePingCheckPacket();
469 endPing.PingID.PingID = startPing.PingID.PingID;
470 OutPacket(endPing);
471 }
472 else
473 {
474 QueItem item = new QueItem();
475 item.Packet = NewPack;
476 item.Incoming = true;
477 this.PacketQueue.Enqueue(item);
478 }
479
480 }
481
482 public virtual void OutPacket(Packet NewPack)
483 {
484 QueItem item = new QueItem();
485 item.Packet = NewPack;
486 item.Incoming = false;
487 this.PacketQueue.Enqueue(item);
488 }
489
490 protected virtual void ClientLoop() 238 protected virtual void ClientLoop()
491 { 239 {
492 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "OpenSimClient.cs:ClientLoop() - Entered loop"); 240 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "OpenSimClient.cs:ClientLoop() - Entered loop");
@@ -506,8 +254,6 @@ namespace OpenSim
506 } 254 }
507 } 255 }
508 256
509 #endregion
510
511 # region Setup 257 # region Setup
512 258
513 protected virtual void InitNewClient() 259 protected virtual void InitNewClient()
@@ -556,6 +302,31 @@ namespace OpenSim
556 } 302 }
557 # endregion 303 # endregion
558 304
305
306 protected override void KillThread()
307 {
308 this.ClientThread.Abort();
309 }
310
311 #region World/Avatar To Viewer Methods
312
313 public void SendChatMessage(byte[] message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID)
314 {
315 System.Text.Encoding enc = System.Text.Encoding.ASCII;
316 libsecondlife.Packets.ChatFromSimulatorPacket reply = new ChatFromSimulatorPacket();
317 reply.ChatData.Audible = 1;
318 reply.ChatData.Message = message;
319 reply.ChatData.ChatType = type;
320 reply.ChatData.SourceType = 1;
321 reply.ChatData.Position = fromPos;
322 reply.ChatData.FromName = enc.GetBytes(fromName + "\0");
323 reply.ChatData.OwnerID = fromAgentID;
324 reply.ChatData.SourceID = fromAgentID;
325
326 this.OutPacket(reply);
327 }
328 #endregion
329
559 #region Inventory Creation 330 #region Inventory Creation
560 private void SetupInventory(AuthenticateResponse sessionInfo) 331 private void SetupInventory(AuthenticateResponse sessionInfo)
561 { 332 {
@@ -646,17 +417,5 @@ namespace OpenSim
646 } 417 }
647 #endregion 418 #endregion
648 419
649 #region Nested Classes
650
651 public class QueItem
652 {
653 public QueItem()
654 {
655 }
656
657 public Packet Packet;
658 public bool Incoming;
659 }
660 #endregion
661 } 420 }
662} 421}