aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Framework
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/Framework')
-rw-r--r--OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs426
-rw-r--r--OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs17
-rw-r--r--OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs8
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs353
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs42
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs19
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs69
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs211
-rw-r--r--OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/Framework/Search/BasicSearchModule.cs197
-rw-r--r--OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs256
-rw-r--r--OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs6
-rw-r--r--OpenSim/Region/CoreModules/Framework/UserManagement/Tests/HGUserManagementModuleTests.cs76
-rw-r--r--OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs401
14 files changed, 1702 insertions, 383 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
index fff86d5..de8925d 100644
--- a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Linq;
31using System.Reflection; 32using System.Reflection;
32using System.Text; 33using System.Text;
33using log4net; 34using log4net;
@@ -37,6 +38,7 @@ using OpenMetaverse;
37using OpenSim.Framework; 38using OpenSim.Framework;
38using OpenSim.Framework.Console; 39using OpenSim.Framework.Console;
39using OpenSim.Framework.Servers; 40using OpenSim.Framework.Servers;
41using OpenSim.Framework.Servers.HttpServer;
40using OpenSim.Region.Framework.Interfaces; 42using OpenSim.Region.Framework.Interfaces;
41using OpenSim.Region.Framework.Scenes; 43using OpenSim.Region.Framework.Scenes;
42using Caps=OpenSim.Framework.Capabilities.Caps; 44using Caps=OpenSim.Framework.Capabilities.Caps;
@@ -57,8 +59,9 @@ namespace OpenSim.Region.CoreModules.Framework
57 /// </summary> 59 /// </summary>
58 protected Dictionary<uint, Caps> m_capsObjects = new Dictionary<uint, Caps>(); 60 protected Dictionary<uint, Caps> m_capsObjects = new Dictionary<uint, Caps>();
59 61
60 protected Dictionary<UUID, string> capsPaths = new Dictionary<UUID, string>(); 62 protected Dictionary<UUID, string> m_capsPaths = new Dictionary<UUID, string>();
61 protected Dictionary<UUID, Dictionary<ulong, string>> childrenSeeds 63
64 protected Dictionary<UUID, Dictionary<ulong, string>> m_childrenSeeds
62 = new Dictionary<UUID, Dictionary<ulong, string>>(); 65 = new Dictionary<UUID, Dictionary<ulong, string>>();
63 66
64 public void Initialise(IConfigSource source) 67 public void Initialise(IConfigSource source)
@@ -70,9 +73,24 @@ namespace OpenSim.Region.CoreModules.Framework
70 m_scene = scene; 73 m_scene = scene;
71 m_scene.RegisterModuleInterface<ICapabilitiesModule>(this); 74 m_scene.RegisterModuleInterface<ICapabilitiesModule>(this);
72 75
73 MainConsole.Instance.Commands.AddCommand("Comms", false, "show caps", 76 MainConsole.Instance.Commands.AddCommand(
74 "show caps", 77 "Comms", false, "show caps list",
75 "Shows all registered capabilities for users", HandleShowCapsCommand); 78 "show caps list",
79 "Shows list of registered capabilities for users.", HandleShowCapsListCommand);
80
81 MainConsole.Instance.Commands.AddCommand(
82 "Comms", false, "show caps stats by user",
83 "show caps stats by user [<first-name> <last-name>]",
84 "Shows statistics on capabilities use by user.",
85 "If a user name is given, then prints a detailed breakdown of caps use ordered by number of requests received.",
86 HandleShowCapsStatsByUserCommand);
87
88 MainConsole.Instance.Commands.AddCommand(
89 "Comms", false, "show caps stats by cap",
90 "show caps stats by cap [<cap-name>]",
91 "Shows statistics on capabilities use by capability.",
92 "If a capability name is given, then prints a detailed breakdown of use by each user.",
93 HandleShowCapsStatsByCapCommand);
76 } 94 }
77 95
78 public void RegionLoaded(Scene scene) 96 public void RegionLoaded(Scene scene)
@@ -106,35 +124,38 @@ namespace OpenSim.Region.CoreModules.Framework
106 if (m_scene.RegionInfo.EstateSettings.IsBanned(agentId, flags)) 124 if (m_scene.RegionInfo.EstateSettings.IsBanned(agentId, flags))
107 return; 125 return;
108 126
127 Caps caps;
109 String capsObjectPath = GetCapsPath(agentId); 128 String capsObjectPath = GetCapsPath(agentId);
110 129
111 if (m_capsObjects.ContainsKey(circuitCode)) 130 lock (m_capsObjects)
112 { 131 {
113 Caps oldCaps = m_capsObjects[circuitCode]; 132 if (m_capsObjects.ContainsKey(circuitCode))
114 133 {
115 m_log.DebugFormat( 134 Caps oldCaps = m_capsObjects[circuitCode];
116 "[CAPS]: Recreating caps for agent {0}. Old caps path {1}, new caps path {2}. ", 135
117 agentId, oldCaps.CapsObjectPath, capsObjectPath); 136 //m_log.WarnFormat(
118 // This should not happen. The caller code is confused. We need to fix that. 137 // "[CAPS]: Recreating caps for agent {0} in region {1}. Old caps path {2}, new caps path {3}. ",
119 // CAPs can never be reregistered, or the client will be confused. 138 // agentId, m_scene.RegionInfo.RegionName, oldCaps.CapsObjectPath, capsObjectPath);
120 // Hence this return here. 139 }
121 //return;
122 }
123
124 Caps caps = new Caps(MainServer.Instance, m_scene.RegionInfo.ExternalHostName,
125 (MainServer.Instance == null) ? 0: MainServer.Instance.Port,
126 capsObjectPath, agentId, m_scene.RegionInfo.RegionName);
127 140
128 m_capsObjects[circuitCode] = caps; 141 caps = new Caps(MainServer.Instance, m_scene.RegionInfo.ExternalHostName,
142 (MainServer.Instance == null) ? 0: MainServer.Instance.Port,
143 capsObjectPath, agentId, m_scene.RegionInfo.RegionName);
129 144
145 m_capsObjects[circuitCode] = caps;
146 }
130 m_scene.EventManager.TriggerOnRegisterCaps(agentId, caps); 147 m_scene.EventManager.TriggerOnRegisterCaps(agentId, caps);
131 } 148 }
132 149
133 public void RemoveCaps(UUID agentId, uint circuitCode) 150 public void RemoveCaps(UUID agentId, uint circuitCode)
134 { 151 {
135 if (childrenSeeds.ContainsKey(agentId)) 152 m_log.DebugFormat("[CAPS]: Remove caps for agent {0} in region {1}", agentId, m_scene.RegionInfo.RegionName);
153 lock (m_childrenSeeds)
136 { 154 {
137 childrenSeeds.Remove(agentId); 155 if (m_childrenSeeds.ContainsKey(agentId))
156 {
157 m_childrenSeeds.Remove(agentId);
158 }
138 } 159 }
139 160
140 lock (m_capsObjects) 161 lock (m_capsObjects)
@@ -180,16 +201,22 @@ namespace OpenSim.Region.CoreModules.Framework
180 201
181 public void SetAgentCapsSeeds(AgentCircuitData agent) 202 public void SetAgentCapsSeeds(AgentCircuitData agent)
182 { 203 {
183 capsPaths[agent.AgentID] = agent.CapsPath; 204 lock (m_capsPaths)
184 childrenSeeds[agent.AgentID] 205 m_capsPaths[agent.AgentID] = agent.CapsPath;
185 = ((agent.ChildrenCapSeeds == null) ? new Dictionary<ulong, string>() : agent.ChildrenCapSeeds); 206
207 lock (m_childrenSeeds)
208 m_childrenSeeds[agent.AgentID]
209 = ((agent.ChildrenCapSeeds == null) ? new Dictionary<ulong, string>() : agent.ChildrenCapSeeds);
186 } 210 }
187 211
188 public string GetCapsPath(UUID agentId) 212 public string GetCapsPath(UUID agentId)
189 { 213 {
190 if (capsPaths.ContainsKey(agentId)) 214 lock (m_capsPaths)
191 { 215 {
192 return capsPaths[agentId]; 216 if (m_capsPaths.ContainsKey(agentId))
217 {
218 return m_capsPaths[agentId];
219 }
193 } 220 }
194 221
195 return null; 222 return null;
@@ -198,17 +225,24 @@ namespace OpenSim.Region.CoreModules.Framework
198 public Dictionary<ulong, string> GetChildrenSeeds(UUID agentID) 225 public Dictionary<ulong, string> GetChildrenSeeds(UUID agentID)
199 { 226 {
200 Dictionary<ulong, string> seeds = null; 227 Dictionary<ulong, string> seeds = null;
201 if (childrenSeeds.TryGetValue(agentID, out seeds)) 228
202 return seeds; 229 lock (m_childrenSeeds)
230 if (m_childrenSeeds.TryGetValue(agentID, out seeds))
231 return seeds;
232
203 return new Dictionary<ulong, string>(); 233 return new Dictionary<ulong, string>();
204 } 234 }
205 235
206 public void DropChildSeed(UUID agentID, ulong handle) 236 public void DropChildSeed(UUID agentID, ulong handle)
207 { 237 {
208 Dictionary<ulong, string> seeds; 238 Dictionary<ulong, string> seeds;
209 if (childrenSeeds.TryGetValue(agentID, out seeds)) 239
240 lock (m_childrenSeeds)
210 { 241 {
211 seeds.Remove(handle); 242 if (m_childrenSeeds.TryGetValue(agentID, out seeds))
243 {
244 seeds.Remove(handle);
245 }
212 } 246 }
213 } 247 }
214 248
@@ -216,53 +250,339 @@ namespace OpenSim.Region.CoreModules.Framework
216 { 250 {
217 Dictionary<ulong, string> seeds; 251 Dictionary<ulong, string> seeds;
218 string returnval; 252 string returnval;
219 if (childrenSeeds.TryGetValue(agentID, out seeds)) 253
254 lock (m_childrenSeeds)
220 { 255 {
221 if (seeds.TryGetValue(handle, out returnval)) 256 if (m_childrenSeeds.TryGetValue(agentID, out seeds))
222 return returnval; 257 {
258 if (seeds.TryGetValue(handle, out returnval))
259 return returnval;
260 }
223 } 261 }
262
224 return null; 263 return null;
225 } 264 }
226 265
227 public void SetChildrenSeed(UUID agentID, Dictionary<ulong, string> seeds) 266 public void SetChildrenSeed(UUID agentID, Dictionary<ulong, string> seeds)
228 { 267 {
229 //m_log.DebugFormat(" !!! Setting child seeds in {0} to {1}", m_scene.RegionInfo.RegionName, seeds.Count); 268 //m_log.DebugFormat(" !!! Setting child seeds in {0} to {1}", m_scene.RegionInfo.RegionName, seeds.Count);
230 childrenSeeds[agentID] = seeds; 269
270 lock (m_childrenSeeds)
271 m_childrenSeeds[agentID] = seeds;
231 } 272 }
232 273
233 public void DumpChildrenSeeds(UUID agentID) 274 public void DumpChildrenSeeds(UUID agentID)
234 { 275 {
235 m_log.Info("================ ChildrenSeed "+m_scene.RegionInfo.RegionName+" ================"); 276 m_log.Info("================ ChildrenSeed "+m_scene.RegionInfo.RegionName+" ================");
236 foreach (KeyValuePair<ulong, string> kvp in childrenSeeds[agentID]) 277
278 lock (m_childrenSeeds)
279 {
280 foreach (KeyValuePair<ulong, string> kvp in m_childrenSeeds[agentID])
281 {
282 uint x, y;
283 Utils.LongToUInts(kvp.Key, out x, out y);
284 x = x / Constants.RegionSize;
285 y = y / Constants.RegionSize;
286 m_log.Info(" >> "+x+", "+y+": "+kvp.Value);
287 }
288 }
289 }
290
291 private void HandleShowCapsListCommand(string module, string[] cmdParams)
292 {
293 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
294 return;
295
296 StringBuilder capsReport = new StringBuilder();
297 capsReport.AppendFormat("Region {0}:\n", m_scene.RegionInfo.RegionName);
298
299 lock (m_capsObjects)
237 { 300 {
238 uint x, y; 301 foreach (KeyValuePair<uint, Caps> kvp in m_capsObjects)
239 Utils.LongToUInts(kvp.Key, out x, out y); 302 {
240 x = x / Constants.RegionSize; 303 capsReport.AppendFormat("** Circuit {0}:\n", kvp.Key);
241 y = y / Constants.RegionSize; 304 Caps caps = kvp.Value;
242 m_log.Info(" >> "+x+", "+y+": "+kvp.Value); 305
306 for (IDictionaryEnumerator kvp2 = caps.CapsHandlers.GetCapsDetails(false, null).GetEnumerator(); kvp2.MoveNext(); )
307 {
308 Uri uri = new Uri(kvp2.Value.ToString());
309 capsReport.AppendFormat(m_showCapsCommandFormat, kvp2.Key, uri.PathAndQuery);
310 }
311
312 foreach (KeyValuePair<string, PollServiceEventArgs> kvp2 in caps.GetPollHandlers())
313 capsReport.AppendFormat(m_showCapsCommandFormat, kvp2.Key, kvp2.Value.Url);
314
315 foreach (KeyValuePair<string, string> kvp3 in caps.ExternalCapsHandlers)
316 capsReport.AppendFormat(m_showCapsCommandFormat, kvp3.Key, kvp3.Value);
317 }
243 } 318 }
319
320 MainConsole.Instance.Output(capsReport.ToString());
244 } 321 }
245 322
246 private void HandleShowCapsCommand(string module, string[] cmdparams) 323 private void HandleShowCapsStatsByCapCommand(string module, string[] cmdParams)
247 { 324 {
248 StringBuilder caps = new StringBuilder(); 325 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
249 caps.AppendFormat("Region {0}:\n", m_scene.RegionInfo.RegionName); 326 return;
327
328 if (cmdParams.Length != 5 && cmdParams.Length != 6)
329 {
330 MainConsole.Instance.Output("Usage: show caps stats by cap [<cap-name>]");
331 return;
332 }
333
334 StringBuilder sb = new StringBuilder();
335 sb.AppendFormat("Region {0}:\n", m_scene.Name);
336
337 if (cmdParams.Length == 5)
338 {
339 BuildSummaryStatsByCapReport(sb);
340 }
341 else if (cmdParams.Length == 6)
342 {
343 BuildDetailedStatsByCapReport(sb, cmdParams[5]);
344 }
345
346 MainConsole.Instance.Output(sb.ToString());
347 }
348
349 private void BuildDetailedStatsByCapReport(StringBuilder sb, string capName)
350 {
351 /*
352 sb.AppendFormat("Capability name {0}\n", capName);
353
354 ConsoleDisplayTable cdt = new ConsoleDisplayTable();
355 cdt.AddColumn("User Name", 34);
356 cdt.AddColumn("Req Received", 12);
357 cdt.AddColumn("Req Handled", 12);
358 cdt.Indent = 2;
359
360 Dictionary<string, int> receivedStats = new Dictionary<string, int>();
361 Dictionary<string, int> handledStats = new Dictionary<string, int>();
362
363 m_scene.ForEachScenePresence(
364 sp =>
365 {
366 Caps caps = m_scene.CapsModule.GetCapsForUser(sp.UUID);
250 367
251 foreach (KeyValuePair<uint, Caps> kvp in m_capsObjects) 368 if (caps == null)
369 return;
370
371 Dictionary<string, IRequestHandler> capsHandlers = caps.CapsHandlers.GetCapsHandlers();
372
373 IRequestHandler reqHandler;
374 if (capsHandlers.TryGetValue(capName, out reqHandler))
375 {
376 receivedStats[sp.Name] = reqHandler.RequestsReceived;
377 handledStats[sp.Name] = reqHandler.RequestsHandled;
378 }
379 else
380 {
381 PollServiceEventArgs pollHandler = null;
382 if (caps.TryGetPollHandler(capName, out pollHandler))
383 {
384 receivedStats[sp.Name] = pollHandler.RequestsReceived;
385 handledStats[sp.Name] = pollHandler.RequestsHandled;
386 }
387 }
388 }
389 );
390
391 foreach (KeyValuePair<string, int> kvp in receivedStats.OrderByDescending(kp => kp.Value))
252 { 392 {
253 caps.AppendFormat("** Circuit {0}:\n", kvp.Key); 393 cdt.AddRow(kvp.Key, kvp.Value, handledStats[kvp.Key]);
394 }
395
396 sb.Append(cdt.ToString());
397 */
398 }
399
400 private void BuildSummaryStatsByCapReport(StringBuilder sb)
401 {
402 /*
403 ConsoleDisplayTable cdt = new ConsoleDisplayTable();
404 cdt.AddColumn("Name", 34);
405 cdt.AddColumn("Req Received", 12);
406 cdt.AddColumn("Req Handled", 12);
407 cdt.Indent = 2;
408
409 Dictionary<string, int> receivedStats = new Dictionary<string, int>();
410 Dictionary<string, int> handledStats = new Dictionary<string, int>();
254 411
255 for (IDictionaryEnumerator kvp2 = kvp.Value.CapsHandlers.GetCapsDetails(false, null).GetEnumerator(); kvp2.MoveNext(); ) 412 m_scene.ForEachScenePresence(
413 sp =>
256 { 414 {
257 Uri uri = new Uri(kvp2.Value.ToString()); 415 Caps caps = m_scene.CapsModule.GetCapsForUser(sp.UUID);
258 caps.AppendFormat(m_showCapsCommandFormat, kvp2.Key, uri.PathAndQuery); 416
417 if (caps == null)
418 return;
419
420 foreach (IRequestHandler reqHandler in caps.CapsHandlers.GetCapsHandlers().Values)
421 {
422 string reqName = reqHandler.Name ?? "";
423
424 if (!receivedStats.ContainsKey(reqName))
425 {
426 receivedStats[reqName] = reqHandler.RequestsReceived;
427 handledStats[reqName] = reqHandler.RequestsHandled;
428 }
429 else
430 {
431 receivedStats[reqName] += reqHandler.RequestsReceived;
432 handledStats[reqName] += reqHandler.RequestsHandled;
433 }
434 }
435
436 foreach (KeyValuePair<string, PollServiceEventArgs> kvp in caps.GetPollHandlers())
437 {
438 string name = kvp.Key;
439 PollServiceEventArgs pollHandler = kvp.Value;
440
441 if (!receivedStats.ContainsKey(name))
442 {
443 receivedStats[name] = pollHandler.RequestsReceived;
444 handledStats[name] = pollHandler.RequestsHandled;
445 }
446 else
447 {
448 receivedStats[name] += pollHandler.RequestsReceived;
449 handledStats[name] += pollHandler.RequestsHandled;
450 }
451 }
259 } 452 }
453 );
454
455 foreach (KeyValuePair<string, int> kvp in receivedStats.OrderByDescending(kp => kp.Value))
456 cdt.AddRow(kvp.Key, kvp.Value, handledStats[kvp.Key]);
457
458 sb.Append(cdt.ToString());
459 */
460 }
461
462 private void HandleShowCapsStatsByUserCommand(string module, string[] cmdParams)
463 {
464 /*
465 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
466 return;
467
468 if (cmdParams.Length != 5 && cmdParams.Length != 7)
469 {
470 MainConsole.Instance.Output("Usage: show caps stats by user [<first-name> <last-name>]");
471 return;
472 }
473
474 StringBuilder sb = new StringBuilder();
475 sb.AppendFormat("Region {0}:\n", m_scene.Name);
476
477 if (cmdParams.Length == 5)
478 {
479 BuildSummaryStatsByUserReport(sb);
480 }
481 else if (cmdParams.Length == 7)
482 {
483 string firstName = cmdParams[5];
484 string lastName = cmdParams[6];
485
486 ScenePresence sp = m_scene.GetScenePresence(firstName, lastName);
487
488 if (sp == null)
489 return;
260 490
261 foreach (KeyValuePair<string, string> kvp3 in kvp.Value.ExternalCapsHandlers) 491 BuildDetailedStatsByUserReport(sb, sp);
262 caps.AppendFormat(m_showCapsCommandFormat, kvp3.Key, kvp3.Value);
263 } 492 }
264 493
265 MainConsole.Instance.Output(caps.ToString()); 494 MainConsole.Instance.Output(sb.ToString());
495 */
496 }
497
498 private void BuildDetailedStatsByUserReport(StringBuilder sb, ScenePresence sp)
499 {
500 /*
501 sb.AppendFormat("Avatar name {0}, type {1}\n", sp.Name, sp.IsChildAgent ? "child" : "root");
502
503 ConsoleDisplayTable cdt = new ConsoleDisplayTable();
504 cdt.AddColumn("Cap Name", 34);
505 cdt.AddColumn("Req Received", 12);
506 cdt.AddColumn("Req Handled", 12);
507 cdt.Indent = 2;
508
509 Caps caps = m_scene.CapsModule.GetCapsForUser(sp.UUID);
510
511 if (caps == null)
512 return;
513
514 List<CapTableRow> capRows = new List<CapTableRow>();
515
516 foreach (IRequestHandler reqHandler in caps.CapsHandlers.GetCapsHandlers().Values)
517 capRows.Add(new CapTableRow(reqHandler.Name, reqHandler.RequestsReceived, reqHandler.RequestsHandled));
518
519 foreach (KeyValuePair<string, PollServiceEventArgs> kvp in caps.GetPollHandlers())
520 capRows.Add(new CapTableRow(kvp.Key, kvp.Value.RequestsReceived, kvp.Value.RequestsHandled));
521
522 foreach (CapTableRow ctr in capRows.OrderByDescending(ctr => ctr.RequestsReceived))
523 cdt.AddRow(ctr.Name, ctr.RequestsReceived, ctr.RequestsHandled);
524
525 sb.Append(cdt.ToString());
526 */
527 }
528
529 private void BuildSummaryStatsByUserReport(StringBuilder sb)
530 {
531 /*
532 ConsoleDisplayTable cdt = new ConsoleDisplayTable();
533 cdt.AddColumn("Name", 32);
534 cdt.AddColumn("Type", 5);
535 cdt.AddColumn("Req Received", 12);
536 cdt.AddColumn("Req Handled", 12);
537 cdt.Indent = 2;
538
539 m_scene.ForEachScenePresence(
540 sp =>
541 {
542 Caps caps = m_scene.CapsModule.GetCapsForUser(sp.UUID);
543
544 if (caps == null)
545 return;
546
547 Dictionary<string, IRequestHandler> capsHandlers = caps.CapsHandlers.GetCapsHandlers();
548
549 int totalRequestsReceived = 0;
550 int totalRequestsHandled = 0;
551
552 foreach (IRequestHandler reqHandler in capsHandlers.Values)
553 {
554 totalRequestsReceived += reqHandler.RequestsReceived;
555 totalRequestsHandled += reqHandler.RequestsHandled;
556 }
557
558 Dictionary<string, PollServiceEventArgs> capsPollHandlers = caps.GetPollHandlers();
559
560 foreach (PollServiceEventArgs handler in capsPollHandlers.Values)
561 {
562 totalRequestsReceived += handler.RequestsReceived;
563 totalRequestsHandled += handler.RequestsHandled;
564 }
565
566 cdt.AddRow(sp.Name, sp.IsChildAgent ? "child" : "root", totalRequestsReceived, totalRequestsHandled);
567 }
568 );
569
570 sb.Append(cdt.ToString());
571 */
572 }
573
574 private class CapTableRow
575 {
576 public string Name { get; set; }
577 public int RequestsReceived { get; set; }
578 public int RequestsHandled { get; set; }
579
580 public CapTableRow(string name, int requestsReceived, int requestsHandled)
581 {
582 Name = name;
583 RequestsReceived = requestsReceived;
584 RequestsHandled = requestsHandled;
585 }
266 } 586 }
267 } 587 }
268} 588}
diff --git a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs
index 1f1568f..0c632b1 100644
--- a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs
@@ -44,11 +44,12 @@ namespace OpenSim.Region.CoreModules.Framework.DynamicAttributes.DAExampleModule
44 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DAExampleModule")] 44 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DAExampleModule")]
45 public class DAExampleModule : INonSharedRegionModule 45 public class DAExampleModule : INonSharedRegionModule
46 { 46 {
47// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48 48
49 private static readonly bool ENABLED = false; // enable for testing 49 private readonly bool ENABLED = false; // enable for testing
50 50
51 public const string DANamespace = "DAExample Module"; 51 public const string Namespace = "Example";
52 public const string StoreName = "DA";
52 53
53 protected Scene m_scene; 54 protected Scene m_scene;
54 protected IDialogModule m_dialogMod; 55 protected IDialogModule m_dialogMod;
@@ -65,6 +66,8 @@ namespace OpenSim.Region.CoreModules.Framework.DynamicAttributes.DAExampleModule
65 m_scene = scene; 66 m_scene = scene;
66 m_scene.EventManager.OnSceneGroupMove += OnSceneGroupMove; 67 m_scene.EventManager.OnSceneGroupMove += OnSceneGroupMove;
67 m_dialogMod = m_scene.RequestModuleInterface<IDialogModule>(); 68 m_dialogMod = m_scene.RequestModuleInterface<IDialogModule>();
69
70 m_log.DebugFormat("[DA EXAMPLE MODULE]: Added region {0}", m_scene.Name);
68 } 71 }
69 } 72 }
70 73
@@ -91,7 +94,7 @@ namespace OpenSim.Region.CoreModules.Framework.DynamicAttributes.DAExampleModule
91 if (sop == null) 94 if (sop == null)
92 return true; 95 return true;
93 96
94 if (!sop.DynAttrs.TryGetValue(DANamespace, out attrs)) 97 if (!sop.DynAttrs.TryGetStore(Namespace, StoreName, out attrs))
95 attrs = new OSDMap(); 98 attrs = new OSDMap();
96 99
97 OSDInteger newValue; 100 OSDInteger newValue;
@@ -106,12 +109,14 @@ namespace OpenSim.Region.CoreModules.Framework.DynamicAttributes.DAExampleModule
106 109
107 attrs["moves"] = newValue; 110 attrs["moves"] = newValue;
108 111
109 sop.DynAttrs[DANamespace] = attrs; 112 sop.DynAttrs.SetStore(Namespace, StoreName, attrs);
110 } 113 }
111 114
112 sop.ParentGroup.HasGroupChanged = true; 115 sop.ParentGroup.HasGroupChanged = true;
113 116
114 m_dialogMod.SendGeneralAlert(string.Format("{0} {1} moved {2} times", sop.Name, sop.UUID, newValue)); 117 string msg = string.Format("{0} {1} moved {2} times", sop.Name, sop.UUID, newValue);
118 m_log.DebugFormat("[DA EXAMPLE MODULE]: {0}", msg);
119 m_dialogMod.SendGeneralAlert(msg);
115 120
116 return true; 121 return true;
117 } 122 }
diff --git a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs
index 650aa35..166a994 100644
--- a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs
@@ -64,8 +64,8 @@ namespace OpenSim.Region.Framework.DynamicAttributes.DOExampleModule
64 64
65 private Scene m_scene; 65 private Scene m_scene;
66 private IDialogModule m_dialogMod; 66 private IDialogModule m_dialogMod;
67 67
68 public string Name { get { return "DOExample Module"; } } 68 public string Name { get { return "DO"; } }
69 public Type ReplaceableInterface { get { return null; } } 69 public Type ReplaceableInterface { get { return null; } }
70 70
71 public void Initialise(IConfigSource source) {} 71 public void Initialise(IConfigSource source) {}
@@ -106,7 +106,7 @@ namespace OpenSim.Region.Framework.DynamicAttributes.DOExampleModule
106 106
107// Console.WriteLine("Here for {0}", so.Name); 107// Console.WriteLine("Here for {0}", so.Name);
108 108
109 if (rootPart.DynAttrs.TryGetValue(DAExampleModule.DANamespace, out attrs)) 109 if (rootPart.DynAttrs.TryGetStore(DAExampleModule.Namespace, DAExampleModule.StoreName, out attrs))
110 { 110 {
111 movesSoFar = attrs["moves"].AsInteger(); 111 movesSoFar = attrs["moves"].AsInteger();
112 112
@@ -114,7 +114,7 @@ namespace OpenSim.Region.Framework.DynamicAttributes.DOExampleModule
114 "[DO EXAMPLE MODULE]: Found saved moves {0} for {1} in {2}", movesSoFar, so.Name, m_scene.Name); 114 "[DO EXAMPLE MODULE]: Found saved moves {0} for {1} in {2}", movesSoFar, so.Name, m_scene.Name);
115 } 115 }
116 116
117 rootPart.DynObjs.Add(Name, new MyObject(movesSoFar)); 117 rootPart.DynObjs.Add(DAExampleModule.Namespace, Name, new MyObject(movesSoFar));
118 } 118 }
119 119
120 private bool OnSceneGroupMove(UUID groupId, Vector3 delta) 120 private bool OnSceneGroupMove(UUID groupId, Vector3 delta)
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index ed867b8..5fea0cf 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -51,11 +51,19 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
51 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "EntityTransferModule")] 51 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "EntityTransferModule")]
52 public class EntityTransferModule : INonSharedRegionModule, IEntityTransferModule 52 public class EntityTransferModule : INonSharedRegionModule, IEntityTransferModule
53 { 53 {
54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55 private static readonly string LogHeader = "[ENTITY TRANSFER MODULE]";
55 56
56 public const int DefaultMaxTransferDistance = 4095; 57 public const int DefaultMaxTransferDistance = 4095;
57 public const bool WaitForAgentArrivedAtDestinationDefault = true; 58 public const bool WaitForAgentArrivedAtDestinationDefault = true;
58 59
60 public string OutgoingTransferVersionName { get; set; }
61
62 /// <summary>
63 /// Determine the maximum entity transfer version we will use for teleports.
64 /// </summary>
65 public float MaxOutgoingTransferVersion { get; set; }
66
59 /// <summary> 67 /// <summary>
60 /// The maximum distance, in standard region units (256m) that an agent is allowed to transfer. 68 /// The maximum distance, in standard region units (256m) that an agent is allowed to transfer.
61 /// </summary> 69 /// </summary>
@@ -151,9 +159,39 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
151 /// <param name="source"></param> 159 /// <param name="source"></param>
152 protected virtual void InitialiseCommon(IConfigSource source) 160 protected virtual void InitialiseCommon(IConfigSource source)
153 { 161 {
162 string transferVersionName = "SIMULATION";
163 float maxTransferVersion = 0.2f;
164
154 IConfig transferConfig = source.Configs["EntityTransfer"]; 165 IConfig transferConfig = source.Configs["EntityTransfer"];
155 if (transferConfig != null) 166 if (transferConfig != null)
156 { 167 {
168 string rawVersion
169 = transferConfig.GetString(
170 "MaxOutgoingTransferVersion",
171 string.Format("{0}/{1}", transferVersionName, maxTransferVersion));
172
173 string[] rawVersionComponents = rawVersion.Split(new char[] { '/' });
174
175 bool versionValid = false;
176
177 if (rawVersionComponents.Length >= 2)
178 versionValid = float.TryParse(rawVersionComponents[1], out maxTransferVersion);
179
180 if (!versionValid)
181 {
182 m_log.ErrorFormat(
183 "[ENTITY TRANSFER MODULE]: MaxOutgoingTransferVersion {0} is invalid, using {1}",
184 rawVersion, string.Format("{0}/{1}", transferVersionName, maxTransferVersion));
185 }
186 else
187 {
188 transferVersionName = rawVersionComponents[0];
189
190 m_log.InfoFormat(
191 "[ENTITY TRANSFER MODULE]: MaxOutgoingTransferVersion set to {0}",
192 string.Format("{0}/{1}", transferVersionName, maxTransferVersion));
193 }
194
157 DisableInterRegionTeleportCancellation 195 DisableInterRegionTeleportCancellation
158 = transferConfig.GetBoolean("DisableInterRegionTeleportCancellation", false); 196 = transferConfig.GetBoolean("DisableInterRegionTeleportCancellation", false);
159 197
@@ -167,6 +205,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
167 MaxTransferDistance = DefaultMaxTransferDistance; 205 MaxTransferDistance = DefaultMaxTransferDistance;
168 } 206 }
169 207
208 OutgoingTransferVersionName = transferVersionName;
209 MaxOutgoingTransferVersion = maxTransferVersion;
210
170 m_entityTransferStateMachine = new EntityTransferStateMachine(this); 211 m_entityTransferStateMachine = new EntityTransferStateMachine(this);
171 212
172 m_Enabled = true; 213 m_Enabled = true;
@@ -280,10 +321,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
280 321
281 private void OnConnectionClosed(IClientAPI client) 322 private void OnConnectionClosed(IClientAPI client)
282 { 323 {
283 if (client.IsLoggingOut) 324 if (client.IsLoggingOut && m_entityTransferStateMachine.UpdateInTransit(client.AgentId, AgentTransferState.Aborting))
284 { 325 {
285 m_entityTransferStateMachine.UpdateInTransit(client.AgentId, AgentTransferState.Aborting);
286
287 m_log.DebugFormat( 326 m_log.DebugFormat(
288 "[ENTITY TRANSFER MODULE]: Aborted teleport request from {0} in {1} due to simultaneous logout", 327 "[ENTITY TRANSFER MODULE]: Aborted teleport request from {0} in {1} due to simultaneous logout",
289 client.Name, Scene.Name); 328 client.Name, Scene.Name);
@@ -318,7 +357,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
318 m_log.DebugFormat( 357 m_log.DebugFormat(
319 "[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2}@{3} - agent is already in transit.", 358 "[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2}@{3} - agent is already in transit.",
320 sp.Name, sp.UUID, position, regionHandle); 359 sp.Name, sp.UUID, position, regionHandle);
321 360
361 sp.ControllingClient.SendTeleportFailed("Previous teleport process incomplete. Please retry shortly.");
362
322 return; 363 return;
323 } 364 }
324 365
@@ -522,6 +563,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
522 /// </returns> 563 /// </returns>
523 private bool IsWithinMaxTeleportDistance(RegionInfo sourceRegion, GridRegion destRegion) 564 private bool IsWithinMaxTeleportDistance(RegionInfo sourceRegion, GridRegion destRegion)
524 { 565 {
566 if(MaxTransferDistance == 0)
567 return true;
568
525// m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Source co-ords are x={0} y={1}", curRegionX, curRegionY); 569// m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Source co-ords are x={0} y={1}", curRegionX, curRegionY);
526// 570//
527// m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Final dest is x={0} y={1} {2}@{3}", 571// m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Final dest is x={0} y={1} {2}@{3}",
@@ -623,7 +667,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
623 if (!sp.ValidateAttachments()) 667 if (!sp.ValidateAttachments())
624 m_log.DebugFormat( 668 m_log.DebugFormat(
625 "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.", 669 "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.",
626 sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName); 670 sp.Name, sp.Scene.Name, finalDestination.RegionName);
627 671
628 string reason; 672 string reason;
629 string version; 673 string version;
@@ -634,7 +678,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
634 678
635 m_log.DebugFormat( 679 m_log.DebugFormat(
636 "[ENTITY TRANSFER MODULE]: {0} was stopped from teleporting from {1} to {2} because {3}", 680 "[ENTITY TRANSFER MODULE]: {0} was stopped from teleporting from {1} to {2} because {3}",
637 sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason); 681 sp.Name, sp.Scene.Name, finalDestination.RegionName, reason);
638 682
639 return; 683 return;
640 } 684 }
@@ -644,7 +688,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
644 // as server attempts. 688 // as server attempts.
645 m_interRegionTeleportAttempts.Value++; 689 m_interRegionTeleportAttempts.Value++;
646 690
647 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version); 691 m_log.DebugFormat(
692 "[ENTITY TRANSFER MODULE]: {0} max transfer version is {1}/{2}, {3} max version is {4}",
693 sp.Scene.Name, OutgoingTransferVersionName, MaxOutgoingTransferVersion, finalDestination.RegionName, version);
648 694
649 // Fixing a bug where teleporting while sitting results in the avatar ending up removed from 695 // Fixing a bug where teleporting while sitting results in the avatar ending up removed from
650 // both regions 696 // both regions
@@ -691,6 +737,29 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
691 agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); 737 agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath();
692 } 738 }
693 739
740 // We're going to fallback to V1 if the destination gives us anything smaller than 0.2 or we're forcing
741 // use of the earlier protocol
742 float versionNumber = 0.1f;
743 string[] versionComponents = version.Split(new char[] { '/' });
744 if (versionComponents.Length >= 2)
745 float.TryParse(versionComponents[1], out versionNumber);
746
747 if (versionNumber == 0.2f && MaxOutgoingTransferVersion >= versionNumber)
748 TransferAgent_V2(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, oldRegionX, newRegionX, oldRegionY, newRegionY, version, out reason);
749 else
750 TransferAgent_V1(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, oldRegionX, newRegionX, oldRegionY, newRegionY, version, out reason);
751 }
752
753 private void TransferAgent_V1(ScenePresence sp, AgentCircuitData agentCircuit, GridRegion reg, GridRegion finalDestination,
754 IPEndPoint endPoint, uint teleportFlags, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, string version, out string reason)
755 {
756 ulong destinationHandle = finalDestination.RegionHandle;
757 AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
758
759 m_log.DebugFormat(
760 "[ENTITY TRANSFER MODULE]: Using TP V1 for {0} going from {1} to {2}",
761 sp.Name, Scene.Name, finalDestination.RegionName);
762
694 // Let's create an agent there if one doesn't exist yet. 763 // Let's create an agent there if one doesn't exist yet.
695 // NOTE: logout will always be false for a non-HG teleport. 764 // NOTE: logout will always be false for a non-HG teleport.
696 bool logout = false; 765 bool logout = false;
@@ -712,7 +781,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
712 m_interRegionTeleportCancels.Value++; 781 m_interRegionTeleportCancels.Value++;
713 782
714 m_log.DebugFormat( 783 m_log.DebugFormat(
715 "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after CreateAgent on client request", 784 "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after CreateAgent on client request",
716 sp.Name, finalDestination.RegionName, sp.Scene.Name); 785 sp.Name, finalDestination.RegionName, sp.Scene.Name);
717 786
718 return; 787 return;
@@ -734,11 +803,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
734 // OK, it got this agent. Let's close some child agents 803 // OK, it got this agent. Let's close some child agents
735 sp.CloseChildAgents(newRegionX, newRegionY); 804 sp.CloseChildAgents(newRegionX, newRegionY);
736 805
737 IClientIPEndpoint ipepClient; 806 IClientIPEndpoint ipepClient;
807 string capsPath = String.Empty;
738 if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) 808 if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY))
739 { 809 {
740 m_log.DebugFormat( 810 m_log.DebugFormat(
741 "[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} needs new child agent for incoming agent {3} from {4}", 811 "[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} needs new child agent for incoming agent {3} from {4}",
742 finalDestination.RegionName, newRegionX, newRegionY, sp.Name, Scene.Name); 812 finalDestination.RegionName, newRegionX, newRegionY, sp.Name, Scene.Name);
743 813
744 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent..."); 814 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent...");
@@ -756,7 +826,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
756 // The EnableSimulator message makes the client establish a connection with the destination 826 // The EnableSimulator message makes the client establish a connection with the destination
757 // simulator by sending the initial UseCircuitCode UDP packet to the destination containing the 827 // simulator by sending the initial UseCircuitCode UDP packet to the destination containing the
758 // correct circuit code. 828 // correct circuit code.
759 m_eqModule.EnableSimulator(destinationHandle, endPoint, sp.UUID); 829 m_eqModule.EnableSimulator(destinationHandle, endPoint, sp.UUID,
830 finalDestination.RegionSizeX, finalDestination.RegionSizeY);
831 m_log.DebugFormat("{0} Sent EnableSimulator. regName={1}, size=<{2},{3}>", LogHeader,
832 finalDestination.RegionName, finalDestination.RegionSizeX, finalDestination.RegionSizeY);
760 833
761 // XXX: Is this wait necessary? We will always end up waiting on UpdateAgent for the destination 834 // XXX: Is this wait necessary? We will always end up waiting on UpdateAgent for the destination
762 // simulator to confirm that it has established communication with the viewer. 835 // simulator to confirm that it has established communication with the viewer.
@@ -766,7 +839,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
766 // unnecessary - teleport will succeed and SEED caps will be requested without it (though possibly 839 // unnecessary - teleport will succeed and SEED caps will be requested without it (though possibly
767 // only on TeleportFinish). This is untested for region teleport between different simulators 840 // only on TeleportFinish). This is untested for region teleport between different simulators
768 // though this probably also works. 841 // though this probably also works.
769 m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); 842 m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath, finalDestination.RegionHandle,
843 finalDestination.RegionSizeX, finalDestination.RegionSizeY);
770 } 844 }
771 else 845 else
772 { 846 {
@@ -785,10 +859,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
785 // Let's send a full update of the agent. This is a synchronous call. 859 // Let's send a full update of the agent. This is a synchronous call.
786 AgentData agent = new AgentData(); 860 AgentData agent = new AgentData();
787 sp.CopyTo(agent); 861 sp.CopyTo(agent);
788 agent.Position = position; 862 agent.Position = agentCircuit.startpos;
789 SetCallbackURL(agent, sp.Scene.RegionInfo); 863 SetCallbackURL(agent, sp.Scene.RegionInfo);
790 864
791 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent...");
792 865
793 // We will check for an abort before UpdateAgent since UpdateAgent will require an active viewer to 866 // We will check for an abort before UpdateAgent since UpdateAgent will require an active viewer to
794 // establish th econnection to the destination which makes it return true. 867 // establish th econnection to the destination which makes it return true.
@@ -821,10 +894,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
821 } 894 }
822 895
823 m_log.WarnFormat( 896 m_log.WarnFormat(
824 "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Keeping avatar in source region.", 897 "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1}. Keeping avatar in {2}",
825 sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); 898 sp.Name, finalDestination.RegionName, sp.Scene.Name);
826 899
827 Fail(sp, finalDestination, logout, "Connection between viewer and destination region could not be established."); 900 Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Connection between viewer and destination region could not be established.");
828 return; 901 return;
829 } 902 }
830 903
@@ -833,10 +906,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
833 m_interRegionTeleportCancels.Value++; 906 m_interRegionTeleportCancels.Value++;
834 907
835 m_log.DebugFormat( 908 m_log.DebugFormat(
836 "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after UpdateAgent on client request", 909 "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after UpdateAgent on client request",
837 sp.Name, finalDestination.RegionName, sp.Scene.Name); 910 sp.Name, finalDestination.RegionName, sp.Scene.Name);
838 911
839 CleanupFailedInterRegionTeleport(sp, finalDestination); 912 CleanupFailedInterRegionTeleport(sp, currentAgentCircuit.SessionID.ToString(), finalDestination);
840 913
841 return; 914 return;
842 } 915 }
@@ -850,9 +923,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
850 // closes our existing agent which is still signalled as root. 923 // closes our existing agent which is still signalled as root.
851 sp.IsChildAgent = true; 924 sp.IsChildAgent = true;
852 925
926 // OK, send TPFinish to the client, so that it starts the process of contacting the destination region
853 if (m_eqModule != null) 927 if (m_eqModule != null)
854 { 928 {
855 m_eqModule.TeleportFinishEvent(destinationHandle, 13, endPoint, 0, teleportFlags, capsPath, sp.UUID); 929 m_eqModule.TeleportFinishEvent(destinationHandle, 13, endPoint, 0, teleportFlags, capsPath, sp.UUID,
930 finalDestination.RegionSizeX, finalDestination.RegionSizeY);
856 } 931 }
857 else 932 else
858 { 933 {
@@ -879,8 +954,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
879 m_log.WarnFormat( 954 m_log.WarnFormat(
880 "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.", 955 "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.",
881 sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); 956 sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName);
882 957
883 Fail(sp, finalDestination, logout, "Destination region did not signal teleport completion."); 958 Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Destination region did not signal teleport completion.");
884 959
885 return; 960 return;
886 } 961 }
@@ -908,15 +983,190 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
908 983
909 if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) 984 if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg))
910 { 985 {
986 if (!sp.Scene.IncomingPreCloseClient(sp))
987 return;
988
911 // We need to delay here because Imprudence viewers, unlike v1 or v3, have a short (<200ms, <500ms) delay before 989 // We need to delay here because Imprudence viewers, unlike v1 or v3, have a short (<200ms, <500ms) delay before
912 // they regard the new region as the current region after receiving the AgentMovementComplete 990 // they regard the new region as the current region after receiving the AgentMovementComplete
913 // response. If close is sent before then, it will cause the viewer to quit instead. 991 // response. If close is sent before then, it will cause the viewer to quit instead.
914 // 992 //
915 // This sleep can be increased if necessary. However, whilst it's active, 993 // This sleep can be increased if necessary. However, whilst it's active,
916 // an agent cannot teleport back to this region if it has teleported away. 994 // an agent cannot teleport back to this region if it has teleported away.
917 Thread.Sleep(3000); 995 Thread.Sleep(2000);
918 996
919 sp.Scene.IncomingCloseAgent(sp.UUID, false); 997 sp.Scene.CloseAgent(sp.UUID, false);
998 }
999 else
1000 {
1001 // now we have a child agent in this region.
1002 sp.Reset();
1003 }
1004 }
1005
1006 private void TransferAgent_V2(ScenePresence sp, AgentCircuitData agentCircuit, GridRegion reg, GridRegion finalDestination,
1007 IPEndPoint endPoint, uint teleportFlags, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, string version, out string reason)
1008 {
1009 ulong destinationHandle = finalDestination.RegionHandle;
1010 AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
1011
1012 // Let's create an agent there if one doesn't exist yet.
1013 // NOTE: logout will always be false for a non-HG teleport.
1014 bool logout = false;
1015 if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout))
1016 {
1017 m_interRegionTeleportFailures.Value++;
1018
1019 sp.ControllingClient.SendTeleportFailed(String.Format("Teleport refused: {0}", reason));
1020
1021 m_log.DebugFormat(
1022 "[ENTITY TRANSFER MODULE]: Teleport of {0} from {1} to {2} was refused because {3}",
1023 sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason);
1024
1025 return;
1026 }
1027
1028 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Cancelling)
1029 {
1030 m_interRegionTeleportCancels.Value++;
1031
1032 m_log.DebugFormat(
1033 "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after CreateAgent on client request",
1034 sp.Name, finalDestination.RegionName, sp.Scene.Name);
1035
1036 return;
1037 }
1038 else if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
1039 {
1040 m_interRegionTeleportAborts.Value++;
1041
1042 m_log.DebugFormat(
1043 "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after CreateAgent due to previous client close.",
1044 sp.Name, finalDestination.RegionName, sp.Scene.Name);
1045
1046 return;
1047 }
1048
1049 // Past this point we have to attempt clean up if the teleport fails, so update transfer state.
1050 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring);
1051
1052 IClientIPEndpoint ipepClient;
1053 string capsPath = String.Empty;
1054 if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY))
1055 {
1056 m_log.DebugFormat(
1057 "[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} needs new child agent for agent {3} from {4}",
1058 finalDestination.RegionName, newRegionX, newRegionY, sp.Name, Scene.Name);
1059
1060 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent...");
1061 #region IP Translation for NAT
1062 // Uses ipepClient above
1063 if (sp.ClientView.TryGet(out ipepClient))
1064 {
1065 endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address);
1066 }
1067 #endregion
1068 capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
1069 }
1070 else
1071 {
1072 agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle);
1073 capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
1074 }
1075
1076 // We need to set this here to avoid an unlikely race condition when teleporting to a neighbour simulator,
1077 // where that neighbour simulator could otherwise request a child agent create on the source which then
1078 // closes our existing agent which is still signalled as root.
1079 //sp.IsChildAgent = true;
1080
1081 // New protocol: send TP Finish directly, without prior ES or EAC. That's what happens in the Linden grid
1082 if (m_eqModule != null)
1083 m_eqModule.TeleportFinishEvent(destinationHandle, 13, endPoint, 0, teleportFlags, capsPath, sp.UUID,
1084 finalDestination.RegionSizeX, finalDestination.RegionSizeY);
1085 else
1086 sp.ControllingClient.SendRegionTeleport(destinationHandle, 13, endPoint, 4,
1087 teleportFlags, capsPath);
1088
1089 m_log.DebugFormat(
1090 "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} from {1} to {2}",
1091 capsPath, sp.Scene.RegionInfo.RegionName, sp.Name);
1092
1093 // Let's send a full update of the agent.
1094 AgentData agent = new AgentData();
1095 sp.CopyTo(agent);
1096 agent.Position = agentCircuit.startpos;
1097 agent.SenderWantsToWaitForRoot = true;
1098 //SetCallbackURL(agent, sp.Scene.RegionInfo);
1099
1100 // Reset the do not close flag. This must be done before the destination opens child connections (here
1101 // triggered by UpdateAgent) to avoid race conditions. However, we also want to reset it as late as possible
1102 // to avoid a situation where an unexpectedly early call to Scene.NewUserConnection() wrongly results
1103 // in no close.
1104 sp.DoNotCloseAfterTeleport = false;
1105
1106 // Send the Update. If this returns true, we know the client has contacted the destination
1107 // via CompleteMovementIntoRegion, so we can let go.
1108 // If it returns false, something went wrong, and we need to abort.
1109 if (!UpdateAgent(reg, finalDestination, agent, sp))
1110 {
1111 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
1112 {
1113 m_interRegionTeleportAborts.Value++;
1114
1115 m_log.DebugFormat(
1116 "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after UpdateAgent due to previous client close.",
1117 sp.Name, finalDestination.RegionName, sp.Scene.Name);
1118
1119 return;
1120 }
1121
1122 m_log.WarnFormat(
1123 "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1}. Keeping avatar in {2}",
1124 sp.Name, finalDestination.RegionName, sp.Scene.Name);
1125
1126 Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Connection between viewer and destination region could not be established.");
1127 return;
1128 }
1129
1130 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp);
1131
1132 // Need to signal neighbours whether child agents may need closing irrespective of whether this
1133 // one needed closing. We also need to close child agents as quickly as possible to avoid complicated
1134 // race conditions with rapid agent releporting (e.g. from A1 to a non-neighbour B, back
1135 // to a neighbour A2 then off to a non-neighbour C). Closing child agents any later requires complex
1136 // distributed checks to avoid problems in rapid reteleporting scenarios and where child agents are
1137 // abandoned without proper close by viewer but then re-used by an incoming connection.
1138 sp.CloseChildAgents(newRegionX, newRegionY);
1139
1140 // May need to logout or other cleanup
1141 AgentHasMovedAway(sp, logout);
1142
1143 // Well, this is it. The agent is over there.
1144 KillEntity(sp.Scene, sp.LocalId);
1145
1146 // Now let's make it officially a child agent
1147 sp.MakeChildAgent();
1148
1149 // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone
1150 if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg))
1151 {
1152 if (!sp.Scene.IncomingPreCloseClient(sp))
1153 return;
1154
1155 // RED ALERT!!!!
1156 // PLEASE DO NOT DECREASE THIS WAIT TIME UNDER ANY CIRCUMSTANCES.
1157 // THE VIEWERS SEEM TO NEED SOME TIME AFTER RECEIVING MoveAgentIntoRegion
1158 // BEFORE THEY SETTLE IN THE NEW REGION.
1159 // DECREASING THE WAIT TIME HERE WILL EITHER RESULT IN A VIEWER CRASH OR
1160 // IN THE AVIE BEING PLACED IN INFINITY FOR A COUPLE OF SECONDS.
1161 Thread.Sleep(15000);
1162
1163 // OK, it got this agent. Let's close everything
1164 // If we shouldn't close the agent due to some other region renewing the connection
1165 // then this will be handled in IncomingCloseAgent under lock conditions
1166 m_log.DebugFormat(
1167 "[ENTITY TRANSFER MODULE]: Closing agent {0} in {1} after teleport", sp.Name, Scene.Name);
1168
1169 sp.Scene.CloseAgent(sp.UUID, false);
920 } 1170 }
921 else 1171 else
922 { 1172 {
@@ -934,17 +1184,20 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
934 /// <remarks> 1184 /// <remarks>
935 /// <param name='sp'> </param> 1185 /// <param name='sp'> </param>
936 /// <param name='finalDestination'></param> 1186 /// <param name='finalDestination'></param>
937 protected virtual void CleanupFailedInterRegionTeleport(ScenePresence sp, GridRegion finalDestination) 1187 protected virtual void CleanupFailedInterRegionTeleport(ScenePresence sp, string auth_token, GridRegion finalDestination)
938 { 1188 {
939 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); 1189 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp);
940 1190
941 sp.IsChildAgent = false; 1191 if (sp.IsChildAgent) // We had set it to child before attempted TP (V1)
942 ReInstantiateScripts(sp); 1192 {
943 1193 sp.IsChildAgent = false;
944 EnableChildAgents(sp); 1194 ReInstantiateScripts(sp);
945 1195
1196 EnableChildAgents(sp);
1197 }
946 // Finally, kill the agent we just created at the destination. 1198 // Finally, kill the agent we just created at the destination.
947 Scene.SimulationService.CloseAgent(finalDestination, sp.UUID); 1199 // XXX: Possibly this should be done asynchronously.
1200 Scene.SimulationService.CloseAgent(finalDestination, sp.UUID, auth_token);
948 } 1201 }
949 1202
950 /// <summary> 1203 /// <summary>
@@ -954,9 +1207,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
954 /// <param name='finalDestination'></param> 1207 /// <param name='finalDestination'></param>
955 /// <param name='logout'></param> 1208 /// <param name='logout'></param>
956 /// <param name='reason'>Human readable reason for teleport failure. Will be sent to client.</param> 1209 /// <param name='reason'>Human readable reason for teleport failure. Will be sent to client.</param>
957 protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout, string reason) 1210 protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout, string auth_code, string reason)
958 { 1211 {
959 CleanupFailedInterRegionTeleport(sp, finalDestination); 1212 CleanupFailedInterRegionTeleport(sp, auth_code, finalDestination);
960 1213
961 m_interRegionTeleportFailures.Value++; 1214 m_interRegionTeleportFailures.Value++;
962 1215
@@ -1132,7 +1385,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1132 public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos) 1385 public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos)
1133 { 1386 {
1134 version = String.Empty; 1387 version = String.Empty;
1135 newpos = new Vector3(pos.X, pos.Y, pos.Z); 1388 newpos = pos;
1136 1389
1137// m_log.DebugFormat( 1390// m_log.DebugFormat(
1138// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name); 1391// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name);
@@ -1471,11 +1724,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1471 if (m_eqModule != null) 1724 if (m_eqModule != null)
1472 { 1725 {
1473 m_eqModule.CrossRegion( 1726 m_eqModule.CrossRegion(
1474 neighbourRegion.RegionHandle, pos + agent.Velocity, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint, 1727 neighbourRegion.RegionHandle, pos + agent.Velocity, vel2 /* agent.Velocity */,
1475 capsPath, agent.UUID, agent.ControllingClient.SessionId); 1728 neighbourRegion.ExternalEndPoint,
1729 capsPath, agent.UUID, agent.ControllingClient.SessionId,
1730 neighbourRegion.RegionSizeX, neighbourRegion.RegionSizeY);
1476 } 1731 }
1477 else 1732 else
1478 { 1733 {
1734 m_log.ErrorFormat("{0} Using old CrossRegion packet. Varregion will not work!!", LogHeader);
1479 agent.ControllingClient.CrossRegion(neighbourRegion.RegionHandle, pos + agent.Velocity, agent.Velocity, neighbourRegion.ExternalEndPoint, 1735 agent.ControllingClient.CrossRegion(neighbourRegion.RegionHandle, pos + agent.Velocity, agent.Velocity, neighbourRegion.ExternalEndPoint,
1480 capsPath); 1736 capsPath);
1481 } 1737 }
@@ -1654,10 +1910,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1654 List<ulong> newRegions = NewNeighbours(neighbourHandles, previousRegionNeighbourHandles); 1910 List<ulong> newRegions = NewNeighbours(neighbourHandles, previousRegionNeighbourHandles);
1655 List<ulong> oldRegions = OldNeighbours(neighbourHandles, previousRegionNeighbourHandles); 1911 List<ulong> oldRegions = OldNeighbours(neighbourHandles, previousRegionNeighbourHandles);
1656 1912
1657 //Dump("Current Neighbors", neighbourHandles); 1913// Dump("Current Neighbors", neighbourHandles);
1658 //Dump("Previous Neighbours", previousRegionNeighbourHandles); 1914// Dump("Previous Neighbours", previousRegionNeighbourHandles);
1659 //Dump("New Neighbours", newRegions); 1915// Dump("New Neighbours", newRegions);
1660 //Dump("Old Neighbours", oldRegions); 1916// Dump("Old Neighbours", oldRegions);
1661 1917
1662 /// Update the scene presence's known regions here on this region 1918 /// Update the scene presence's known regions here on this region
1663 sp.DropOldNeighbours(oldRegions); 1919 sp.DropOldNeighbours(oldRegions);
@@ -1665,8 +1921,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1665 /// Collect as many seeds as possible 1921 /// Collect as many seeds as possible
1666 Dictionary<ulong, string> seeds; 1922 Dictionary<ulong, string> seeds;
1667 if (sp.Scene.CapsModule != null) 1923 if (sp.Scene.CapsModule != null)
1668 seeds 1924 seeds = new Dictionary<ulong, string>(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID));
1669 = new Dictionary<ulong, string>(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID));
1670 else 1925 else
1671 seeds = new Dictionary<ulong, string>(); 1926 seeds = new Dictionary<ulong, string>();
1672 1927
@@ -1736,6 +1991,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1736 newAgent = true; 1991 newAgent = true;
1737 else 1992 else
1738 newAgent = false; 1993 newAgent = false;
1994// continue;
1739 1995
1740 if (neighbour.RegionHandle != sp.Scene.RegionInfo.RegionHandle) 1996 if (neighbour.RegionHandle != sp.Scene.RegionInfo.RegionHandle)
1741 { 1997 {
@@ -1841,12 +2097,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1841 } 2097 }
1842 #endregion 2098 #endregion
1843 2099
1844 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: {0} is sending {1} EnableSimulator for neighbour region {2} @ {3} " + 2100 m_log.DebugFormat("{0} {1} is sending {2} EnableSimulator for neighbour region {3}(loc=<{4},{5}>,siz=<{6},{7}>) " +
1845 "and EstablishAgentCommunication with seed cap {4}", 2101 "and EstablishAgentCommunication with seed cap {8}", LogHeader,
1846 scene.RegionInfo.RegionName, sp.Name, reg.RegionName, reg.RegionHandle, capsPath); 2102 scene.RegionInfo.RegionName, sp.Name,
2103 reg.RegionName, reg.RegionLocX, reg.RegionLocY, reg.RegionSizeX, reg.RegionSizeY , capsPath);
1847 2104
1848 m_eqModule.EnableSimulator(reg.RegionHandle, endPoint, sp.UUID); 2105 m_eqModule.EnableSimulator(reg.RegionHandle, endPoint, sp.UUID, reg.RegionSizeX, reg.RegionSizeY);
1849 m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); 2106 m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath, reg.RegionHandle, reg.RegionSizeX, reg.RegionSizeY);
1850 } 2107 }
1851 else 2108 else
1852 { 2109 {
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
index d372c0e..7abdc21 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
@@ -53,8 +53,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
53 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 53 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
54 54
55 private int m_levelHGTeleport = 0; 55 private int m_levelHGTeleport = 0;
56 private string m_ThisHomeURI;
56 57
57 private GatekeeperServiceConnector m_GatekeeperConnector; 58 private GatekeeperServiceConnector m_GatekeeperConnector;
59 private IUserAgentService m_UAS;
58 60
59 protected bool m_RestrictAppearanceAbroad; 61 protected bool m_RestrictAppearanceAbroad;
60 protected string m_AccountName; 62 protected string m_AccountName;
@@ -143,6 +145,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
143 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: {0} enabled.", Name); 145 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: {0} enabled.", Name);
144 } 146 }
145 } 147 }
148
149 moduleConfig = source.Configs["Hypergrid"];
150 if (moduleConfig != null)
151 {
152 m_ThisHomeURI = moduleConfig.GetString("HomeURI", string.Empty);
153 if (m_ThisHomeURI != string.Empty && !m_ThisHomeURI.EndsWith("/"))
154 m_ThisHomeURI += '/';
155 }
146 } 156 }
147 157
148 public override void AddRegion(Scene scene) 158 public override void AddRegion(Scene scene)
@@ -161,22 +171,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
161 if (!so.IsAttachment) 171 if (!so.IsAttachment)
162 return; 172 return;
163 173
164 if (so.Scene.UserManagementModule.IsLocalGridUser(so.AttachedAvatar)) 174 if (so.AttachedAvatar == UUID.Zero || Scene.UserManagementModule.IsLocalGridUser(so.AttachedAvatar))
165 return; 175 return;
166 176
167 // foreign user 177 // foreign user
168 AgentCircuitData aCircuit = so.Scene.AuthenticateHandler.GetAgentCircuitData(so.AttachedAvatar); 178 AgentCircuitData aCircuit = Scene.AuthenticateHandler.GetAgentCircuitData(so.AttachedAvatar);
169 if (aCircuit != null && (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0) 179 if (aCircuit != null && (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0)
170 { 180 {
171 if (aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("AssetServerURI")) 181 if (aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("AssetServerURI"))
172 { 182 {
173 string url = aCircuit.ServiceURLs["AssetServerURI"].ToString(); 183 string url = aCircuit.ServiceURLs["AssetServerURI"].ToString();
174 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Incoming attachement {0} for HG user {1} with asset server {2}", so.Name, so.AttachedAvatar, url); 184 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Incoming attachment {0} for HG user {1} with asset server {2}", so.Name, so.AttachedAvatar, url);
175 Dictionary<UUID, AssetType> ids = new Dictionary<UUID, AssetType>(); 185 Dictionary<UUID, sbyte> ids = new Dictionary<UUID, sbyte>();
176 HGUuidGatherer uuidGatherer = new HGUuidGatherer(so.Scene.AssetService, url); 186 HGUuidGatherer uuidGatherer = new HGUuidGatherer(Scene.AssetService, url);
177 uuidGatherer.GatherAssetUuids(so, ids); 187 uuidGatherer.GatherAssetUuids(so, ids);
178 188
179 foreach (KeyValuePair<UUID, AssetType> kvp in ids) 189 foreach (KeyValuePair<UUID, sbyte> kvp in ids)
180 uuidGatherer.FetchAsset(kvp.Key); 190 uuidGatherer.FetchAsset(kvp.Key);
181 } 191 }
182 } 192 }
@@ -194,7 +204,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
194 base.RegionLoaded(scene); 204 base.RegionLoaded(scene);
195 205
196 if (m_Enabled) 206 if (m_Enabled)
207 {
197 m_GatekeeperConnector = new GatekeeperServiceConnector(scene.AssetService); 208 m_GatekeeperConnector = new GatekeeperServiceConnector(scene.AssetService);
209 m_UAS = scene.RequestModuleInterface<IUserAgentService>();
210 if (m_UAS == null)
211 m_UAS = new UserAgentServiceConnector(m_ThisHomeURI);
212
213 }
198 } 214 }
199 215
200 public override void RemoveRegion(Scene scene) 216 public override void RemoveRegion(Scene scene)
@@ -272,8 +288,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
272 if (agentCircuit.ServiceURLs.ContainsKey("HomeURI")) 288 if (agentCircuit.ServiceURLs.ContainsKey("HomeURI"))
273 { 289 {
274 string userAgentDriver = agentCircuit.ServiceURLs["HomeURI"].ToString(); 290 string userAgentDriver = agentCircuit.ServiceURLs["HomeURI"].ToString();
275 IUserAgentService connector = new UserAgentServiceConnector(userAgentDriver); 291 IUserAgentService connector;
276 bool success = connector.LoginAgentToGrid(agentCircuit, reg, finalDestination, out reason); 292
293 if (userAgentDriver.Equals(m_ThisHomeURI) && m_UAS != null)
294 connector = m_UAS;
295 else
296 connector = new UserAgentServiceConnector(userAgentDriver);
297
298 bool success = connector.LoginAgentToGrid(agentCircuit, reg, finalDestination, false, out reason);
277 logout = success; // flag for later logout from this grid; this is an HG TP 299 logout = success; // flag for later logout from this grid; this is an HG TP
278 300
279 if (success) 301 if (success)
@@ -552,12 +574,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
552 if (uMan != null && uMan.IsLocalGridUser(obj.AgentId)) 574 if (uMan != null && uMan.IsLocalGridUser(obj.AgentId))
553 { 575 {
554 // local grid user 576 // local grid user
577 m_UAS.LogoutAgent(obj.AgentId, obj.SessionId);
555 return; 578 return;
556 } 579 }
557 580
558 AgentCircuitData aCircuit = ((Scene)(obj.Scene)).AuthenticateHandler.GetAgentCircuitData(obj.CircuitCode); 581 AgentCircuitData aCircuit = ((Scene)(obj.Scene)).AuthenticateHandler.GetAgentCircuitData(obj.CircuitCode);
559 582 if (aCircuit != null && aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("HomeURI"))
560 if (aCircuit.ServiceURLs.ContainsKey("HomeURI"))
561 { 583 {
562 string url = aCircuit.ServiceURLs["HomeURI"].ToString(); 584 string url = aCircuit.ServiceURLs["HomeURI"].ToString();
563 IUserAgentService security = new UserAgentServiceConnector(url); 585 IUserAgentService security = new UserAgentServiceConnector(url);
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
index 7871eda..d4fb1ba 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
@@ -73,6 +73,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
73 73
74 private AssetMetadata FetchMetadata(string url, UUID assetID) 74 private AssetMetadata FetchMetadata(string url, UUID assetID)
75 { 75 {
76 if (string.IsNullOrEmpty(url))
77 return null;
78
76 if (!url.EndsWith("/") && !url.EndsWith("=")) 79 if (!url.EndsWith("/") && !url.EndsWith("="))
77 url = url + "/"; 80 url = url + "/";
78 81
@@ -92,6 +95,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
92 AssetBase asset = m_scene.AssetService.Get(assetID.ToString()); 95 AssetBase asset = m_scene.AssetService.Get(assetID.ToString());
93 if (asset == null) 96 if (asset == null)
94 { 97 {
98 if (string.IsNullOrEmpty(url))
99 return null;
100
95 if (!url.EndsWith("/") && !url.EndsWith("=")) 101 if (!url.EndsWith("/") && !url.EndsWith("="))
96 url = url + "/"; 102 url = url + "/";
97 103
@@ -109,6 +115,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
109 115
110 public bool PostAsset(string url, AssetBase asset) 116 public bool PostAsset(string url, AssetBase asset)
111 { 117 {
118 if (string.IsNullOrEmpty(url))
119 return false;
120
112 if (asset != null) 121 if (asset != null)
113 { 122 {
114 if (!url.EndsWith("/") && !url.EndsWith("=")) 123 if (!url.EndsWith("/") && !url.EndsWith("="))
@@ -165,7 +174,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
165 174
166 private void AdjustIdentifiers(AssetMetadata meta) 175 private void AdjustIdentifiers(AssetMetadata meta)
167 { 176 {
168 if (meta.CreatorID != null && meta.CreatorID != string.Empty) 177 if (!string.IsNullOrEmpty(meta.CreatorID))
169 { 178 {
170 UUID uuid = UUID.Zero; 179 UUID uuid = UUID.Zero;
171 UUID.TryParse(meta.CreatorID, out uuid); 180 UUID.TryParse(meta.CreatorID, out uuid);
@@ -251,9 +260,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
251 260
252 // The act of gathering UUIDs downloads some assets from the remote server 261 // The act of gathering UUIDs downloads some assets from the remote server
253 // but not all... 262 // but not all...
254 Dictionary<UUID, AssetType> ids = new Dictionary<UUID, AssetType>(); 263 Dictionary<UUID, sbyte> ids = new Dictionary<UUID, sbyte>();
255 HGUuidGatherer uuidGatherer = new HGUuidGatherer(m_scene.AssetService, userAssetURL); 264 HGUuidGatherer uuidGatherer = new HGUuidGatherer(m_scene.AssetService, userAssetURL);
256 uuidGatherer.GatherAssetUuids(assetID, (AssetType)meta.Type, ids); 265 uuidGatherer.GatherAssetUuids(assetID, meta.Type, ids);
257 m_log.DebugFormat("[HG ASSET MAPPER]: Preparing to get {0} assets", ids.Count); 266 m_log.DebugFormat("[HG ASSET MAPPER]: Preparing to get {0} assets", ids.Count);
258 bool success = true; 267 bool success = true;
259 foreach (UUID uuid in ids.Keys) 268 foreach (UUID uuid in ids.Keys)
@@ -277,9 +286,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
277 AssetBase asset = m_scene.AssetService.Get(assetID.ToString()); 286 AssetBase asset = m_scene.AssetService.Get(assetID.ToString());
278 if (asset != null) 287 if (asset != null)
279 { 288 {
280 Dictionary<UUID, AssetType> ids = new Dictionary<UUID, AssetType>(); 289 Dictionary<UUID, sbyte> ids = new Dictionary<UUID, sbyte>();
281 HGUuidGatherer uuidGatherer = new HGUuidGatherer(m_scene.AssetService, string.Empty); 290 HGUuidGatherer uuidGatherer = new HGUuidGatherer(m_scene.AssetService, string.Empty);
282 uuidGatherer.GatherAssetUuids(asset.FullID, (AssetType)asset.Type, ids); 291 uuidGatherer.GatherAssetUuids(asset.FullID, asset.Type, ids);
283 bool success = false; 292 bool success = false;
284 foreach (UUID uuid in ids.Keys) 293 foreach (UUID uuid in ids.Keys)
285 { 294 {
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
index b2b628d..ce7ed26 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
@@ -62,6 +62,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
62 private string m_ThisGatekeeper; 62 private string m_ThisGatekeeper;
63 private bool m_RestrictInventoryAccessAbroad; 63 private bool m_RestrictInventoryAccessAbroad;
64 64
65 private bool m_bypassPermissions = true;
66
65// private bool m_Initialized = false; 67// private bool m_Initialized = false;
66 68
67 #region INonSharedRegionModule 69 #region INonSharedRegionModule
@@ -100,6 +102,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
100 } 102 }
101 else 103 else
102 m_log.Warn("[HG INVENTORY ACCESS MODULE]: HGInventoryAccessModule configs not found. ProfileServerURI not set!"); 104 m_log.Warn("[HG INVENTORY ACCESS MODULE]: HGInventoryAccessModule configs not found. ProfileServerURI not set!");
105
106 m_bypassPermissions = !Util.GetConfigVarFromSections<bool>(source, "serverside_object_permissions",
107 new string[] { "Startup", "Permissions" }, true);
108
103 } 109 }
104 } 110 }
105 } 111 }
@@ -114,6 +120,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
114 scene.EventManager.OnNewInventoryItemUploadComplete += UploadInventoryItem; 120 scene.EventManager.OnNewInventoryItemUploadComplete += UploadInventoryItem;
115 scene.EventManager.OnTeleportStart += TeleportStart; 121 scene.EventManager.OnTeleportStart += TeleportStart;
116 scene.EventManager.OnTeleportFail += TeleportFail; 122 scene.EventManager.OnTeleportFail += TeleportFail;
123
124 // We're fgoing to enforce some stricter permissions if Outbound is false
125 scene.Permissions.OnTakeObject += CanTakeObject;
126 scene.Permissions.OnTakeCopyObject += CanTakeObject;
127 scene.Permissions.OnTransferUserInventory += OnTransferUserInventory;
117 } 128 }
118 129
119 #endregion 130 #endregion
@@ -135,7 +146,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
135 if (sp is ScenePresence) 146 if (sp is ScenePresence)
136 { 147 {
137 AgentCircuitData aCircuit = ((ScenePresence)sp).Scene.AuthenticateHandler.GetAgentCircuitData(client.AgentId); 148 AgentCircuitData aCircuit = ((ScenePresence)sp).Scene.AuthenticateHandler.GetAgentCircuitData(client.AgentId);
138 if ((aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0) 149 if (aCircuit != null && (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0)
139 { 150 {
140 if (m_RestrictInventoryAccessAbroad) 151 if (m_RestrictInventoryAccessAbroad)
141 { 152 {
@@ -185,8 +196,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
185 } 196 }
186 } 197 }
187 198
188 public void UploadInventoryItem(UUID avatarID, UUID assetID, string name, int userlevel) 199 public void UploadInventoryItem(UUID avatarID, AssetType type, UUID assetID, string name, int userlevel)
189 { 200 {
201 if (type == AssetType.Link)
202 return;
203
190 string userAssetServer = string.Empty; 204 string userAssetServer = string.Empty;
191 if (IsForeignUser(avatarID, out userAssetServer) && userAssetServer != string.Empty && m_OutboundPermission) 205 if (IsForeignUser(avatarID, out userAssetServer) && userAssetServer != string.Empty && m_OutboundPermission)
192 { 206 {
@@ -221,7 +235,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
221 { 235 {
222 UUID newAssetID = base.CapsUpdateInventoryItemAsset(remoteClient, itemID, data); 236 UUID newAssetID = base.CapsUpdateInventoryItemAsset(remoteClient, itemID, data);
223 237
224 UploadInventoryItem(remoteClient.AgentId, newAssetID, "", 0); 238 UploadInventoryItem(remoteClient.AgentId, AssetType.Unknown, newAssetID, "", 0);
225 239
226 return newAssetID; 240 return newAssetID;
227 } 241 }
@@ -232,7 +246,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
232 protected override void ExportAsset(UUID agentID, UUID assetID) 246 protected override void ExportAsset(UUID agentID, UUID assetID)
233 { 247 {
234 if (!assetID.Equals(UUID.Zero)) 248 if (!assetID.Equals(UUID.Zero))
235 UploadInventoryItem(agentID, assetID, "", 0); 249 UploadInventoryItem(agentID, AssetType.Unknown, assetID, "", 0);
236 else 250 else
237 m_log.Debug("[HGScene]: Scene.Inventory did not create asset"); 251 m_log.Debug("[HGScene]: Scene.Inventory did not create asset");
238 } 252 }
@@ -244,7 +258,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
244 UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, 258 UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
245 bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) 259 bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
246 { 260 {
247 m_log.DebugFormat("[HGScene] RezObject itemID={0} fromTaskID={1}", itemID, fromTaskID); 261 m_log.DebugFormat("[HGScene]: RezObject itemID={0} fromTaskID={1}", itemID, fromTaskID);
248 262
249 //if (fromTaskID.Equals(UUID.Zero)) 263 //if (fromTaskID.Equals(UUID.Zero))
250 //{ 264 //{
@@ -297,7 +311,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
297 if (m_Scene.TryGetScenePresence(userID, out sp)) 311 if (m_Scene.TryGetScenePresence(userID, out sp))
298 { 312 {
299 AgentCircuitData aCircuit = m_Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); 313 AgentCircuitData aCircuit = m_Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
300 if (aCircuit.ServiceURLs.ContainsKey("AssetServerURI")) 314 if (aCircuit != null && aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("AssetServerURI"))
301 { 315 {
302 assetServerURL = aCircuit.ServiceURLs["AssetServerURI"].ToString(); 316 assetServerURL = aCircuit.ServiceURLs["AssetServerURI"].ToString();
303 assetServerURL = assetServerURL.Trim(new char[] { '/' }); 317 assetServerURL = assetServerURL.Trim(new char[] { '/' });
@@ -348,7 +362,15 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
348 InventoryFolderBase root = m_Scene.InventoryService.GetRootFolder(client.AgentId); 362 InventoryFolderBase root = m_Scene.InventoryService.GetRootFolder(client.AgentId);
349 InventoryCollection content = m_Scene.InventoryService.GetFolderContent(client.AgentId, root.ID); 363 InventoryCollection content = m_Scene.InventoryService.GetFolderContent(client.AgentId, root.ID);
350 364
351 inv.SendBulkUpdateInventory(content.Folders.ToArray(), content.Items.ToArray()); 365 List<InventoryFolderBase> keep = new List<InventoryFolderBase>();
366
367 foreach (InventoryFolderBase f in content.Folders)
368 {
369 if (f.Name != "My Suitcase" && f.Name != "Current Outfit")
370 keep.Add(f);
371 }
372
373 inv.SendBulkUpdateInventory(keep.ToArray(), content.Items.ToArray());
352 } 374 }
353 } 375 }
354 } 376 }
@@ -381,7 +403,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
381 403
382 foreach (InventoryFolderBase f in content.Folders) 404 foreach (InventoryFolderBase f in content.Folders)
383 { 405 {
384 if (f.Name != "My Suitcase") 406 if (f.Name != "My Suitcase" && f.Name != "Current Outfit")
385 { 407 {
386 f.Name = f.Name + " (Unavailable)"; 408 f.Name = f.Name + " (Unavailable)";
387 keep.Add(f); 409 keep.Add(f);
@@ -406,5 +428,36 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
406 } 428 }
407 429
408 #endregion 430 #endregion
431
432 #region Permissions
433
434 private bool CanTakeObject(UUID objectID, UUID stealer, Scene scene)
435 {
436 if (m_bypassPermissions) return true;
437
438 if (!m_OutboundPermission && !UserManagementModule.IsLocalGridUser(stealer))
439 {
440 SceneObjectGroup sog = null;
441 if (m_Scene.TryGetSceneObjectGroup(objectID, out sog) && sog.OwnerID == stealer)
442 return true;
443
444 return false;
445 }
446
447 return true;
448 }
449
450 private bool OnTransferUserInventory(UUID itemID, UUID userID, UUID recipientID)
451 {
452 if (m_bypassPermissions) return true;
453
454 if (!m_OutboundPermission && !UserManagementModule.IsLocalGridUser(recipientID))
455 return false;
456
457 return true;
458 }
459
460
461 #endregion
409 } 462 }
410} \ No newline at end of file 463} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index d09ea3e..fadcd5e 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -358,7 +358,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
358 bool asAttachment) 358 bool asAttachment)
359 { 359 {
360 CoalescedSceneObjects coa = new CoalescedSceneObjects(UUID.Zero); 360 CoalescedSceneObjects coa = new CoalescedSceneObjects(UUID.Zero);
361 Dictionary<UUID, Vector3> originalPositions = new Dictionary<UUID, Vector3>(); 361// Dictionary<UUID, Vector3> originalPositions = new Dictionary<UUID, Vector3>();
362 362
363 foreach (SceneObjectGroup objectGroup in objlist) 363 foreach (SceneObjectGroup objectGroup in objlist)
364 { 364 {
@@ -379,7 +379,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
379 objectGroup.AbsolutePosition.Z); 379 objectGroup.AbsolutePosition.Z);
380 380
381 Quaternion inventoryStoredRotation = objectGroup.GroupRotation; 381 Quaternion inventoryStoredRotation = objectGroup.GroupRotation;
382 originalPositions[objectGroup.UUID] = objectGroup.AbsolutePosition; 382 //originalPositions[objectGroup.UUID] = objectGroup.AbsolutePosition;
383 383
384 // Restore attachment data after trip through the sim 384 // Restore attachment data after trip through the sim
385 if (objectGroup.RootPart.AttachPoint > 0) 385 if (objectGroup.RootPart.AttachPoint > 0)
@@ -390,9 +390,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
390 390
391 // Trees could be attached and it's been done, but it makes 391 // Trees could be attached and it's been done, but it makes
392 // no sense. State must be preserved because it's the tree type 392 // no sense. State must be preserved because it's the tree type
393 if (objectGroup.RootPart.Shape.PCode != (byte)PCode.Tree && 393 if (objectGroup.RootPart.Shape.PCode != (byte) PCode.Tree &&
394 objectGroup.RootPart.Shape.PCode != (byte)PCode.NewTree) 394 objectGroup.RootPart.Shape.PCode != (byte) PCode.NewTree)
395 {
395 objectGroup.RootPart.Shape.State = objectGroup.RootPart.AttachPoint; 396 objectGroup.RootPart.Shape.State = objectGroup.RootPart.AttachPoint;
397 if (objectGroup.RootPart.AttachPoint > 0)
398 objectGroup.RootPart.Shape.LastAttachPoint = objectGroup.RootPart.AttachPoint;
399 }
396 400
397 objectGroup.AbsolutePosition = inventoryStoredPosition; 401 objectGroup.AbsolutePosition = inventoryStoredPosition;
398 objectGroup.RootPart.RotationOffset = inventoryStoredRotation; 402 objectGroup.RootPart.RotationOffset = inventoryStoredRotation;
@@ -423,9 +427,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
423 else 427 else
424 itemXml = SceneObjectSerializer.ToOriginalXmlFormat(objlist[0], !asAttachment); 428 itemXml = SceneObjectSerializer.ToOriginalXmlFormat(objlist[0], !asAttachment);
425 429
426 // Restore the position of each group now that it has been stored to inventory. 430// // Restore the position of each group now that it has been stored to inventory.
427 foreach (SceneObjectGroup objectGroup in objlist) 431// foreach (SceneObjectGroup objectGroup in objlist)
428 objectGroup.AbsolutePosition = originalPositions[objectGroup.UUID]; 432// objectGroup.AbsolutePosition = originalPositions[objectGroup.UUID];
429 433
430 InventoryItemBase item = CreateItemForObject(action, remoteClient, objlist[0], folderID); 434 InventoryItemBase item = CreateItemForObject(action, remoteClient, objlist[0], folderID);
431 435
@@ -435,17 +439,28 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
435 439
436 if (item == null) 440 if (item == null)
437 return null; 441 return null;
442
443 item.CreatorId = objlist[0].RootPart.CreatorID.ToString();
444 item.CreatorData = objlist[0].RootPart.CreatorData;
438 445
439 // Can't know creator is the same, so null it in inventory
440 if (objlist.Count > 1) 446 if (objlist.Count > 1)
441 { 447 {
442 item.CreatorId = UUID.Zero.ToString();
443 item.Flags = (uint)InventoryItemFlags.ObjectHasMultipleItems; 448 item.Flags = (uint)InventoryItemFlags.ObjectHasMultipleItems;
449
450 // If the objects have different creators then don't specify a creator at all
451 foreach (SceneObjectGroup objectGroup in objlist)
452 {
453 if ((objectGroup.RootPart.CreatorID.ToString() != item.CreatorId)
454 || (objectGroup.RootPart.CreatorData.ToString() != item.CreatorData))
455 {
456 item.CreatorId = UUID.Zero.ToString();
457 item.CreatorData = string.Empty;
458 break;
459 }
460 }
444 } 461 }
445 else 462 else
446 { 463 {
447 item.CreatorId = objlist[0].RootPart.CreatorID.ToString();
448 item.CreatorData = objlist[0].RootPart.CreatorData;
449 item.SaleType = objlist[0].RootPart.ObjectSaleType; 464 item.SaleType = objlist[0].RootPart.ObjectSaleType;
450 item.SalePrice = objlist[0].RootPart.SalePrice; 465 item.SalePrice = objlist[0].RootPart.SalePrice;
451 } 466 }
@@ -466,13 +481,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
466 } 481 }
467 else 482 else
468 { 483 {
469 AddPermissions(item, objlist[0], objlist, remoteClient);
470
471 item.CreationDate = Util.UnixTimeSinceEpoch(); 484 item.CreationDate = Util.UnixTimeSinceEpoch();
472 item.Description = asset.Description; 485 item.Description = asset.Description;
473 item.Name = asset.Name; 486 item.Name = asset.Name;
474 item.AssetType = asset.Type; 487 item.AssetType = asset.Type;
475 488
489 AddPermissions(item, objlist[0], objlist, remoteClient);
490
476 m_Scene.AddInventoryItem(item); 491 m_Scene.AddInventoryItem(item);
477 492
478 if (remoteClient != null && item.Owner == remoteClient.AgentId) 493 if (remoteClient != null && item.Owner == remoteClient.AgentId)
@@ -527,16 +542,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
527 } 542 }
528 effectivePerms |= (uint)PermissionMask.Move; 543 effectivePerms |= (uint)PermissionMask.Move;
529 544
545 //PermissionsUtil.LogPermissions(item.Name, "Before AddPermissions", item.BasePermissions, item.CurrentPermissions, item.NextPermissions);
546
530 if (remoteClient != null && (remoteClient.AgentId != so.RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions()) 547 if (remoteClient != null && (remoteClient.AgentId != so.RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions())
531 { 548 {
532 uint perms = effectivePerms; 549 uint perms = effectivePerms;
533 uint nextPerms = (perms & 7) << 13; 550 PermissionsUtil.ApplyFoldedPermissions(effectivePerms, ref perms);
534 if ((nextPerms & (uint)PermissionMask.Copy) == 0)
535 perms &= ~(uint)PermissionMask.Copy;
536 if ((nextPerms & (uint)PermissionMask.Transfer) == 0)
537 perms &= ~(uint)PermissionMask.Transfer;
538 if ((nextPerms & (uint)PermissionMask.Modify) == 0)
539 perms &= ~(uint)PermissionMask.Modify;
540 551
541 item.BasePermissions = perms & so.RootPart.NextOwnerMask; 552 item.BasePermissions = perms & so.RootPart.NextOwnerMask;
542 item.CurrentPermissions = item.BasePermissions; 553 item.CurrentPermissions = item.BasePermissions;
@@ -544,10 +555,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
544 item.EveryOnePermissions = so.RootPart.EveryoneMask & so.RootPart.NextOwnerMask; 555 item.EveryOnePermissions = so.RootPart.EveryoneMask & so.RootPart.NextOwnerMask;
545 item.GroupPermissions = so.RootPart.GroupMask & so.RootPart.NextOwnerMask; 556 item.GroupPermissions = so.RootPart.GroupMask & so.RootPart.NextOwnerMask;
546 557
547 // Magic number badness. Maybe this deserves an enum. 558 // apply next owner perms on rez
548 // bit 4 (16) is the "Slam" bit, it means treat as passed 559 item.CurrentPermissions |= SceneObjectGroup.SLAM;
549 // and apply next owner perms on rez
550 item.CurrentPermissions |= 16; // Slam!
551 } 560 }
552 else 561 else
553 { 562 {
@@ -564,8 +573,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
564 (uint)PermissionMask.Move | 573 (uint)PermissionMask.Move |
565 (uint)PermissionMask.Export | 574 (uint)PermissionMask.Export |
566 7); // Preserve folded permissions 575 7); // Preserve folded permissions
567 } 576 }
568 577
578 //PermissionsUtil.LogPermissions(item.Name, "After AddPermissions", item.BasePermissions, item.CurrentPermissions, item.NextPermissions);
579
569 return item; 580 return item;
570 } 581 }
571 582
@@ -707,6 +718,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
707 InventoryFolderBase f = new InventoryFolderBase(so.FromFolderID, userID); 718 InventoryFolderBase f = new InventoryFolderBase(so.FromFolderID, userID);
708 if (f != null) 719 if (f != null)
709 folder = m_Scene.InventoryService.GetFolder(f); 720 folder = m_Scene.InventoryService.GetFolder(f);
721
722 if(folder.Type == 14 || folder.Type == 16)
723 {
724 // folder.Type = 6;
725 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.Object);
726 }
710 } 727 }
711 } 728 }
712 729
@@ -779,83 +796,29 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
779 796
780 SceneObjectGroup group = null; 797 SceneObjectGroup group = null;
781 798
782 string xmlData = Utils.BytesToString(rezAsset.Data); 799 List<SceneObjectGroup> objlist;
783 List<SceneObjectGroup> objlist = new List<SceneObjectGroup>(); 800 List<Vector3> veclist;
784 List<Vector3> veclist = new List<Vector3>(); 801 Vector3 bbox;
802 float offsetHeight;
785 byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0); 803 byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0);
786 Vector3 pos; 804 Vector3 pos;
787 805
788 XmlDocument doc = new XmlDocument(); 806 bool single = m_Scene.GetObjectsToRez(rezAsset.Data, attachment, out objlist, out veclist, out bbox, out offsetHeight);
789 doc.LoadXml(xmlData);
790 XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject");
791 Vector3 rez_pos;
792 if (e == null || attachment) // Single
793 {
794 SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
795 if (!attachment)
796 {
797 g.RootPart.AttachPoint = g.RootPart.Shape.State;
798 g.RootPart.AttachOffset = g.AbsolutePosition;
799 g.RootPart.AttachRotation = g.GroupRotation;
800 if (g.RootPart.Shape.PCode != (byte)PCode.NewTree &&
801 g.RootPart.Shape.PCode != (byte)PCode.Tree)
802 g.RootPart.Shape.State = 0;
803 }
804 807
805 objlist.Add(g); 808 if (single)
806 veclist.Add(new Vector3(0, 0, 0)); 809 {
807
808 float offsetHeight = 0;
809 pos = m_Scene.GetNewRezLocation( 810 pos = m_Scene.GetNewRezLocation(
810 RayStart, RayEnd, RayTargetID, Quaternion.Identity, 811 RayStart, RayEnd, RayTargetID, Quaternion.Identity,
811 BypassRayCast, bRayEndIsIntersection, true, g.GetAxisAlignedBoundingBox(out offsetHeight), false); 812 BypassRayCast, bRayEndIsIntersection, true, bbox, false);
812 pos.Z += offsetHeight; 813 pos.Z += offsetHeight;
813 rez_pos = pos;
814 } 814 }
815 else 815 else
816 { 816 {
817 XmlElement coll = (XmlElement)e;
818 float bx = Convert.ToSingle(coll.GetAttribute("x"));
819 float by = Convert.ToSingle(coll.GetAttribute("y"));
820 float bz = Convert.ToSingle(coll.GetAttribute("z"));
821 Vector3 bbox = new Vector3(bx, by, bz);
822
823 pos = m_Scene.GetNewRezLocation(RayStart, RayEnd, 817 pos = m_Scene.GetNewRezLocation(RayStart, RayEnd,
824 RayTargetID, Quaternion.Identity, 818 RayTargetID, Quaternion.Identity,
825 BypassRayCast, bRayEndIsIntersection, true, 819 BypassRayCast, bRayEndIsIntersection, true,
826 bbox, false); 820 bbox, false);
827
828 rez_pos = pos;
829
830 pos -= bbox / 2; 821 pos -= bbox / 2;
831
832 XmlNodeList groups = e.SelectNodes("SceneObjectGroup");
833 foreach (XmlNode n in groups)
834 {
835 SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(n.OuterXml);
836 g.RootPart.AttachPoint = g.RootPart.Shape.State;
837 g.RootPart.AttachOffset = g.AbsolutePosition;
838 g.RootPart.AttachRotation = g.GroupRotation;
839 if (g.RootPart.Shape.PCode != (byte)PCode.NewTree &&
840 g.RootPart.Shape.PCode != (byte)PCode.Tree)
841 g.RootPart.Shape.State = 0;
842
843 objlist.Add(g);
844 XmlElement el = (XmlElement)n;
845
846 string rawX = el.GetAttribute("offsetx");
847 string rawY = el.GetAttribute("offsety");
848 string rawZ = el.GetAttribute("offsetz");
849//
850// m_log.DebugFormat(
851// "[INVENTORY ACCESS MODULE]: Converting coalesced object {0} offset <{1}, {2}, {3}>",
852// g.Name, rawX, rawY, rawZ);
853
854 float x = Convert.ToSingle(rawX);
855 float y = Convert.ToSingle(rawY);
856 float z = Convert.ToSingle(rawZ);
857 veclist.Add(new Vector3(x, y, z));
858 }
859 } 822 }
860 823
861 int primcount = 0; 824 int primcount = 0;
@@ -863,7 +826,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
863 primcount += g.PrimCount; 826 primcount += g.PrimCount;
864 827
865 if (!m_Scene.Permissions.CanRezObject( 828 if (!m_Scene.Permissions.CanRezObject(
866 primcount, remoteClient.AgentId, rez_pos) 829 primcount, remoteClient.AgentId, pos)
867 && !attachment) 830 && !attachment)
868 { 831 {
869 // The client operates in no fail mode. It will 832 // The client operates in no fail mode. It will
@@ -880,7 +843,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
880 return null; 843 return null;
881 } 844 }
882 845
883 if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, rez_pos, attachment)) 846 if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, pos, veclist, attachment))
884 return null; 847 return null;
885 848
886 for (int i = 0; i < objlist.Count; i++) 849 for (int i = 0; i < objlist.Count; i++)
@@ -900,11 +863,23 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
900 m_log.Debug("[INVENTORY ACCESS MODULE]: Object has UUID.Zero! Position 3"); 863 m_log.Debug("[INVENTORY ACCESS MODULE]: Object has UUID.Zero! Position 3");
901 } 864 }
902 865
903 foreach (SceneObjectPart part in group.Parts) 866 // if this was previously an attachment and is now being rezzed,
867 // save the old attachment info.
868 if (group.IsAttachment == false && group.RootPart.Shape.State != 0)
904 { 869 {
905 // Make the rezzer the owner, as this is not necessarily set correctly in the serialized asset. 870 group.RootPart.AttachedPos = group.AbsolutePosition;
906 part.LastOwnerID = part.OwnerID; 871 group.RootPart.Shape.LastAttachPoint = (byte)group.AttachmentPoint;
907 part.OwnerID = remoteClient.AgentId; 872 }
873
874 if (item == null)
875 {
876 // Change ownership. Normally this is done in DoPreRezWhenFromItem(), but in this case we must do it here.
877 foreach (SceneObjectPart part in group.Parts)
878 {
879 // Make the rezzer the owner, as this is not necessarily set correctly in the serialized asset.
880 part.LastOwnerID = part.OwnerID;
881 part.OwnerID = remoteClient.AgentId;
882 }
908 } 883 }
909 884
910 if (!attachment) 885 if (!attachment)
@@ -979,10 +954,15 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
979 /// <param name="item"></param> 954 /// <param name="item"></param>
980 /// <param name="objlist"></param> 955 /// <param name="objlist"></param>
981 /// <param name="pos"></param> 956 /// <param name="pos"></param>
957 /// <param name="veclist">
958 /// List of vector position adjustments for a coalesced objects. For ordinary objects
959 /// this list will contain just Vector3.Zero. The order of adjustments must match the order of objlist
960 /// </param>
982 /// <param name="isAttachment"></param> 961 /// <param name="isAttachment"></param>
983 /// <returns>true if we can processed with rezzing, false if we need to abort</returns> 962 /// <returns>true if we can processed with rezzing, false if we need to abort</returns>
984 private bool DoPreRezWhenFromItem( 963 private bool DoPreRezWhenFromItem(
985 IClientAPI remoteClient, InventoryItemBase item, List<SceneObjectGroup> objlist, Vector3 pos, bool isAttachment) 964 IClientAPI remoteClient, InventoryItemBase item, List<SceneObjectGroup> objlist,
965 Vector3 pos, List<Vector3> veclist, bool isAttachment)
986 { 966 {
987 UUID fromUserInventoryItemId = UUID.Zero; 967 UUID fromUserInventoryItemId = UUID.Zero;
988 968
@@ -1005,28 +985,29 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
1005 } 985 }
1006 } 986 }
1007 987
1008 int primcount = 0; 988 for (int i = 0; i < objlist.Count; i++)
1009 foreach (SceneObjectGroup g in objlist)
1010 primcount += g.PrimCount;
1011
1012 if (!m_Scene.Permissions.CanRezObject(
1013 primcount, remoteClient.AgentId, pos)
1014 && !isAttachment)
1015 { 989 {
1016 // The client operates in no fail mode. It will 990 SceneObjectGroup g = objlist[i];
1017 // have already removed the item from the folder
1018 // if it's no copy.
1019 // Put it back if it's not an attachment
1020 //
1021 if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!isAttachment))
1022 remoteClient.SendBulkUpdateInventory(item);
1023 991
1024 ILandObject land = m_Scene.LandChannel.GetLandObject(pos.X, pos.Y); 992 if (!m_Scene.Permissions.CanRezObject(
1025 remoteClient.SendAlertMessage(string.Format( 993 g.PrimCount, remoteClient.AgentId, pos + veclist[i])
1026 "Can't rez object '{0}' at <{1:F3}, {2:F3}, {3:F3}> on parcel '{4}' in region {5}.", 994 && !isAttachment)
1027 item.Name, pos.X, pos.Y, pos.Z, land != null ? land.LandData.Name : "Unknown", m_Scene.RegionInfo.RegionName)); 995 {
996 // The client operates in no fail mode. It will
997 // have already removed the item from the folder
998 // if it's no copy.
999 // Put it back if it's not an attachment
1000 //
1001 if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!isAttachment))
1002 remoteClient.SendBulkUpdateInventory(item);
1028 1003
1029 return false; 1004 ILandObject land = m_Scene.LandChannel.GetLandObject(pos.X, pos.Y);
1005 remoteClient.SendAlertMessage(string.Format(
1006 "Can't rez object '{0}' at <{1:F3}, {2:F3}, {3:F3}> on parcel '{4}' in region {5}.",
1007 item.Name, pos.X, pos.Y, pos.Z, land != null ? land.LandData.Name : "Unknown", m_Scene.Name));
1008
1009 return false;
1010 }
1030 } 1011 }
1031 1012
1032 for (int i = 0; i < objlist.Count; i++) 1013 for (int i = 0; i < objlist.Count; i++)
@@ -1107,7 +1088,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
1107 part.GroupMask = item.GroupPermissions; 1088 part.GroupMask = item.GroupPermissions;
1108 } 1089 }
1109 } 1090 }
1110 1091
1111 rootPart.TrimPermissions(); 1092 rootPart.TrimPermissions();
1112 1093
1113 if (isAttachment) 1094 if (isAttachment)
diff --git a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs
index d07cff4..69d7e16 100644
--- a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs
@@ -176,7 +176,7 @@ namespace OpenSim.Region.CoreModules.Framework.Library
176 m_log.InfoFormat("[LIBRARY MODULE]: Loading library archive {0} ({1})...", iarFileName, simpleName); 176 m_log.InfoFormat("[LIBRARY MODULE]: Loading library archive {0} ({1})...", iarFileName, simpleName);
177 simpleName = GetInventoryPathFromName(simpleName); 177 simpleName = GetInventoryPathFromName(simpleName);
178 178
179 InventoryArchiveReadRequest archread = new InventoryArchiveReadRequest(m_MockScene, uinfo, simpleName, iarFileName, false); 179 InventoryArchiveReadRequest archread = new InventoryArchiveReadRequest(m_MockScene.InventoryService, m_MockScene.AssetService, m_MockScene.UserAccountService, uinfo, simpleName, iarFileName, false);
180 try 180 try
181 { 181 {
182 HashSet<InventoryNodeBase> nodes = archread.Execute(); 182 HashSet<InventoryNodeBase> nodes = archread.Execute();
@@ -185,7 +185,7 @@ namespace OpenSim.Region.CoreModules.Framework.Library
185 // didn't find the subfolder with the given name; place it on the top 185 // didn't find the subfolder with the given name; place it on the top
186 m_log.InfoFormat("[LIBRARY MODULE]: Didn't find {0} in library. Placing archive on the top level", simpleName); 186 m_log.InfoFormat("[LIBRARY MODULE]: Didn't find {0} in library. Placing archive on the top level", simpleName);
187 archread.Close(); 187 archread.Close();
188 archread = new InventoryArchiveReadRequest(m_MockScene, uinfo, "/", iarFileName, false); 188 archread = new InventoryArchiveReadRequest(m_MockScene.InventoryService, m_MockScene.AssetService, m_MockScene.UserAccountService, uinfo, "/", iarFileName, false);
189 archread.Execute(); 189 archread.Execute();
190 } 190 }
191 191
diff --git a/OpenSim/Region/CoreModules/Framework/Search/BasicSearchModule.cs b/OpenSim/Region/CoreModules/Framework/Search/BasicSearchModule.cs
new file mode 100644
index 0000000..8838612
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Framework/Search/BasicSearchModule.cs
@@ -0,0 +1,197 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27using System;
28using System.Collections.Generic;
29using System.IO;
30using System.Reflection;
31using System.Threading;
32
33using OpenSim.Framework;
34using OpenSim.Framework.Console;
35using OpenSim.Framework.Monitoring;
36using OpenSim.Region.ClientStack.LindenUDP;
37using OpenSim.Region.Framework;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Services.Interfaces;
41using OpenSim.Services.Connectors.Hypergrid;
42
43using OpenMetaverse;
44using OpenMetaverse.Packets;
45using log4net;
46using Nini.Config;
47using Mono.Addins;
48
49using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags;
50
51namespace OpenSim.Region.CoreModules.Framework.Search
52{
53 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "BasicSearchModule")]
54 public class BasicSearchModule : ISharedRegionModule
55 {
56 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
57
58 protected bool m_Enabled;
59 protected List<Scene> m_Scenes = new List<Scene>();
60
61 private IGroupsModule m_GroupsService = null;
62
63 #region ISharedRegionModule
64
65 public void Initialise(IConfigSource config)
66 {
67 string umanmod = config.Configs["Modules"].GetString("SearchModule", Name);
68 if (umanmod == Name)
69 {
70 m_Enabled = true;
71 m_log.DebugFormat("[BASIC SEARCH MODULE]: {0} is enabled", Name);
72 }
73 }
74
75 public bool IsSharedModule
76 {
77 get { return true; }
78 }
79
80 public virtual string Name
81 {
82 get { return "BasicSearchModule"; }
83 }
84
85 public Type ReplaceableInterface
86 {
87 get { return null; }
88 }
89
90 public void AddRegion(Scene scene)
91 {
92 if (m_Enabled)
93 {
94 m_Scenes.Add(scene);
95
96 scene.EventManager.OnMakeRootAgent += new Action<ScenePresence>(EventManager_OnMakeRootAgent);
97 scene.EventManager.OnMakeChildAgent += new EventManager.OnMakeChildAgentDelegate(EventManager_OnMakeChildAgent);
98 }
99 }
100
101 public void RemoveRegion(Scene scene)
102 {
103 if (m_Enabled)
104 {
105 m_Scenes.Remove(scene);
106
107 scene.EventManager.OnMakeRootAgent -= new Action<ScenePresence>(EventManager_OnMakeRootAgent);
108 scene.EventManager.OnMakeChildAgent -= new EventManager.OnMakeChildAgentDelegate(EventManager_OnMakeChildAgent);
109 }
110 }
111
112 public void RegionLoaded(Scene s)
113 {
114 if (!m_Enabled)
115 return;
116
117 if (m_GroupsService == null)
118 {
119 m_GroupsService = s.RequestModuleInterface<IGroupsModule>();
120
121 // No Groups Service Connector, then group search won't work...
122 if (m_GroupsService == null)
123 m_log.Warn("[BASIC SEARCH MODULE]: Could not get IGroupsModule");
124 }
125 }
126
127 public void PostInitialise()
128 {
129 }
130
131 public void Close()
132 {
133 m_Scenes.Clear();
134 }
135
136 #endregion ISharedRegionModule
137
138
139 #region Event Handlers
140
141 void EventManager_OnMakeRootAgent(ScenePresence sp)
142 {
143 sp.ControllingClient.OnDirFindQuery += OnDirFindQuery;
144 }
145
146 void EventManager_OnMakeChildAgent(ScenePresence sp)
147 {
148 sp.ControllingClient.OnDirFindQuery -= OnDirFindQuery;
149 }
150
151 void OnDirFindQuery(IClientAPI remoteClient, UUID queryID, string queryText, uint queryFlags, int queryStart)
152 {
153 if (((DirFindFlags)queryFlags & DirFindFlags.People) == DirFindFlags.People)
154 {
155 if (string.IsNullOrEmpty(queryText))
156 remoteClient.SendDirPeopleReply(queryID, new DirPeopleReplyData[0]);
157
158 List<UserAccount> accounts = m_Scenes[0].UserAccountService.GetUserAccounts(m_Scenes[0].RegionInfo.ScopeID, queryText);
159 DirPeopleReplyData[] hits = new DirPeopleReplyData[accounts.Count];
160 int i = 0;
161 foreach (UserAccount acc in accounts)
162 {
163 DirPeopleReplyData d = new DirPeopleReplyData();
164 d.agentID = acc.PrincipalID;
165 d.firstName = acc.FirstName;
166 d.lastName = acc.LastName;
167 d.online = false;
168
169 hits[i++] = d;
170 }
171
172 // TODO: This currently ignores pretty much all the query flags including Mature and sort order
173 remoteClient.SendDirPeopleReply(queryID, hits);
174 }
175 else if (((DirFindFlags)queryFlags & DirFindFlags.Groups) == DirFindFlags.Groups)
176 {
177 if (m_GroupsService == null)
178 {
179 m_log.Warn("[BASIC SEARCH MODULE]: Groups service is not available. Unable to search groups.");
180 remoteClient.SendAlertMessage("Groups search is not enabled");
181 return;
182 }
183
184 if (string.IsNullOrEmpty(queryText))
185 remoteClient.SendDirGroupsReply(queryID, new DirGroupsReplyData[0]);
186
187 // TODO: This currently ignores pretty much all the query flags including Mature and sort order
188 remoteClient.SendDirGroupsReply(queryID, m_GroupsService.FindGroups(remoteClient, queryText).ToArray());
189 }
190
191 }
192
193 #endregion Event Handlers
194
195 }
196
197} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs b/OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs
new file mode 100644
index 0000000..a70261e
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs
@@ -0,0 +1,256 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using System.Threading;
32using log4net;
33using Mono.Addins;
34using Nini.Config;
35using OpenMetaverse;
36using OpenSim.Framework;
37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Framework.Monitoring;
39using OpenSim.Region.Framework.Scenes;
40using GridRegion = OpenSim.Services.Interfaces.GridRegion;
41
42namespace OpenSim.Region.CoreModules.Framework
43{
44 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GridServiceThrottleModule")]
45 public class ServiceThrottleModule : ISharedRegionModule, IServiceThrottleModule
46 {
47 private static readonly ILog m_log = LogManager.GetLogger(
48 MethodBase.GetCurrentMethod().DeclaringType);
49
50 private readonly List<Scene> m_scenes = new List<Scene>();
51 private System.Timers.Timer m_timer = new System.Timers.Timer();
52
53 private Queue<Action> m_RequestQueue = new Queue<Action>();
54 private Dictionary<string, List<string>> m_Pending = new Dictionary<string, List<string>>();
55 private int m_Interval;
56
57 #region ISharedRegionModule
58
59 public void Initialise(IConfigSource config)
60 {
61 m_Interval = Util.GetConfigVarFromSections<int>(config, "Interval", new string[] { "ServiceThrottle" }, 5000);
62
63 m_timer = new System.Timers.Timer();
64 m_timer.AutoReset = false;
65 m_timer.Enabled = true;
66 m_timer.Interval = 15000; // 15 secs at first
67 m_timer.Elapsed += ProcessQueue;
68 m_timer.Start();
69
70 //Watchdog.StartThread(
71 // ProcessQueue,
72 // "GridServiceRequestThread",
73 // ThreadPriority.BelowNormal,
74 // true,
75 // false);
76 }
77
78 public void AddRegion(Scene scene)
79 {
80 lock (m_scenes)
81 {
82 m_scenes.Add(scene);
83 scene.RegisterModuleInterface<IServiceThrottleModule>(this);
84 scene.EventManager.OnNewClient += OnNewClient;
85 scene.EventManager.OnMakeRootAgent += OnMakeRootAgent;
86 }
87 }
88
89 public void RegionLoaded(Scene scene)
90 {
91 }
92
93 public void RemoveRegion(Scene scene)
94 {
95 lock (m_scenes)
96 {
97 m_scenes.Remove(scene);
98 scene.EventManager.OnNewClient -= OnNewClient;
99 }
100 }
101
102 public void PostInitialise()
103 {
104 }
105
106 public void Close()
107 {
108 }
109
110 public string Name
111 {
112 get { return "ServiceThrottleModule"; }
113 }
114
115 public Type ReplaceableInterface
116 {
117 get { return null; }
118 }
119
120 #endregion ISharedRegionMOdule
121
122 #region Events
123
124 void OnNewClient(IClientAPI client)
125 {
126 client.OnRegionHandleRequest += OnRegionHandleRequest;
127 }
128
129 void OnMakeRootAgent(ScenePresence obj)
130 {
131 lock (m_timer)
132 {
133 if (!m_timer.Enabled)
134 {
135 m_timer.Interval = m_Interval;
136 m_timer.Enabled = true;
137 m_timer.Start();
138 }
139 }
140 }
141
142 public void OnRegionHandleRequest(IClientAPI client, UUID regionID)
143 {
144 //m_log.DebugFormat("[SERVICE THROTTLE]: RegionHandleRequest {0}", regionID);
145 ulong handle = 0;
146 if (IsLocalRegionHandle(regionID, out handle))
147 {
148 client.SendRegionHandle(regionID, handle);
149 return;
150 }
151
152 Action action = delegate
153 {
154 GridRegion r = m_scenes[0].GridService.GetRegionByUUID(UUID.Zero, regionID);
155
156 if (r != null && r.RegionHandle != 0)
157 client.SendRegionHandle(regionID, r.RegionHandle);
158 };
159
160 Enqueue("region", regionID.ToString(), action);
161 }
162
163 #endregion Events
164
165 #region IServiceThrottleModule
166
167 public void Enqueue(string category, string itemid, Action continuation)
168 {
169 lock (m_RequestQueue)
170 {
171 if (m_Pending.ContainsKey(category))
172 {
173 if (m_Pending[category].Contains(itemid))
174 // Don't enqueue, it's already pending
175 return;
176 }
177 else
178 m_Pending.Add(category, new List<string>());
179
180 m_Pending[category].Add(itemid);
181
182 m_RequestQueue.Enqueue(delegate
183 {
184 lock (m_RequestQueue)
185 m_Pending[category].Remove(itemid);
186
187 continuation();
188 });
189 }
190 }
191
192 #endregion IServiceThrottleModule
193
194 #region Process Continuation Queue
195
196 private void ProcessQueue(object sender, System.Timers.ElapsedEventArgs e)
197 {
198 //m_log.DebugFormat("[YYY]: Process queue with {0} continuations", m_RequestQueue.Count);
199
200 while (m_RequestQueue.Count > 0)
201 {
202 Action continuation = null;
203 lock (m_RequestQueue)
204 continuation = m_RequestQueue.Dequeue();
205
206 if (continuation != null)
207 continuation();
208 }
209
210 if (AreThereRootAgents())
211 {
212 lock (m_timer)
213 {
214 m_timer.Interval = 1000; // 1 sec
215 m_timer.Enabled = true;
216 m_timer.Start();
217 }
218 }
219 else
220 lock (m_timer)
221 m_timer.Enabled = false;
222
223 }
224
225 #endregion Process Continuation Queue
226
227 #region Misc
228
229 private bool IsLocalRegionHandle(UUID regionID, out ulong regionHandle)
230 {
231 regionHandle = 0;
232 foreach (Scene s in m_scenes)
233 if (s.RegionInfo.RegionID == regionID)
234 {
235 regionHandle = s.RegionInfo.RegionHandle;
236 return true;
237 }
238 return false;
239 }
240
241 private bool AreThereRootAgents()
242 {
243 foreach (Scene s in m_scenes)
244 {
245 foreach (ScenePresence sp in s.GetScenePresences())
246 if (!sp.IsChildAgent)
247 return true;
248 }
249
250 return false;
251 }
252
253 #endregion Misc
254 }
255
256}
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs
index 8ce20e9..245c808 100644
--- a/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs
@@ -54,11 +54,11 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
54 54
55 public new void Initialise(IConfigSource config) 55 public new void Initialise(IConfigSource config)
56 { 56 {
57 string umanmod = config.Configs["Modules"].GetString("UserManagementModule", Name); 57 string umanmod = config.Configs["Modules"].GetString("UserManagementModule", null);
58 if (umanmod == Name) 58 if (umanmod == Name)
59 { 59 {
60 m_Enabled = true; 60 m_Enabled = true;
61 RegisterConsoleCmds(); 61 Init();
62 m_log.DebugFormat("[USER MANAGEMENT MODULE]: {0} is enabled", Name); 62 m_log.DebugFormat("[USER MANAGEMENT MODULE]: {0} is enabled", Name);
63 } 63 }
64 } 64 }
@@ -70,7 +70,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
70 70
71 #endregion ISharedRegionModule 71 #endregion ISharedRegionModule
72 72
73 protected override void AddAdditionalUsers(UUID avatarID, string query, List<UserData> users) 73 protected override void AddAdditionalUsers(string query, List<UserData> users)
74 { 74 {
75 if (query.Contains("@")) // First.Last@foo.com, maybe? 75 if (query.Contains("@")) // First.Last@foo.com, maybe?
76 { 76 {
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/Tests/HGUserManagementModuleTests.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/Tests/HGUserManagementModuleTests.cs
new file mode 100644
index 0000000..9d36aa5
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/Tests/HGUserManagementModuleTests.cs
@@ -0,0 +1,76 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using Nini.Config;
30using NUnit.Framework;
31using OpenMetaverse;
32using OpenSim.Framework;
33using OpenSim.Region.CoreModules.Framework.UserManagement;
34using OpenSim.Tests.Common;
35using OpenSim.Tests.Common.Mock;
36
37namespace OpenSim.Region.CoreModules.Framework.UserManagement.Tests
38{
39 [TestFixture]
40 public class HGUserManagementModuleTests : OpenSimTestCase
41 {
42 /// <summary>
43 /// Test that a new HG agent (i.e. one without a user account) has their name cached in the UMM upon creation.
44 /// </summary>
45 [Test]
46 public void TestCachedUserNameForNewAgent()
47 {
48 TestHelpers.InMethod();
49// TestHelpers.EnableLogging();
50
51 HGUserManagementModule hgumm = new HGUserManagementModule();
52 UUID userId = TestHelpers.ParseStem("11");
53 string firstName = "Fred";
54 string lastName = "Astaire";
55 string homeUri = "example.com";
56
57 IConfigSource config = new IniConfigSource();
58 config.AddConfig("Modules");
59 config.Configs["Modules"].Set("UserManagementModule", hgumm.Name);
60
61 SceneHelpers sceneHelpers = new SceneHelpers();
62 TestScene scene = sceneHelpers.SetupScene();
63 SceneHelpers.SetupSceneModules(scene, config, hgumm);
64
65 AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId);
66 acd.firstname = firstName;
67 acd.lastname = lastName;
68 acd.ServiceURLs["HomeURI"] = "http://" + homeUri;
69
70 SceneHelpers.AddScenePresence(scene, acd);
71
72 string name = hgumm.GetUserName(userId);
73 Assert.That(name, Is.EqualTo(string.Format("{0}.{1} @{2}", firstName, lastName, homeUri)));
74 }
75 }
76} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
index 77e8b00..3fb5195 100644
--- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
@@ -28,9 +28,11 @@ using System;
28using System.Collections.Generic; 28using System.Collections.Generic;
29using System.IO; 29using System.IO;
30using System.Reflection; 30using System.Reflection;
31using System.Threading;
31 32
32using OpenSim.Framework; 33using OpenSim.Framework;
33using OpenSim.Framework.Console; 34using OpenSim.Framework.Console;
35using OpenSim.Framework.Monitoring;
34using OpenSim.Region.ClientStack.LindenUDP; 36using OpenSim.Region.ClientStack.LindenUDP;
35using OpenSim.Region.Framework; 37using OpenSim.Region.Framework;
36using OpenSim.Region.Framework.Interfaces; 38using OpenSim.Region.Framework.Interfaces;
@@ -44,25 +46,19 @@ using log4net;
44using Nini.Config; 46using Nini.Config;
45using Mono.Addins; 47using Mono.Addins;
46 48
49using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags;
50
47namespace OpenSim.Region.CoreModules.Framework.UserManagement 51namespace OpenSim.Region.CoreModules.Framework.UserManagement
48{ 52{
49 public class UserData
50 {
51 public UUID Id { get; set; }
52 public string FirstName { get; set; }
53 public string LastName { get; set; }
54 public string HomeURL { get; set; }
55 public Dictionary<string, object> ServerURLs { get; set; }
56 }
57
58 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "UserManagementModule")] 53 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "UserManagementModule")]
59 public class UserManagementModule : ISharedRegionModule, IUserManagement 54 public class UserManagementModule : ISharedRegionModule, IUserManagement, IPeople
60 { 55 {
61 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 56 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
62 57
63 protected bool m_Enabled; 58 protected bool m_Enabled;
64 protected List<Scene> m_Scenes = new List<Scene>(); 59 protected List<Scene> m_Scenes = new List<Scene>();
65 60
61 protected IServiceThrottleModule m_ServiceThrottle;
66 // The cache 62 // The cache
67 protected Dictionary<UUID, UserData> m_UserCache = new Dictionary<UUID, UserData>(); 63 protected Dictionary<UUID, UserData> m_UserCache = new Dictionary<UUID, UserData>();
68 64
@@ -74,7 +70,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
74 if (umanmod == Name) 70 if (umanmod == Name)
75 { 71 {
76 m_Enabled = true; 72 m_Enabled = true;
77 RegisterConsoleCmds(); 73 Init();
78 m_log.DebugFormat("[USER MANAGEMENT MODULE]: {0} is enabled", Name); 74 m_log.DebugFormat("[USER MANAGEMENT MODULE]: {0} is enabled", Name);
79 } 75 }
80 } 76 }
@@ -101,6 +97,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
101 m_Scenes.Add(scene); 97 m_Scenes.Add(scene);
102 98
103 scene.RegisterModuleInterface<IUserManagement>(this); 99 scene.RegisterModuleInterface<IUserManagement>(this);
100 scene.RegisterModuleInterface<IPeople>(this);
104 scene.EventManager.OnNewClient += new EventManager.OnNewClientDelegate(EventManager_OnNewClient); 101 scene.EventManager.OnNewClient += new EventManager.OnNewClientDelegate(EventManager_OnNewClient);
105 scene.EventManager.OnPrimsLoaded += new EventManager.PrimsLoaded(EventManager_OnPrimsLoaded); 102 scene.EventManager.OnPrimsLoaded += new EventManager.PrimsLoaded(EventManager_OnPrimsLoaded);
106 } 103 }
@@ -117,6 +114,8 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
117 114
118 public void RegionLoaded(Scene s) 115 public void RegionLoaded(Scene s)
119 { 116 {
117 if (m_Enabled && m_ServiceThrottle == null)
118 m_ServiceThrottle = s.RequestModuleInterface<IServiceThrottleModule>();
120 } 119 }
121 120
122 public void PostInitialise() 121 public void PostInitialise()
@@ -143,7 +142,6 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
143 s.ForEachSOG(delegate(SceneObjectGroup sog) { CacheCreators(sog); }); 142 s.ForEachSOG(delegate(SceneObjectGroup sog) { CacheCreators(sog); });
144 } 143 }
145 144
146
147 void EventManager_OnNewClient(IClientAPI client) 145 void EventManager_OnNewClient(IClientAPI client)
148 { 146 {
149 client.OnConnectionClosed += new Action<IClientAPI>(HandleConnectionClosed); 147 client.OnConnectionClosed += new Action<IClientAPI>(HandleConnectionClosed);
@@ -157,21 +155,43 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
157 client.OnAvatarPickerRequest -= new AvatarPickerRequest(HandleAvatarPickerRequest); 155 client.OnAvatarPickerRequest -= new AvatarPickerRequest(HandleAvatarPickerRequest);
158 } 156 }
159 157
160 void HandleUUIDNameRequest(UUID uuid, IClientAPI remote_client) 158 void HandleUUIDNameRequest(UUID uuid, IClientAPI client)
161 { 159 {
160// m_log.DebugFormat(
161// "[USER MANAGEMENT MODULE]: Handling request for name binding of UUID {0} from {1}",
162// uuid, remote_client.Name);
163
162 if (m_Scenes[0].LibraryService != null && (m_Scenes[0].LibraryService.LibraryRootFolder.Owner == uuid)) 164 if (m_Scenes[0].LibraryService != null && (m_Scenes[0].LibraryService.LibraryRootFolder.Owner == uuid))
163 { 165 {
164 remote_client.SendNameReply(uuid, "Mr", "OpenSim"); 166 client.SendNameReply(uuid, "Mr", "OpenSim");
165 } 167 }
166 else 168 else
167 { 169 {
168 string[] names = GetUserNames(uuid); 170 string[] names = new string[2];
169 if (names.Length == 2) 171 if (TryGetUserNamesFromCache(uuid, names))
170 { 172 {
171 //m_log.DebugFormat("[XXX] HandleUUIDNameRequest {0} is {1} {2}", uuid, names[0], names[1]); 173 client.SendNameReply(uuid, names[0], names[1]);
172 remote_client.SendNameReply(uuid, names[0], names[1]); 174 return;
173 } 175 }
174 176
177 // Not found in cache, queue continuation
178 m_ServiceThrottle.Enqueue("name", uuid.ToString(), delegate
179 {
180 //m_log.DebugFormat("[YYY]: Name request {0}", uuid);
181
182 // As least upto September 2013, clients permanently cache UUID -> Name bindings. Some clients
183 // appear to clear this when the user asks it to clear the cache, but others may not.
184 //
185 // So to avoid clients
186 // (particularly Hypergrid clients) permanently binding "Unknown User" to a given UUID, we will
187 // instead drop the request entirely.
188 if (TryGetUserNames(uuid, names))
189 client.SendNameReply(uuid, names[0], names[1]);
190// else
191// m_log.DebugFormat(
192// "[USER MANAGEMENT MODULE]: No bound name for {0} found, ignoring request from {1}",
193// uuid, client.Name);
194 });
175 } 195 }
176 } 196 }
177 197
@@ -181,29 +201,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
181 201
182 m_log.DebugFormat("[USER MANAGEMENT MODULE]: HandleAvatarPickerRequest for {0}", query); 202 m_log.DebugFormat("[USER MANAGEMENT MODULE]: HandleAvatarPickerRequest for {0}", query);
183 203
184 // searhc the user accounts service 204 List<UserData> users = GetUserData(query, 500, 1);
185 List<UserAccount> accs = m_Scenes[0].UserAccountService.GetUserAccounts(m_Scenes[0].RegionInfo.ScopeID, query);
186
187 List<UserData> users = new List<UserData>();
188 if (accs != null)
189 {
190 foreach (UserAccount acc in accs)
191 {
192 UserData ud = new UserData();
193 ud.FirstName = acc.FirstName;
194 ud.LastName = acc.LastName;
195 ud.Id = acc.PrincipalID;
196 users.Add(ud);
197 }
198 }
199
200 // search the local cache
201 foreach (UserData data in m_UserCache.Values)
202 if (users.Find(delegate(UserData d) { return d.Id == data.Id; }) == null &&
203 (data.FirstName.StartsWith(query) || data.LastName.StartsWith(query)))
204 users.Add(data);
205
206 AddAdditionalUsers(avatarID, query, users);
207 205
208 AvatarPickerReplyPacket replyPacket = (AvatarPickerReplyPacket)PacketPool.Instance.GetPacket(PacketType.AvatarPickerReply); 206 AvatarPickerReplyPacket replyPacket = (AvatarPickerReplyPacket)PacketPool.Instance.GetPacket(PacketType.AvatarPickerReply);
209 // TODO: don't create new blocks if recycling an old packet 207 // TODO: don't create new blocks if recycling an old packet
@@ -249,12 +247,51 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
249 client.SendAvatarPickerReply(agent_data, data_args); 247 client.SendAvatarPickerReply(agent_data, data_args);
250 } 248 }
251 249
252 protected virtual void AddAdditionalUsers(UUID avatarID, string query, List<UserData> users) 250 protected virtual void AddAdditionalUsers(string query, List<UserData> users)
253 { 251 {
254 } 252 }
255 253
256 #endregion Event Handlers 254 #endregion Event Handlers
257 255
256 #region IPeople
257
258 public List<UserData> GetUserData(string query, int page_size, int page_number)
259 {
260 // search the user accounts service
261 List<UserAccount> accs = m_Scenes[0].UserAccountService.GetUserAccounts(m_Scenes[0].RegionInfo.ScopeID, query);
262
263 List<UserData> users = new List<UserData>();
264 if (accs != null)
265 {
266 foreach (UserAccount acc in accs)
267 {
268 UserData ud = new UserData();
269 ud.FirstName = acc.FirstName;
270 ud.LastName = acc.LastName;
271 ud.Id = acc.PrincipalID;
272 users.Add(ud);
273 }
274 }
275
276 // search the local cache
277 lock (m_UserCache)
278 {
279 foreach (UserData data in m_UserCache.Values)
280 {
281 if (users.Find(delegate(UserData d) { return d.Id == data.Id; }) == null &&
282 (data.FirstName.ToLower().StartsWith(query.ToLower()) || data.LastName.ToLower().StartsWith(query.ToLower())))
283 users.Add(data);
284 }
285 }
286
287 AddAdditionalUsers(query, users);
288
289 return users;
290
291 }
292
293 #endregion IPeople
294
258 private void CacheCreators(SceneObjectGroup sog) 295 private void CacheCreators(SceneObjectGroup sog)
259 { 296 {
260 //m_log.DebugFormat("[USER MANAGEMENT MODULE]: processing {0} {1}; {2}", sog.RootPart.Name, sog.RootPart.CreatorData, sog.RootPart.CreatorIdentification); 297 //m_log.DebugFormat("[USER MANAGEMENT MODULE]: processing {0} {1}; {2}", sog.RootPart.Name, sog.RootPart.CreatorData, sog.RootPart.CreatorIdentification);
@@ -268,26 +305,56 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
268 } 305 }
269 } 306 }
270 307
271 private string[] GetUserNames(UUID uuid) 308 /// <summary>
309 ///
310 /// </summary>
311 /// <param name="uuid"></param>
312 /// <param name="names">Caller please provide a properly instantiated array for names, string[2]</param>
313 /// <returns></returns>
314 private bool TryGetUserNames(UUID uuid, string[] names)
272 { 315 {
273 string[] returnstring = new string[2]; 316 if (names == null)
317 names = new string[2];
318
319 if (TryGetUserNamesFromCache(uuid, names))
320 return true;
321
322 if (TryGetUserNamesFromServices(uuid, names))
323 return true;
324
325 return false;
326 }
274 327
328 private bool TryGetUserNamesFromCache(UUID uuid, string[] names)
329 {
275 lock (m_UserCache) 330 lock (m_UserCache)
276 { 331 {
277 if (m_UserCache.ContainsKey(uuid)) 332 if (m_UserCache.ContainsKey(uuid))
278 { 333 {
279 returnstring[0] = m_UserCache[uuid].FirstName; 334 names[0] = m_UserCache[uuid].FirstName;
280 returnstring[1] = m_UserCache[uuid].LastName; 335 names[1] = m_UserCache[uuid].LastName;
281 return returnstring; 336
337 return true;
282 } 338 }
283 } 339 }
284 340
341 return false;
342 }
343
344 /// <summary>
345 /// Try to get the names bound to the given uuid, from the services.
346 /// </summary>
347 /// <returns>True if the name was found, false if not.</returns>
348 /// <param name='uuid'></param>
349 /// <param name='names'>The array of names if found. If not found, then names[0] = "Unknown" and names[1] = "User"</param>
350 private bool TryGetUserNamesFromServices(UUID uuid, string[] names)
351 {
285 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(UUID.Zero, uuid); 352 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(UUID.Zero, uuid);
286 353
287 if (account != null) 354 if (account != null)
288 { 355 {
289 returnstring[0] = account.FirstName; 356 names[0] = account.FirstName;
290 returnstring[1] = account.LastName; 357 names[1] = account.LastName;
291 358
292 UserData user = new UserData(); 359 UserData user = new UserData();
293 user.FirstName = account.FirstName; 360 user.FirstName = account.FirstName;
@@ -295,14 +362,42 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
295 362
296 lock (m_UserCache) 363 lock (m_UserCache)
297 m_UserCache[uuid] = user; 364 m_UserCache[uuid] = user;
365
366 return true;
298 } 367 }
299 else 368 else
300 { 369 {
301 returnstring[0] = "Unknown"; 370 // Let's try the GridUser service
302 returnstring[1] = "User"; 371 GridUserInfo uInfo = m_Scenes[0].GridUserService.GetGridUserInfo(uuid.ToString());
303 } 372 if (uInfo != null)
373 {
374 string url, first, last, tmp;
375 UUID u;
376 if (Util.ParseUniversalUserIdentifier(uInfo.UserID, out u, out url, out first, out last, out tmp))
377 {
378 AddUser(uuid, first, last, url);
379
380 if (m_UserCache.ContainsKey(uuid))
381 {
382 names[0] = m_UserCache[uuid].FirstName;
383 names[1] = m_UserCache[uuid].LastName;
384
385 return true;
386 }
387 }
388 else
389 m_log.DebugFormat("[USER MANAGEMENT MODULE]: Unable to parse UUI {0}", uInfo.UserID);
390 }
391 else
392 {
393 m_log.DebugFormat("[USER MANAGEMENT MODULE]: No grid user found for {0}", uuid);
394 }
304 395
305 return returnstring; 396 names[0] = "Unknown";
397 names[1] = "UserUMMTGUN9";
398
399 return false;
400 }
306 } 401 }
307 402
308 #region IUserManagement 403 #region IUserManagement
@@ -338,16 +433,11 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
338 433
339 public string GetUserName(UUID uuid) 434 public string GetUserName(UUID uuid)
340 { 435 {
341 string[] names = GetUserNames(uuid); 436 string[] names = new string[2];
342 if (names.Length == 2) 437 TryGetUserNames(uuid, names);
343 {
344 string firstname = names[0];
345 string lastname = names[1];
346 438
347 return firstname + " " + lastname; 439 return names[0] + " " + names[1];
348 440
349 }
350 return "(hippos)";
351 } 441 }
352 442
353 public string GetUserHomeURL(UUID userID) 443 public string GetUserHomeURL(UUID userID)
@@ -376,7 +466,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
376 return userdata.ServerURLs[serverType].ToString(); 466 return userdata.ServerURLs[serverType].ToString();
377 } 467 }
378 468
379 if (userdata.HomeURL != null && userdata.HomeURL != string.Empty) 469 if (!string.IsNullOrEmpty(userdata.HomeURL))
380 { 470 {
381 //m_log.DebugFormat( 471 //m_log.DebugFormat(
382 // "[USER MANAGEMENT MODULE]: Did not find url type {0} so requesting urls from '{1}' for {2}", 472 // "[USER MANAGEMENT MODULE]: Did not find url type {0} so requesting urls from '{1}' for {2}",
@@ -394,14 +484,20 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
394 484
395 public string GetUserUUI(UUID userID) 485 public string GetUserUUI(UUID userID)
396 { 486 {
397 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, userID);
398 if (account != null)
399 return userID.ToString();
400
401 UserData ud; 487 UserData ud;
402 lock (m_UserCache) 488 lock (m_UserCache)
403 m_UserCache.TryGetValue(userID, out ud); 489 m_UserCache.TryGetValue(userID, out ud);
404 490
491 if (ud == null) // It's not in the cache
492 {
493 string[] names = new string[2];
494 // This will pull the data from either UserAccounts or GridUser
495 // and stick it into the cache
496 TryGetUserNamesFromServices(userID, names);
497 lock (m_UserCache)
498 m_UserCache.TryGetValue(userID, out ud);
499 }
500
405 if (ud != null) 501 if (ud != null)
406 { 502 {
407 string homeURL = ud.HomeURL; 503 string homeURL = ud.HomeURL;
@@ -446,77 +542,81 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
446 AddUser(uuid, homeURL + ";" + first + " " + last); 542 AddUser(uuid, homeURL + ";" + first + " " + last);
447 } 543 }
448 544
449 public void AddUser (UUID id, string creatorData) 545 public void AddUser(UUID id, string creatorData)
450 { 546 {
451 //m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, creatorData {1}", id, creatorData); 547 //m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, creatorData {1}", id, creatorData);
452 548
453 UserData oldUser; 549 UserData oldUser;
454 //lock the whole block - prevent concurrent update
455 lock (m_UserCache) 550 lock (m_UserCache)
551 m_UserCache.TryGetValue(id, out oldUser);
552
553 if (oldUser != null)
456 { 554 {
457 m_UserCache.TryGetValue (id, out oldUser); 555 if (string.IsNullOrEmpty(creatorData))
458 if (oldUser != null)
459 { 556 {
460 if (creatorData == null || creatorData == String.Empty) 557 //ignore updates without creator data
461 { 558 return;
462 //ignore updates without creator data
463 return;
464 }
465 //try update unknown users
466 //and creator's home URL's
467 if ((oldUser.FirstName == "Unknown" && !creatorData.Contains ("Unknown")) || (oldUser.HomeURL != null && !creatorData.StartsWith (oldUser.HomeURL)))
468 {
469 m_UserCache.Remove (id);
470// m_log.DebugFormat("[USER MANAGEMENT MODULE]: Re-adding user with id {0}, creatorData [{1}] and old HomeURL {2}", id, creatorData,oldUser.HomeURL);
471 }
472 else
473 {
474 //we have already a valid user within the cache
475 return;
476 }
477 } 559 }
478 560
479 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount (m_Scenes [0].RegionInfo.ScopeID, id); 561 //try update unknown users, but don't update anyone else
480 562 if (oldUser.FirstName == "Unknown" && !creatorData.Contains("Unknown"))
481 if (account != null)
482 { 563 {
483 AddUser (id, account.FirstName, account.LastName); 564 lock (m_UserCache)
565 m_UserCache.Remove(id);
566 m_log.DebugFormat("[USER MANAGEMENT MODULE]: Re-adding user with id {0}, creatorData [{1}] and old HomeURL {2}", id, creatorData, oldUser.HomeURL);
484 } 567 }
485 else 568 else
486 { 569 {
487 UserData user = new UserData (); 570 //we have already a valid user within the cache
488 user.Id = id; 571 return;
572 }
573 }
489 574
490 if (creatorData != null && creatorData != string.Empty) 575 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, id);
491 {
492 //creatorData = <endpoint>;<name>
493 576
494 string[] parts = creatorData.Split (';'); 577 if (account != null)
495 if (parts.Length >= 1) 578 {
579 AddUser(id, account.FirstName, account.LastName);
580 }
581 else
582 {
583 UserData user = new UserData();
584 user.Id = id;
585
586 if (!string.IsNullOrEmpty(creatorData))
587 {
588 //creatorData = <endpoint>;<name>
589
590 string[] parts = creatorData.Split(';');
591 if (parts.Length >= 1)
592 {
593 user.HomeURL = parts[0];
594 try
496 { 595 {
497 user.HomeURL = parts [0]; 596 Uri uri = new Uri(parts[0]);
498 try 597 user.LastName = "@" + uri.Authority;
499 { 598 }
500 Uri uri = new Uri (parts [0]); 599 catch (UriFormatException)
501 user.LastName = "@" + uri.Authority; 600 {
502 } 601 m_log.DebugFormat("[SCENE]: Unable to parse Uri {0}", parts[0]);
503 catch (UriFormatException) 602 user.LastName = "@unknown";
504 {
505 m_log.DebugFormat ("[SCENE]: Unable to parse Uri {0}", parts [0]);
506 user.LastName = "@unknown";
507 }
508 } 603 }
509 if (parts.Length >= 2)
510 user.FirstName = parts [1].Replace (' ', '.');
511 }
512 else
513 {
514 user.FirstName = "Unknown";
515 user.LastName = "User";
516 } 604 }
517 605
518 AddUserInternal (user); 606 if (parts.Length >= 2)
607 user.FirstName = parts[1].Replace(' ', '.');
608 }
609 else
610 {
611 // Temporarily add unknown user entries of this type into the cache so that we can distinguish
612 // this source from other recent (hopefully resolved) bugs that fail to retrieve a user name binding
613 // TODO: Can be removed when GUN* unknown users have definitely dropped significantly or
614 // disappeared.
615 user.FirstName = "Unknown";
616 user.LastName = "UserUMMAU4";
519 } 617 }
618
619 AddUserInternal(user);
520 } 620 }
521 } 621 }
522 622
@@ -541,9 +641,22 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
541 641
542 #endregion IUserManagement 642 #endregion IUserManagement
543 643
644 protected void Init()
645 {
646 AddUser(UUID.Zero, "Unknown", "User");
647 RegisterConsoleCmds();
648 }
649
544 protected void RegisterConsoleCmds() 650 protected void RegisterConsoleCmds()
545 { 651 {
546 MainConsole.Instance.Commands.AddCommand("Users", true, 652 MainConsole.Instance.Commands.AddCommand("Users", true,
653 "show name",
654 "show name <uuid>",
655 "Show the bindings between a single user UUID and a user name",
656 String.Empty,
657 HandleShowUser);
658
659 MainConsole.Instance.Commands.AddCommand("Users", true,
547 "show names", 660 "show names",
548 "show names", 661 "show names",
549 "Show the bindings between user UUIDs and user names", 662 "Show the bindings between user UUIDs and user names",
@@ -551,26 +664,56 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
551 HandleShowUsers); 664 HandleShowUsers);
552 } 665 }
553 666
554 private void HandleShowUsers(string module, string[] cmd) 667 private void HandleShowUser(string module, string[] cmd)
555 { 668 {
669 if (cmd.Length < 3)
670 {
671 MainConsole.Instance.OutputFormat("Usage: show name <uuid>");
672 return;
673 }
674
675 UUID userId;
676 if (!ConsoleUtil.TryParseConsoleUuid(MainConsole.Instance, cmd[2], out userId))
677 return;
678
679 string[] names;
680
681 UserData ud;
682
556 lock (m_UserCache) 683 lock (m_UserCache)
557 { 684 {
558 if (m_UserCache.Count == 0) 685 if (!m_UserCache.TryGetValue(userId, out ud))
559 { 686 {
560 MainConsole.Instance.Output("No users found"); 687 MainConsole.Instance.OutputFormat("No name known for user with id {0}", userId);
561 return; 688 return;
562 } 689 }
563 690 }
564 MainConsole.Instance.Output("UUID User Name"); 691
565 MainConsole.Instance.Output("-----------------------------------------------------------------------------"); 692 ConsoleDisplayTable cdt = new ConsoleDisplayTable();
693 cdt.AddColumn("UUID", 36);
694 cdt.AddColumn("Name", 30);
695 cdt.AddColumn("HomeURL", 40);
696 cdt.AddRow(userId, string.Format("{0} {1}", ud.FirstName, ud.LastName), ud.HomeURL);
697
698 MainConsole.Instance.Output(cdt.ToString());
699 }
700
701 private void HandleShowUsers(string module, string[] cmd)
702 {
703 ConsoleDisplayTable cdt = new ConsoleDisplayTable();
704 cdt.AddColumn("UUID", 36);
705 cdt.AddColumn("Name", 30);
706 cdt.AddColumn("HomeURL", 40);
707
708 lock (m_UserCache)
709 {
566 foreach (KeyValuePair<UUID, UserData> kvp in m_UserCache) 710 foreach (KeyValuePair<UUID, UserData> kvp in m_UserCache)
567 { 711 cdt.AddRow(kvp.Key, string.Format("{0} {1}", kvp.Value.FirstName, kvp.Value.LastName), kvp.Value.HomeURL);
568 MainConsole.Instance.Output(String.Format("{0} {1} {2} ({3})",
569 kvp.Key, kvp.Value.FirstName, kvp.Value.LastName, kvp.Value.HomeURL));
570 }
571
572 return;
573 } 712 }
713
714 MainConsole.Instance.Output(cdt.ToString());
574 } 715 }
716
575 } 717 }
718
576} \ No newline at end of file 719} \ No newline at end of file