aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/OpenSim.RegionServer/ClientView.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/OpenSim.RegionServer/ClientView.cs449
1 files changed, 449 insertions, 0 deletions
diff --git a/OpenSim/OpenSim.RegionServer/ClientView.cs b/OpenSim/OpenSim.RegionServer/ClientView.cs
new file mode 100644
index 0000000..295cd7b
--- /dev/null
+++ b/OpenSim/OpenSim.RegionServer/ClientView.cs
@@ -0,0 +1,449 @@
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 Nwc.XmlRpc;
33using System.Net;
34using System.Net.Sockets;
35using System.IO;
36using System.Threading;
37using System.Timers;
38using OpenSim.Framework.Interfaces;
39using OpenSim.Framework.Types;
40using OpenSim.Framework.Inventory;
41using OpenSim.Framework.Utilities;
42using OpenSim.world;
43using OpenSim.Assets;
44
45namespace OpenSim
46{
47 public delegate bool PacketMethod(ClientView simClient, Packet packet);
48
49 /// <summary>
50 /// Handles new client connections
51 /// Constructor takes a single Packet and authenticates everything
52 /// </summary>
53 public partial class ClientView : ClientViewBase, IClientAPI
54 {
55 protected static Dictionary<PacketType, PacketMethod> PacketHandlers = new Dictionary<PacketType, PacketMethod>(); //Global/static handlers for all clients
56 protected Dictionary<PacketType, PacketMethod> m_packetHandlers = new Dictionary<PacketType, PacketMethod>(); //local handlers for this instance
57
58 public LLUUID AgentID;
59 public LLUUID SessionID;
60 public LLUUID SecureSessionID = LLUUID.Zero;
61 public bool m_child;
62 public world.Avatar ClientAvatar;
63 private UseCircuitCodePacket cirpack;
64 public Thread ClientThread;
65 public LLVector3 startpos;
66
67 private AgentAssetUpload UploadAssets;
68 private LLUUID newAssetFolder = LLUUID.Zero;
69 private bool debug = false;
70 private World m_world;
71 private Dictionary<uint, ClientView> m_clientThreads;
72 private AssetCache m_assetCache;
73 private IGridServer m_gridServer;
74 private IUserServer m_userServer = null;
75 private InventoryCache m_inventoryCache;
76 public bool m_sandboxMode;
77 private int cachedtextureserial = 0;
78 private RegionInfo m_regionData;
79 protected AuthenticateSessionsBase m_authenticateSessionsHandler;
80
81 public IUserServer UserServer
82 {
83 set
84 {
85 this.m_userServer = value;
86 }
87 }
88
89 public LLVector3 StartPos
90 {
91 get
92 {
93 return startpos;
94 }
95 set
96 {
97 startpos = value;
98 }
99 }
100
101 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)
102 {
103 m_world = world;
104 m_clientThreads = clientThreads;
105 m_assetCache = assetCache;
106 m_gridServer = gridServer;
107 m_networkServer = application;
108 m_inventoryCache = inventoryCache;
109 m_sandboxMode = sandboxMode;
110 m_child = child;
111 m_regionData = regionDat;
112 m_authenticateSessionsHandler = authenSessions;
113
114 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "OpenSimClient.cs - Started up new client thread to handle incoming request");
115 cirpack = initialcirpack;
116 userEP = remoteEP;
117
118 if (m_gridServer.GetName() == "Remote")
119 {
120 this.m_child = m_authenticateSessionsHandler.GetAgentChildStatus(initialcirpack.CircuitCode.Code);
121 this.startpos = m_authenticateSessionsHandler.GetPosition(initialcirpack.CircuitCode.Code);
122 //Console.WriteLine("start pos is " + this.startpos.X + " , " + this.startpos.Y + " , " + this.startpos.Z);
123 }
124 else
125 {
126 this.startpos = new LLVector3(128, 128, m_world.Terrain[(int)128, (int)128] + 15.0f); // new LLVector3(128.0f, 128.0f, 60f);
127 }
128
129 PacketQueue = new BlockingQueue<QueItem>();
130
131 this.UploadAssets = new AgentAssetUpload(this, m_assetCache, m_inventoryCache);
132 AckTimer = new System.Timers.Timer(500);
133 AckTimer.Elapsed += new ElapsedEventHandler(AckTimer_Elapsed);
134 AckTimer.Start();
135
136 this.RegisterLocalPacketHandlers();
137
138 ClientThread = new Thread(new ThreadStart(AuthUser));
139 ClientThread.IsBackground = true;
140 ClientThread.Start();
141 }
142
143 # region Client Methods
144 public void UpgradeClient()
145 {
146 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "SimClient.cs:UpgradeClient() - upgrading child to full agent");
147 this.m_child = false;
148 //this.m_world.RemoveViewerAgent(this);
149 if (!this.m_sandboxMode)
150 {
151 this.startpos = m_authenticateSessionsHandler.GetPosition(CircuitCode);
152 m_authenticateSessionsHandler.UpdateAgentChildStatus(CircuitCode, false);
153 }
154 OnChildAgentStatus(this.m_child);
155 //this.InitNewClient();
156 }
157
158 public void DowngradeClient()
159 {
160 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "SimClient.cs:UpgradeClient() - changing full agent to child");
161 this.m_child = true;
162 OnChildAgentStatus(this.m_child);
163 //this.m_world.RemoveViewerAgent(this);
164 //this.m_world.AddViewerAgent(this);
165 }
166
167 public void KillClient()
168 {
169 KillObjectPacket kill = new KillObjectPacket();
170 kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1];
171 kill.ObjectData[0] = new KillObjectPacket.ObjectDataBlock();
172 kill.ObjectData[0].ID = this.ClientAvatar.localid;
173 foreach (ClientView client in m_clientThreads.Values)
174 {
175 client.OutPacket(kill);
176 }
177 if (this.m_userServer != null)
178 {
179 this.m_inventoryCache.ClientLeaving(this.AgentID, this.m_userServer);
180 }
181 else
182 {
183 this.m_inventoryCache.ClientLeaving(this.AgentID, null);
184 }
185
186 m_world.RemoveViewerAgent(this);
187
188 m_clientThreads.Remove(this.CircuitCode);
189 m_networkServer.RemoveClientCircuit(this.CircuitCode);
190 this.ClientThread.Abort();
191 }
192 #endregion
193
194 # region Packet Handling
195 public static bool AddPacketHandler(PacketType packetType, PacketMethod handler)
196 {
197 bool result = false;
198 lock (PacketHandlers)
199 {
200 if (!PacketHandlers.ContainsKey(packetType))
201 {
202 PacketHandlers.Add(packetType, handler);
203 result = true;
204 }
205 }
206 return result;
207 }
208
209 public bool AddLocalPacketHandler(PacketType packetType, PacketMethod handler)
210 {
211 bool result = false;
212 lock (m_packetHandlers)
213 {
214 if (!m_packetHandlers.ContainsKey(packetType))
215 {
216 m_packetHandlers.Add(packetType, handler);
217 result = true;
218 }
219 }
220 return result;
221 }
222
223 protected virtual bool ProcessPacketMethod(Packet packet)
224 {
225 bool result = false;
226 bool found = false;
227 PacketMethod method;
228 if (m_packetHandlers.TryGetValue(packet.Type, out method))
229 {
230 //there is a local handler for this packet type
231 result = method(this, packet);
232 }
233 else
234 {
235 //there is not a local handler so see if there is a Global handler
236 lock (PacketHandlers)
237 {
238 found = PacketHandlers.TryGetValue(packet.Type, out method);
239 }
240 if (found)
241 {
242 result = method(this, packet);
243 }
244 }
245 return result;
246 }
247
248 protected virtual void ClientLoop()
249 {
250 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "OpenSimClient.cs:ClientLoop() - Entered loop");
251 while (true)
252 {
253 QueItem nextPacket = PacketQueue.Dequeue();
254 if (nextPacket.Incoming)
255 {
256 //is a incoming packet
257 ProcessInPacket(nextPacket.Packet);
258 }
259 else
260 {
261 //is a out going packet
262 ProcessOutPacket(nextPacket.Packet);
263 }
264 }
265 }
266 # endregion
267
268 # region Setup
269
270 protected virtual void InitNewClient()
271 {
272 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "OpenSimClient.cs:InitNewClient() - Adding viewer agent to world");
273 this.ClientAvatar = m_world.AddViewerAgent(this);
274 }
275
276 protected virtual void AuthUser()
277 {
278 // AuthenticateResponse sessionInfo = m_gridServer.AuthenticateSession(cirpack.CircuitCode.SessionID, cirpack.CircuitCode.ID, cirpack.CircuitCode.Code);
279 AuthenticateResponse sessionInfo = this.m_networkServer.AuthenticateSession(cirpack.CircuitCode.SessionID, cirpack.CircuitCode.ID, cirpack.CircuitCode.Code);
280 if (!sessionInfo.Authorised)
281 {
282 //session/circuit not authorised
283 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.NORMAL, "OpenSimClient.cs:AuthUser() - New user request denied to " + userEP.ToString());
284 ClientThread.Abort();
285 }
286 else
287 {
288 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.NORMAL, "OpenSimClient.cs:AuthUser() - Got authenticated connection from " + userEP.ToString());
289 //session is authorised
290 this.AgentID = cirpack.CircuitCode.ID;
291 this.SessionID = cirpack.CircuitCode.SessionID;
292 this.CircuitCode = cirpack.CircuitCode.Code;
293 InitNewClient();
294 this.ClientAvatar.firstname = sessionInfo.LoginInfo.First;
295 this.ClientAvatar.lastname = sessionInfo.LoginInfo.Last;
296 if (sessionInfo.LoginInfo.SecureSession != LLUUID.Zero)
297 {
298 this.SecureSessionID = sessionInfo.LoginInfo.SecureSession;
299 }
300
301 // Create Inventory, currently only works for sandbox mode
302 if (m_sandboxMode)
303 {
304 this.SetupInventory(sessionInfo);
305 }
306
307 ClientLoop();
308 }
309 }
310 # endregion
311
312
313 protected override void KillThread()
314 {
315 this.ClientThread.Abort();
316 }
317
318 #region World/Avatar To Viewer Methods
319
320 public void SendChatMessage(byte[] message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID)
321 {
322 System.Text.Encoding enc = System.Text.Encoding.ASCII;
323 libsecondlife.Packets.ChatFromSimulatorPacket reply = new ChatFromSimulatorPacket();
324 reply.ChatData.Audible = 1;
325 reply.ChatData.Message = message;
326 reply.ChatData.ChatType = type;
327 reply.ChatData.SourceType = 1;
328 reply.ChatData.Position = fromPos;
329 reply.ChatData.FromName = enc.GetBytes(fromName + "\0");
330 reply.ChatData.OwnerID = fromAgentID;
331 reply.ChatData.SourceID = fromAgentID;
332
333 this.OutPacket(reply);
334 }
335
336 public void SendAppearance(AvatarWearable[] wearables)
337 {
338 AgentWearablesUpdatePacket aw = new AgentWearablesUpdatePacket();
339 aw.AgentData.AgentID = this.AgentID;
340 aw.AgentData.SerialNum = 0;
341 aw.AgentData.SessionID = this.SessionID;
342
343 aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[13];
344 AgentWearablesUpdatePacket.WearableDataBlock awb;
345 for (int i = 0; i < wearables.Length; i++)
346 {
347 awb = new AgentWearablesUpdatePacket.WearableDataBlock();
348 awb.WearableType = (byte)i;
349 awb.AssetID = wearables[i].AssetID;
350 awb.ItemID = wearables[i].ItemID;
351 aw.WearableData[i] = awb;
352 }
353
354 this.OutPacket(aw);
355 }
356 #endregion
357
358 #region Inventory Creation
359 private void SetupInventory(AuthenticateResponse sessionInfo)
360 {
361 AgentInventory inventory = null;
362 if (sessionInfo.LoginInfo.InventoryFolder != null)
363 {
364 inventory = this.CreateInventory(sessionInfo.LoginInfo.InventoryFolder);
365 if (sessionInfo.LoginInfo.BaseFolder != null)
366 {
367 if (!inventory.HasFolder(sessionInfo.LoginInfo.BaseFolder))
368 {
369 m_inventoryCache.CreateNewInventoryFolder(this, sessionInfo.LoginInfo.BaseFolder);
370 }
371 this.newAssetFolder = sessionInfo.LoginInfo.BaseFolder;
372 AssetBase[] inventorySet = m_assetCache.CreateNewInventorySet(this.AgentID);
373 if (inventorySet != null)
374 {
375 for (int i = 0; i < inventorySet.Length; i++)
376 {
377 if (inventorySet[i] != null)
378 {
379 m_inventoryCache.AddNewInventoryItem(this, sessionInfo.LoginInfo.BaseFolder, inventorySet[i]);
380 }
381 }
382 }
383 }
384 }
385 }
386 private AgentInventory CreateInventory(LLUUID baseFolder)
387 {
388 AgentInventory inventory = null;
389 if (this.m_userServer != null)
390 {
391 // a user server is set so request the inventory from it
392 Console.WriteLine("getting inventory from user server");
393 inventory = m_inventoryCache.FetchAgentsInventory(this.AgentID, m_userServer);
394 }
395 else
396 {
397 inventory = new AgentInventory();
398 inventory.AgentID = this.AgentID;
399 inventory.CreateRootFolder(this.AgentID, false);
400 m_inventoryCache.AddNewAgentsInventory(inventory);
401 m_inventoryCache.CreateNewInventoryFolder(this, baseFolder);
402 }
403 return inventory;
404 }
405
406 private void CreateInventoryItem(CreateInventoryItemPacket packet)
407 {
408 if (!(packet.InventoryBlock.Type == 3 || packet.InventoryBlock.Type == 7))
409 {
410 System.Console.WriteLine("Attempted to create " + Util.FieldToString(packet.InventoryBlock.Name) + " in inventory. Unsupported type");
411 return;
412 }
413
414 //lets try this out with creating a notecard
415 AssetBase asset = new AssetBase();
416
417 asset.Name = Util.FieldToString(packet.InventoryBlock.Name);
418 asset.Description = Util.FieldToString(packet.InventoryBlock.Description);
419 asset.InvType = packet.InventoryBlock.InvType;
420 asset.Type = packet.InventoryBlock.Type;
421 asset.FullID = LLUUID.Random();
422
423 switch (packet.InventoryBlock.Type)
424 {
425 case 7: // Notecard
426 asset.Data = new byte[0];
427 break;
428
429 case 3: // Landmark
430 String content;
431 content = "Landmark version 2\n";
432 content += "region_id " + m_regionData.SimUUID + "\n";
433 String strPos = String.Format("%.2f %.2f %.2f>",
434 this.ClientAvatar.Pos.X,
435 this.ClientAvatar.Pos.Y,
436 this.ClientAvatar.Pos.Z);
437 content += "local_pos " + strPos + "\n";
438 asset.Data = (new System.Text.ASCIIEncoding()).GetBytes(content);
439 break;
440 default:
441 break;
442 }
443 m_assetCache.AddAsset(asset);
444 m_inventoryCache.AddNewInventoryItem(this, packet.InventoryBlock.FolderID, asset);
445 }
446 #endregion
447
448 }
449}