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