aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim.RegionServer/SimClient.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim.RegionServer/SimClient.cs621
1 files changed, 621 insertions, 0 deletions
diff --git a/OpenSim.RegionServer/SimClient.cs b/OpenSim.RegionServer/SimClient.cs
new file mode 100644
index 0000000..210e0d9
--- /dev/null
+++ b/OpenSim.RegionServer/SimClient.cs
@@ -0,0 +1,621 @@
1/*
2Copyright (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
27using System;
28using System.Collections;
29using System.Collections.Generic;
30using libsecondlife;
31using libsecondlife.Packets;
32using System.Net;
33using System.Net.Sockets;
34using System.IO;
35using System.Threading;
36using System.Timers;
37using OpenSim.Framework.Interfaces;
38using OpenSim.Framework.Assets;
39using OpenSim.Framework.Inventory;
40using OpenSim.Framework.Utilities;
41using OpenSim.world;
42using OpenSim.Assets;
43
44namespace OpenSim
45{
46 /// <summary>
47 /// Handles new client connections
48 /// Constructor takes a single Packet and authenticates everything
49 /// </summary>
50 public class SimClient
51 {
52
53 public LLUUID AgentID;
54 public LLUUID SessionID;
55 public LLUUID SecureSessionID = LLUUID.Zero;
56 public uint CircuitCode;
57 public world.Avatar ClientAvatar;
58 private UseCircuitCodePacket cirpack;
59 private Thread ClientThread;
60 public EndPoint userEP;
61 private BlockingQueue<QueItem> PacketQueue;
62 private Dictionary<uint, uint> PendingAcks = new Dictionary<uint, uint>();
63 private Dictionary<uint, Packet> NeedAck = new Dictionary<uint, Packet>();
64 //private Dictionary<LLUUID, AssetBase> UploadedAssets = new Dictionary<LLUUID, AssetBase>();
65 private System.Timers.Timer AckTimer;
66 private uint Sequence = 0;
67 private object SequenceLock = new object();
68 private const int MAX_APPENDED_ACKS = 10;
69 private const int RESEND_TIMEOUT = 4000;
70 private const int MAX_SEQUENCE = 0xFFFFFF;
71 private LLUUID newAssetFolder = LLUUID.Zero;
72 private bool debug = false;
73
74 private void ack_pack(Packet Pack)
75 {
76 //libsecondlife.Packets.PacketAckPacket ack_it = new PacketAckPacket();
77 //ack_it.Packets = new PacketAckPacket.PacketsBlock[1];
78 //ack_it.Packets[0] = new PacketAckPacket.PacketsBlock();
79 //ack_it.Packets[0].ID = Pack.Header.ID;
80 //ack_it.Header.Reliable = false;
81
82 //OutPacket(ack_it);
83
84 if (Pack.Header.Reliable)
85 {
86 lock (PendingAcks)
87 {
88 uint sequence = (uint)Pack.Header.Sequence;
89 if (!PendingAcks.ContainsKey(sequence)) { PendingAcks[sequence] = sequence; }
90 }
91 }
92 }
93
94 protected virtual void ProcessInPacket(Packet Pack)
95 {
96 ack_pack(Pack);
97 if (debug)
98 {
99 if (Pack.Type != PacketType.AgentUpdate)
100 {
101 Console.WriteLine(Pack.Type.ToString());
102 }
103 }
104 switch (Pack.Type)
105 {
106 case PacketType.CompleteAgentMovement:
107 ClientAvatar.CompleteMovement(OpenSimRoot.Instance.LocalWorld);
108 ClientAvatar.SendInitialPosition();
109 break;
110 case PacketType.RegionHandshakeReply:
111 OpenSimRoot.Instance.LocalWorld.SendLayerData(this);
112 break;
113 case PacketType.AgentWearablesRequest:
114 ClientAvatar.SendInitialAppearance();
115 foreach (SimClient client in OpenSimRoot.Instance.ClientThreads.Values)
116 {
117 if (client.AgentID != this.AgentID)
118 {
119 ObjectUpdatePacket objupdate = client.ClientAvatar.CreateUpdatePacket();
120 this.OutPacket(objupdate);
121 client.ClientAvatar.SendAppearanceToOtherAgent(this);
122 }
123 }
124 OpenSimRoot.Instance.LocalWorld.GetInitialPrims(this);
125 break;
126 case PacketType.ObjectAdd:
127 OpenSimRoot.Instance.LocalWorld.AddNewPrim((ObjectAddPacket)Pack, this);
128 break;
129 case PacketType.ObjectLink:
130 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(Pack.ToString());
131 break;
132 case PacketType.ObjectScale:
133 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(Pack.ToString());
134 break;
135 case PacketType.ObjectShape:
136 ObjectShapePacket shape = (ObjectShapePacket)Pack;
137 for (int i = 0; i < shape.ObjectData.Length; i++)
138 {
139 foreach (Entity ent in OpenSimRoot.Instance.LocalWorld.Entities.Values)
140 {
141 if (ent.localid == shape.ObjectData[i].ObjectLocalID)
142 {
143 ((OpenSim.world.Primitive)ent).UpdateShape(shape.ObjectData[i]);
144 }
145 }
146 }
147 break;
148 case PacketType.MultipleObjectUpdate:
149 MultipleObjectUpdatePacket multipleupdate = (MultipleObjectUpdatePacket)Pack;
150
151 for (int i = 0; i < multipleupdate.ObjectData.Length; i++)
152 {
153 if (multipleupdate.ObjectData[i].Type == 9) //change position
154 {
155 libsecondlife.LLVector3 pos = new LLVector3(multipleupdate.ObjectData[i].Data, 0);
156 foreach (Entity ent in OpenSimRoot.Instance.LocalWorld.Entities.Values)
157 {
158 if (ent.localid == multipleupdate.ObjectData[i].ObjectLocalID)
159 {
160 ((OpenSim.world.Primitive)ent).UpdatePosition(pos);
161
162 }
163 }
164
165 //should update stored position of the prim
166 }
167 else if (multipleupdate.ObjectData[i].Type == 10)//rotation
168 {
169 libsecondlife.LLQuaternion rot = new LLQuaternion(multipleupdate.ObjectData[i].Data, 0, true);
170 foreach (Entity ent in OpenSimRoot.Instance.LocalWorld.Entities.Values)
171 {
172 if (ent.localid == multipleupdate.ObjectData[i].ObjectLocalID)
173 {
174 ent.rotation = new Axiom.MathLib.Quaternion(rot.W, rot.X, rot.Y, rot.W);
175 ((OpenSim.world.Primitive)ent).UpdateFlag = true;
176 }
177 }
178 }
179 else if (multipleupdate.ObjectData[i].Type == 13)//scale
180 {
181
182 libsecondlife.LLVector3 scale = new LLVector3(multipleupdate.ObjectData[i].Data, 12);
183 foreach (Entity ent in OpenSimRoot.Instance.LocalWorld.Entities.Values)
184 {
185 if (ent.localid == multipleupdate.ObjectData[i].ObjectLocalID)
186 {
187 ((OpenSim.world.Primitive)ent).Scale = scale;
188 }
189 }
190 }
191 }
192 break;
193 case PacketType.RequestImage:
194 RequestImagePacket imageRequest = (RequestImagePacket)Pack;
195 for (int i = 0; i < imageRequest.RequestImage.Length; i++)
196 {
197 OpenSimRoot.Instance.AssetCache.AddTextureRequest(this, imageRequest.RequestImage[i].Image);
198 }
199 break;
200 case PacketType.TransferRequest:
201 //Console.WriteLine("OpenSimClient.cs:ProcessInPacket() - Got transfer request");
202 TransferRequestPacket transfer = (TransferRequestPacket)Pack;
203 OpenSimRoot.Instance.AssetCache.AddAssetRequest(this, transfer);
204 break;
205 case PacketType.AgentUpdate:
206 ClientAvatar.HandleUpdate((AgentUpdatePacket)Pack);
207 break;
208 case PacketType.LogoutRequest:
209 OpenSim.Framework.Console.MainConsole.Instance.WriteLine("OpenSimClient.cs:ProcessInPacket() - Got a logout request");
210 //send reply to let the client logout
211 LogoutReplyPacket logReply = new LogoutReplyPacket();
212 logReply.AgentData.AgentID = this.AgentID;
213 logReply.AgentData.SessionID = this.SessionID;
214 logReply.InventoryData = new LogoutReplyPacket.InventoryDataBlock[1];
215 logReply.InventoryData[0] = new LogoutReplyPacket.InventoryDataBlock();
216 logReply.InventoryData[0].ItemID = LLUUID.Zero;
217 OutPacket(logReply);
218 //tell all clients to kill our object
219 KillObjectPacket kill = new KillObjectPacket();
220 kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1];
221 kill.ObjectData[0] = new KillObjectPacket.ObjectDataBlock();
222 kill.ObjectData[0].ID = this.ClientAvatar.localid;
223 foreach (SimClient client in OpenSimRoot.Instance.ClientThreads.Values)
224 {
225 client.OutPacket(kill);
226 }
227 OpenSimRoot.Instance.GridServers.GridServer.LogoutSession(this.SessionID, this.AgentID, this.CircuitCode);
228 lock (OpenSimRoot.Instance.LocalWorld.Entities)
229 {
230 OpenSimRoot.Instance.LocalWorld.Entities.Remove(this.AgentID);
231 }
232 //need to do other cleaning up here too
233 OpenSimRoot.Instance.ClientThreads.Remove(this.CircuitCode); //this.userEP);
234 OpenSimRoot.Instance.Application.RemoveClientCircuit(this.CircuitCode);
235 this.ClientThread.Abort();
236 break;
237 case PacketType.ChatFromViewer:
238 ChatFromViewerPacket inchatpack = (ChatFromViewerPacket)Pack;
239 if (Helpers.FieldToString(inchatpack.ChatData.Message) == "") break;
240
241 System.Text.Encoding _enc = System.Text.Encoding.ASCII;
242 libsecondlife.Packets.ChatFromSimulatorPacket reply = new ChatFromSimulatorPacket();
243 reply.ChatData.Audible = 1;
244 reply.ChatData.Message = inchatpack.ChatData.Message;
245 reply.ChatData.ChatType = 1;
246 reply.ChatData.SourceType = 1;
247 reply.ChatData.Position = this.ClientAvatar.position;
248 reply.ChatData.FromName = _enc.GetBytes(this.ClientAvatar.firstname + " " + this.ClientAvatar.lastname + "\0");
249 reply.ChatData.OwnerID = this.AgentID;
250 reply.ChatData.SourceID = this.AgentID;
251 foreach (SimClient client in OpenSimRoot.Instance.ClientThreads.Values)
252 {
253 client.OutPacket(reply);
254 }
255 break;
256 case PacketType.ObjectImage:
257 ObjectImagePacket imagePack = (ObjectImagePacket)Pack;
258 for (int i = 0; i < imagePack.ObjectData.Length; i++)
259 {
260 foreach (Entity ent in OpenSimRoot.Instance.LocalWorld.Entities.Values)
261 {
262 if (ent.localid == imagePack.ObjectData[i].ObjectLocalID)
263 {
264 ((OpenSim.world.Primitive)ent).UpdateTexture(imagePack.ObjectData[i].TextureEntry);
265 }
266 }
267 }
268 break;
269 case PacketType.ObjectFlagUpdate:
270 ObjectFlagUpdatePacket flags = (ObjectFlagUpdatePacket)Pack;
271 foreach (Entity ent in OpenSimRoot.Instance.LocalWorld.Entities.Values)
272 {
273 if (ent.localid == flags.AgentData.ObjectLocalID)
274 {
275 ((OpenSim.world.Primitive)ent).UpdateObjectFlags(flags);
276 }
277 }
278
279 break;
280 case PacketType.AssetUploadRequest:
281 AssetUploadRequestPacket request = (AssetUploadRequestPacket)Pack;
282 Console.WriteLine("upload request "+ request.AssetBlock.TransactionID);
283 AssetBase newAsset = OpenSimRoot.Instance.AssetCache.UploadPacket(request, LLUUID.Random());
284 if (newAsset != null)
285 {
286 OpenSimRoot.Instance.InventoryCache.AddNewInventoryItem(this, this.newAssetFolder, newAsset);
287 }
288 Console.WriteLine(request.ToString());
289 Console.WriteLine("combined uuid is " + request.AssetBlock.TransactionID.Combine(this.SecureSessionID).ToStringHyphenated());
290
291 AssetUploadCompletePacket response = new AssetUploadCompletePacket();
292 response.AssetBlock.Type =request.AssetBlock.Type;
293 response.AssetBlock.Success = true;
294 response.AssetBlock.UUID = request.AssetBlock.TransactionID.Combine(this.SecureSessionID);
295
296 this.OutPacket(response);
297 break;
298 case PacketType.CreateInventoryFolder:
299 //Console.WriteLine(Pack.ToString());
300 break;
301 case PacketType.CreateInventoryItem:
302 //Console.WriteLine(Pack.ToString());
303 break;
304 case PacketType.FetchInventory:
305 Console.WriteLine("fetch item packet");
306 FetchInventoryPacket FetchInventory = (FetchInventoryPacket)Pack;
307 OpenSimRoot.Instance.InventoryCache.FetchInventory(this, FetchInventory);
308 break;
309 case PacketType.FetchInventoryDescendents:
310 FetchInventoryDescendentsPacket Fetch = (FetchInventoryDescendentsPacket)Pack;
311 OpenSimRoot.Instance.InventoryCache.FetchInventoryDescendents(this, Fetch);
312 break;
313 }
314 }
315
316 private void ResendUnacked()
317 {
318 int now = Environment.TickCount;
319
320 lock (NeedAck)
321 {
322 foreach (Packet packet in NeedAck.Values)
323 {
324 if ((now - packet.TickCount > RESEND_TIMEOUT) && (!packet.Header.Resent))
325 {
326 OpenSim.Framework.Console.MainConsole.Instance.WriteLine("Resending " + packet.Type.ToString() + " packet, " +
327 (now - packet.TickCount) + "ms have passed");
328
329 packet.Header.Resent = true;
330 OutPacket(packet);
331 }
332 }
333 }
334 }
335
336 private void SendAcks()
337 {
338 lock (PendingAcks)
339 {
340 if (PendingAcks.Count > 0)
341 {
342 if (PendingAcks.Count > 250)
343 {
344 // FIXME: Handle the odd case where we have too many pending ACKs queued up
345 OpenSim.Framework.Console.MainConsole.Instance.WriteLine("Too many ACKs queued up!");
346 return;
347 }
348
349 OpenSim.Framework.Console.MainConsole.Instance.WriteLine("Sending PacketAck");
350
351
352 int i = 0;
353 PacketAckPacket acks = new PacketAckPacket();
354 acks.Packets = new PacketAckPacket.PacketsBlock[PendingAcks.Count];
355
356 foreach (uint ack in PendingAcks.Values)
357 {
358 acks.Packets[i] = new PacketAckPacket.PacketsBlock();
359 acks.Packets[i].ID = ack;
360 i++;
361 }
362
363 acks.Header.Reliable = false;
364 OutPacket(acks);
365
366 PendingAcks.Clear();
367 }
368 }
369 }
370
371 private void AckTimer_Elapsed(object sender, ElapsedEventArgs ea)
372 {
373 SendAcks();
374 ResendUnacked();
375 }
376
377 protected virtual void ProcessOutPacket(Packet Pack)
378 {
379
380 // Keep track of when this packet was sent out
381 Pack.TickCount = Environment.TickCount;
382
383 if (!Pack.Header.Resent)
384 {
385 // Set the sequence number
386 lock (SequenceLock)
387 {
388 if (Sequence >= MAX_SEQUENCE)
389 Sequence = 1;
390 else
391 Sequence++;
392 Pack.Header.Sequence = Sequence;
393 }
394
395 if (Pack.Header.Reliable) //DIRTY HACK
396 {
397 lock (NeedAck)
398 {
399 if (!NeedAck.ContainsKey(Pack.Header.Sequence))
400 {
401 NeedAck.Add(Pack.Header.Sequence, Pack);
402 }
403 else
404 {
405 // Client.Log("Attempted to add a duplicate sequence number (" +
406 // packet.Header.Sequence + ") to the NeedAck dictionary for packet type " +
407 // packet.Type.ToString(), Helpers.LogLevel.Warning);
408 }
409 }
410
411 // Don't append ACKs to resent packets, in case that's what was causing the
412 // delivery to fail
413 if (!Pack.Header.Resent)
414 {
415 // Append any ACKs that need to be sent out to this packet
416 lock (PendingAcks)
417 {
418 if (PendingAcks.Count > 0 && PendingAcks.Count < MAX_APPENDED_ACKS &&
419 Pack.Type != PacketType.PacketAck &&
420 Pack.Type != PacketType.LogoutRequest)
421 {
422 Pack.Header.AckList = new uint[PendingAcks.Count];
423 int i = 0;
424
425 foreach (uint ack in PendingAcks.Values)
426 {
427 Pack.Header.AckList[i] = ack;
428 i++;
429 }
430
431 PendingAcks.Clear();
432 Pack.Header.AppendedAcks = true;
433 }
434 }
435 }
436 }
437 }
438
439 //ServerConsole.MainConsole.Instance.WriteLine("OUT: \n" + Pack.ToString());
440
441 byte[] ZeroOutBuffer = new byte[4096];
442 byte[] sendbuffer;
443 sendbuffer = Pack.ToBytes();
444
445 try
446 {
447 if (Pack.Header.Zerocoded)
448 {
449 int packetsize = Helpers.ZeroEncode(sendbuffer, sendbuffer.Length, ZeroOutBuffer);
450 OpenSimRoot.Instance.Application.SendPacketTo(ZeroOutBuffer, packetsize, SocketFlags.None, CircuitCode);//userEP);
451 }
452 else
453 {
454 OpenSimRoot.Instance.Application.SendPacketTo(sendbuffer, sendbuffer.Length, SocketFlags.None, CircuitCode); //userEP);
455 }
456 }
457 catch (Exception)
458 {
459 OpenSim.Framework.Console.MainConsole.Instance.WriteLine("OpenSimClient.cs:ProcessOutPacket() - WARNING: Socket exception occurred on connection " + userEP.ToString() + " - killing thread");
460 ClientThread.Abort();
461 }
462
463 }
464
465 public virtual void InPacket(Packet NewPack)
466 {
467 // Handle appended ACKs
468 if (NewPack.Header.AppendedAcks)
469 {
470 lock (NeedAck)
471 {
472 foreach (uint ack in NewPack.Header.AckList)
473 {
474 NeedAck.Remove(ack);
475 }
476 }
477 }
478
479 // Handle PacketAck packets
480 if (NewPack.Type == PacketType.PacketAck)
481 {
482 PacketAckPacket ackPacket = (PacketAckPacket)NewPack;
483
484 lock (NeedAck)
485 {
486 foreach (PacketAckPacket.PacketsBlock block in ackPacket.Packets)
487 {
488 NeedAck.Remove(block.ID);
489 }
490 }
491 }
492 else if ((NewPack.Type == PacketType.StartPingCheck))
493 {
494 //reply to pingcheck
495 libsecondlife.Packets.StartPingCheckPacket startPing = (libsecondlife.Packets.StartPingCheckPacket)NewPack;
496 libsecondlife.Packets.CompletePingCheckPacket endPing = new CompletePingCheckPacket();
497 endPing.PingID.PingID = startPing.PingID.PingID;
498 OutPacket(endPing);
499 }
500 else
501 {
502 QueItem item = new QueItem();
503 item.Packet = NewPack;
504 item.Incoming = true;
505 this.PacketQueue.Enqueue(item);
506 }
507
508 }
509
510 public virtual void OutPacket(Packet NewPack)
511 {
512 QueItem item = new QueItem();
513 item.Packet = NewPack;
514 item.Incoming = false;
515 this.PacketQueue.Enqueue(item);
516 }
517
518 public SimClient(EndPoint remoteEP, UseCircuitCodePacket initialcirpack)
519 {
520 OpenSim.Framework.Console.MainConsole.Instance.WriteLine("OpenSimClient.cs - Started up new client thread to handle incoming request");
521 cirpack = initialcirpack;
522 userEP = remoteEP;
523 PacketQueue = new BlockingQueue<QueItem>();
524 AckTimer = new System.Timers.Timer(500);
525 AckTimer.Elapsed += new ElapsedEventHandler(AckTimer_Elapsed);
526 AckTimer.Start();
527
528 ClientThread = new Thread(new ThreadStart(AuthUser));
529 ClientThread.IsBackground = true;
530 ClientThread.Start();
531 }
532
533 protected virtual void ClientLoop()
534 {
535 OpenSim.Framework.Console.MainConsole.Instance.WriteLine("OpenSimClient.cs:ClientLoop() - Entered loop");
536 while (true)
537 {
538 QueItem nextPacket = PacketQueue.Dequeue();
539 if (nextPacket.Incoming)
540 {
541 //is a incoming packet
542 ProcessInPacket(nextPacket.Packet);
543 }
544 else
545 {
546 //is a out going packet
547 ProcessOutPacket(nextPacket.Packet);
548 }
549 }
550 }
551
552 protected virtual void InitNewClient()
553 {
554 OpenSim.Framework.Console.MainConsole.Instance.WriteLine("OpenSimClient.cs:InitNewClient() - Adding viewer agent to world");
555 OpenSimRoot.Instance.LocalWorld.AddViewerAgent(this);
556 world.Entity tempent = OpenSimRoot.Instance.LocalWorld.Entities[this.AgentID];
557 this.ClientAvatar = (world.Avatar)tempent;
558 }
559
560 protected virtual void AuthUser()
561 {
562 AuthenticateResponse sessionInfo = OpenSimRoot.Instance.GridServers.GridServer.AuthenticateSession(cirpack.CircuitCode.SessionID, cirpack.CircuitCode.ID, cirpack.CircuitCode.Code);
563 if (!sessionInfo.Authorised)
564 {
565 //session/circuit not authorised
566 OpenSim.Framework.Console.MainConsole.Instance.WriteLine("OpenSimClient.cs:AuthUser() - New user request denied to " + userEP.ToString());
567 ClientThread.Abort();
568 }
569 else
570 {
571 OpenSim.Framework.Console.MainConsole.Instance.WriteLine("OpenSimClient.cs:AuthUser() - Got authenticated connection from " + userEP.ToString());
572 //session is authorised
573 this.AgentID = cirpack.CircuitCode.ID;
574 this.SessionID = cirpack.CircuitCode.SessionID;
575 this.CircuitCode = cirpack.CircuitCode.Code;
576 InitNewClient(); //shouldn't be called here as we might be a child agent and not want a full avatar
577 this.ClientAvatar.firstname = sessionInfo.LoginInfo.First;
578 this.ClientAvatar.lastname = sessionInfo.LoginInfo.Last;
579 if (sessionInfo.LoginInfo.SecureSession != LLUUID.Zero)
580 {
581 this.SecureSessionID = sessionInfo.LoginInfo.SecureSession;
582 }
583
584 // Create Inventory, currently only works for sandbox mode
585 if (OpenSimRoot.Instance.Sandbox)
586 {
587 if (sessionInfo.LoginInfo.InventoryFolder != null)
588 {
589 this.CreateInventory(sessionInfo.LoginInfo.InventoryFolder);
590 if (sessionInfo.LoginInfo.BaseFolder != null)
591 {
592 OpenSimRoot.Instance.InventoryCache.CreateNewInventoryFolder(this, sessionInfo.LoginInfo.BaseFolder);
593 this.newAssetFolder = sessionInfo.LoginInfo.BaseFolder;
594 AssetBase[] inventorySet = OpenSimRoot.Instance.AssetCache.CreateNewInventorySet(this.AgentID);
595 if (inventorySet != null)
596 {
597 for (int i = 0; i < inventorySet.Length; i++)
598 {
599 if (inventorySet[i] != null)
600 {
601 OpenSimRoot.Instance.InventoryCache.AddNewInventoryItem(this, sessionInfo.LoginInfo.BaseFolder, inventorySet[i]);
602 }
603 }
604 }
605 }
606 }
607 }
608
609 ClientLoop();
610 }
611 }
612
613 private void CreateInventory(LLUUID baseFolder)
614 {
615 AgentInventory inventory = new AgentInventory();
616 inventory.AgentID = this.AgentID;
617 OpenSimRoot.Instance.InventoryCache.AddNewAgentsInventory(inventory);
618 OpenSimRoot.Instance.InventoryCache.CreateNewInventoryFolder(this, baseFolder);
619 }
620 }
621}