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