aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim.RegionServer/SimClient.cs
diff options
context:
space:
mode:
authorMW2007-05-21 16:06:58 +0000
committerMW2007-05-21 16:06:58 +0000
commitfe46b045f75dec5ecdd0a29273c70df3e6ea540e (patch)
tree554c0fb47e513fc6a89f496d99b7b67de24edde7 /OpenSim.RegionServer/SimClient.cs
parentIncreased version number to 0.2! ZOMG! (diff)
downloadopensim-SC-fe46b045f75dec5ecdd0a29273c70df3e6ea540e.zip
opensim-SC-fe46b045f75dec5ecdd0a29273c70df3e6ea540e.tar.gz
opensim-SC-fe46b045f75dec5ecdd0a29273c70df3e6ea540e.tar.bz2
opensim-SC-fe46b045f75dec5ecdd0a29273c70df3e6ea540e.tar.xz
Start of a redesign of SimClient (now renamed ClientView)/World/Avatar/Prim , switching to a event based system (World/Avatar register as event handlers). It is possible that I've broke something with this commit but it doesn't matter as I'll just hide and no one will find me.
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}