aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Framework
diff options
context:
space:
mode:
authoronefang2019-05-19 21:24:15 +1000
committeronefang2019-05-19 21:24:15 +1000
commit5e4d6cab00cb29cd088ab7b62ab13aff103b64cb (patch)
treea9fbc62df9eb2d1d9ba2698d8552eae71eca20d8 /OpenSim/Region/CoreModules/Framework
parentAdd a build script. (diff)
downloadopensim-SC_OLD-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.zip
opensim-SC_OLD-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.tar.gz
opensim-SC_OLD-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.tar.bz2
opensim-SC_OLD-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.tar.xz
Dump OpenSim 0.9.0.1 into it's own branch.
Diffstat (limited to 'OpenSim/Region/CoreModules/Framework')
-rw-r--r--OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs150
-rw-r--r--OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs30
-rw-r--r--OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs24
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs1709
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs44
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs84
-rw-r--r--OpenSim/Region/CoreModules/Framework/InterfaceCommander/Commander.cs20
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs8
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs86
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs557
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/HGAssetMapperTests.cs9
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs64
-rw-r--r--OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs6
-rw-r--r--OpenSim/Region/CoreModules/Framework/Library/LocalInventoryService.cs15
-rw-r--r--OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs12
-rw-r--r--OpenSim/Region/CoreModules/Framework/Search/BasicSearchModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs148
-rw-r--r--OpenSim/Region/CoreModules/Framework/Statistics/Logging/BinaryLoggingModule.cs24
-rw-r--r--OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs14
-rw-r--r--OpenSim/Region/CoreModules/Framework/UserManagement/Tests/HGUserManagementModuleTests.cs2
-rw-r--r--OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs345
21 files changed, 1879 insertions, 1474 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
index 817ef85..c0afe7c 100644
--- a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
@@ -47,23 +47,23 @@ namespace OpenSim.Region.CoreModules.Framework
47{ 47{
48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "CapabilitiesModule")] 48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "CapabilitiesModule")]
49 public class CapabilitiesModule : INonSharedRegionModule, ICapabilitiesModule 49 public class CapabilitiesModule : INonSharedRegionModule, ICapabilitiesModule
50 { 50 {
51 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 51 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52 52
53 private string m_showCapsCommandFormat = " {0,-38} {1,-60}\n"; 53 private string m_showCapsCommandFormat = " {0,-38} {1,-60}\n";
54 54
55 protected Scene m_scene; 55 protected Scene m_scene;
56 56
57 /// <summary> 57 /// <summary>
58 /// Each agent has its own capabilities handler. 58 /// Each agent has its own capabilities handler.
59 /// </summary> 59 /// </summary>
60 protected Dictionary<UUID, Caps> m_capsObjects = new Dictionary<UUID, Caps>(); 60 protected Dictionary<uint, Caps> m_capsObjects = new Dictionary<uint, Caps>();
61 61
62 protected Dictionary<UUID, string> m_capsPaths = new Dictionary<UUID, string>(); 62 protected Dictionary<UUID, string> m_capsPaths = new Dictionary<UUID, string>();
63 63
64 protected Dictionary<UUID, Dictionary<ulong, string>> m_childrenSeeds 64 protected Dictionary<UUID, Dictionary<ulong, string>> m_childrenSeeds
65 = new Dictionary<UUID, Dictionary<ulong, string>>(); 65 = new Dictionary<UUID, Dictionary<ulong, string>>();
66 66
67 public void Initialise(IConfigSource source) 67 public void Initialise(IConfigSource source)
68 { 68 {
69 } 69 }
@@ -101,16 +101,16 @@ namespace OpenSim.Region.CoreModules.Framework
101 { 101 {
102 m_scene.UnregisterModuleInterface<ICapabilitiesModule>(this); 102 m_scene.UnregisterModuleInterface<ICapabilitiesModule>(this);
103 } 103 }
104 104
105 public void PostInitialise() 105 public void PostInitialise()
106 { 106 {
107 } 107 }
108 108
109 public void Close() {} 109 public void Close() {}
110 110
111 public string Name 111 public string Name
112 { 112 {
113 get { return "Capabilities Module"; } 113 get { return "Capabilities Module"; }
114 } 114 }
115 115
116 public Type ReplaceableInterface 116 public Type ReplaceableInterface
@@ -118,23 +118,46 @@ namespace OpenSim.Region.CoreModules.Framework
118 get { return null; } 118 get { return null; }
119 } 119 }
120 120
121 public void CreateCaps(UUID agentId) 121 public void CreateCaps(UUID agentId, uint circuitCode)
122 { 122 {
123 if (m_scene.RegionInfo.EstateSettings.IsBanned(agentId)) 123 int ts = Util.EnvironmentTickCount();
124 return; 124/* this as no business here...
125 * must be done elsewhere ( and is )
126 int flags = m_scene.GetUserFlags(agentId);
127
128 m_log.ErrorFormat("[CreateCaps]: banCheck {0} ", Util.EnvironmentTickCountSubtract(ts));
125 129
130 if (m_scene.RegionInfo.EstateSettings.IsBanned(agentId, flags))
131 return;
132*/
126 Caps caps; 133 Caps caps;
127 String capsObjectPath = GetCapsPath(agentId); 134 String capsObjectPath = GetCapsPath(agentId);
128 135
129 lock (m_capsObjects) 136 lock (m_capsObjects)
130 { 137 {
131 if (m_capsObjects.ContainsKey(agentId)) 138 if (m_capsObjects.ContainsKey(circuitCode))
132 { 139 {
133 Caps oldCaps = m_capsObjects[agentId]; 140 Caps oldCaps = m_capsObjects[circuitCode];
134 141
135 //m_log.WarnFormat( 142
136 // "[CAPS]: Recreating caps for agent {0} in region {1}. Old caps path {2}, new caps path {3}. ", 143 if (capsObjectPath == oldCaps.CapsObjectPath)
137 // agentId, m_scene.RegionInfo.RegionName, oldCaps.CapsObjectPath, capsObjectPath); 144 {
145// m_log.WarnFormat(
146// "[CAPS]: Reusing caps for agent {0} in region {1}. Old caps path {2}, new caps path {3}. ",
147// agentId, m_scene.RegionInfo.RegionName, oldCaps.CapsObjectPath, capsObjectPath);
148 return;
149 }
150 else
151 {
152 // not reusing add extra melanie cleanup
153 // Remove tge handlers. They may conflict with the
154 // new object created below
155 oldCaps.DeregisterHandlers();
156
157 // Better safe ... should not be needed but also
158 // no big deal
159 m_capsObjects.Remove(circuitCode);
160 }
138 } 161 }
139 162
140// m_log.DebugFormat( 163// m_log.DebugFormat(
@@ -145,13 +168,17 @@ namespace OpenSim.Region.CoreModules.Framework
145 (MainServer.Instance == null) ? 0: MainServer.Instance.Port, 168 (MainServer.Instance == null) ? 0: MainServer.Instance.Port,
146 capsObjectPath, agentId, m_scene.RegionInfo.RegionName); 169 capsObjectPath, agentId, m_scene.RegionInfo.RegionName);
147 170
148 m_capsObjects[agentId] = caps; 171 m_log.DebugFormat("[CreateCaps]: new caps agent {0}, circuit {1}, path {2}, time {3} ",agentId,
149 } 172 circuitCode,caps.CapsObjectPath, Util.EnvironmentTickCountSubtract(ts));
150 173
174 m_capsObjects[circuitCode] = caps;
175 }
151 m_scene.EventManager.TriggerOnRegisterCaps(agentId, caps); 176 m_scene.EventManager.TriggerOnRegisterCaps(agentId, caps);
177// m_log.ErrorFormat("[CreateCaps]: end {0} ", Util.EnvironmentTickCountSubtract(ts));
178
152 } 179 }
153 180
154 public void RemoveCaps(UUID agentId) 181 public void RemoveCaps(UUID agentId, uint circuitCode)
155 { 182 {
156 m_log.DebugFormat("[CAPS]: Remove caps for agent {0} in region {1}", agentId, m_scene.RegionInfo.RegionName); 183 m_log.DebugFormat("[CAPS]: Remove caps for agent {0} in region {1}", agentId, m_scene.RegionInfo.RegionName);
157 lock (m_childrenSeeds) 184 lock (m_childrenSeeds)
@@ -164,44 +191,65 @@ namespace OpenSim.Region.CoreModules.Framework
164 191
165 lock (m_capsObjects) 192 lock (m_capsObjects)
166 { 193 {
167 if (m_capsObjects.ContainsKey(agentId)) 194 if (m_capsObjects.ContainsKey(circuitCode))
168 { 195 {
169 m_capsObjects[agentId].DeregisterHandlers(); 196 m_capsObjects[circuitCode].DeregisterHandlers();
170 m_scene.EventManager.TriggerOnDeregisterCaps(agentId, m_capsObjects[agentId]); 197 m_scene.EventManager.TriggerOnDeregisterCaps(agentId, m_capsObjects[circuitCode]);
171 m_capsObjects.Remove(agentId); 198 m_capsObjects.Remove(circuitCode);
172 } 199 }
173 else 200 else
174 { 201 {
202 foreach (KeyValuePair<uint, Caps> kvp in m_capsObjects)
203 {
204 if (kvp.Value.AgentID == agentId)
205 {
206 kvp.Value.DeregisterHandlers();
207 m_scene.EventManager.TriggerOnDeregisterCaps(agentId, kvp.Value);
208 m_capsObjects.Remove(kvp.Key);
209 return;
210 }
211 }
175 m_log.WarnFormat( 212 m_log.WarnFormat(
176 "[CAPS]: Received request to remove CAPS handler for root agent {0} in {1}, but no such CAPS handler found!", 213 "[CAPS]: Received request to remove CAPS handler for root agent {0} in {1}, but no such CAPS handler found!",
177 agentId, m_scene.RegionInfo.RegionName); 214 agentId, m_scene.RegionInfo.RegionName);
178 } 215 }
179 } 216 }
180 } 217 }
181 218
182 public Caps GetCapsForUser(UUID agentId) 219 public Caps GetCapsForUser(uint circuitCode)
183 { 220 {
184 lock (m_capsObjects) 221 lock (m_capsObjects)
185 { 222 {
186 if (m_capsObjects.ContainsKey(agentId)) 223 if (m_capsObjects.ContainsKey(circuitCode))
187 { 224 {
188 return m_capsObjects[agentId]; 225 return m_capsObjects[circuitCode];
189 } 226 }
190 } 227 }
191 228
192 return null; 229 return null;
193 } 230 }
194 231
232 public void ActivateCaps(uint circuitCode)
233 {
234 lock (m_capsObjects)
235 {
236 if (m_capsObjects.ContainsKey(circuitCode))
237 {
238 m_capsObjects[circuitCode].Activate();
239 }
240 }
241 }
242
195 public void SetAgentCapsSeeds(AgentCircuitData agent) 243 public void SetAgentCapsSeeds(AgentCircuitData agent)
196 { 244 {
197 lock (m_capsPaths) 245 lock (m_capsPaths)
198 m_capsPaths[agent.AgentID] = agent.CapsPath; 246 m_capsPaths[agent.AgentID] = agent.CapsPath;
199 247
200 lock (m_childrenSeeds) 248 lock (m_childrenSeeds)
201 m_childrenSeeds[agent.AgentID] 249 m_childrenSeeds[agent.AgentID]
202 = ((agent.ChildrenCapSeeds == null) ? new Dictionary<ulong, string>() : agent.ChildrenCapSeeds); 250 = ((agent.ChildrenCapSeeds == null) ? new Dictionary<ulong, string>() : agent.ChildrenCapSeeds);
203 } 251 }
204 252
205 public string GetCapsPath(UUID agentId) 253 public string GetCapsPath(UUID agentId)
206 { 254 {
207 lock (m_capsPaths) 255 lock (m_capsPaths)
@@ -214,7 +262,7 @@ namespace OpenSim.Region.CoreModules.Framework
214 262
215 return null; 263 return null;
216 } 264 }
217 265
218 public Dictionary<ulong, string> GetChildrenSeeds(UUID agentID) 266 public Dictionary<ulong, string> GetChildrenSeeds(UUID agentID)
219 { 267 {
220 Dictionary<ulong, string> seeds = null; 268 Dictionary<ulong, string> seeds = null;
@@ -289,9 +337,9 @@ namespace OpenSim.Region.CoreModules.Framework
289 337
290 lock (m_capsObjects) 338 lock (m_capsObjects)
291 { 339 {
292 foreach (KeyValuePair<UUID, Caps> kvp in m_capsObjects) 340 foreach (KeyValuePair<uint, Caps> kvp in m_capsObjects)
293 { 341 {
294 capsReport.AppendFormat("** User {0}:\n", kvp.Key); 342 capsReport.AppendFormat("** Circuit {0}:\n", kvp.Key);
295 Caps caps = kvp.Value; 343 Caps caps = kvp.Value;
296 344
297 for (IDictionaryEnumerator kvp2 = caps.CapsHandlers.GetCapsDetails(false, null).GetEnumerator(); kvp2.MoveNext(); ) 345 for (IDictionaryEnumerator kvp2 = caps.CapsHandlers.GetCapsDetails(false, null).GetEnumerator(); kvp2.MoveNext(); )
@@ -339,6 +387,7 @@ namespace OpenSim.Region.CoreModules.Framework
339 387
340 private void BuildDetailedStatsByCapReport(StringBuilder sb, string capName) 388 private void BuildDetailedStatsByCapReport(StringBuilder sb, string capName)
341 { 389 {
390 /*
342 sb.AppendFormat("Capability name {0}\n", capName); 391 sb.AppendFormat("Capability name {0}\n", capName);
343 392
344 ConsoleDisplayTable cdt = new ConsoleDisplayTable(); 393 ConsoleDisplayTable cdt = new ConsoleDisplayTable();
@@ -365,8 +414,8 @@ namespace OpenSim.Region.CoreModules.Framework
365 { 414 {
366 receivedStats[sp.Name] = reqHandler.RequestsReceived; 415 receivedStats[sp.Name] = reqHandler.RequestsReceived;
367 handledStats[sp.Name] = reqHandler.RequestsHandled; 416 handledStats[sp.Name] = reqHandler.RequestsHandled;
368 } 417 }
369 else 418 else
370 { 419 {
371 PollServiceEventArgs pollHandler = null; 420 PollServiceEventArgs pollHandler = null;
372 if (caps.TryGetPollHandler(capName, out pollHandler)) 421 if (caps.TryGetPollHandler(capName, out pollHandler))
@@ -384,10 +433,12 @@ namespace OpenSim.Region.CoreModules.Framework
384 } 433 }
385 434
386 sb.Append(cdt.ToString()); 435 sb.Append(cdt.ToString());
436 */
387 } 437 }
388 438
389 private void BuildSummaryStatsByCapReport(StringBuilder sb) 439 private void BuildSummaryStatsByCapReport(StringBuilder sb)
390 { 440 {
441 /*
391 ConsoleDisplayTable cdt = new ConsoleDisplayTable(); 442 ConsoleDisplayTable cdt = new ConsoleDisplayTable();
392 cdt.AddColumn("Name", 34); 443 cdt.AddColumn("Name", 34);
393 cdt.AddColumn("Req Received", 12); 444 cdt.AddColumn("Req Received", 12);
@@ -403,7 +454,7 @@ namespace OpenSim.Region.CoreModules.Framework
403 Caps caps = m_scene.CapsModule.GetCapsForUser(sp.UUID); 454 Caps caps = m_scene.CapsModule.GetCapsForUser(sp.UUID);
404 455
405 if (caps == null) 456 if (caps == null)
406 return; 457 return;
407 458
408 foreach (IRequestHandler reqHandler in caps.CapsHandlers.GetCapsHandlers().Values) 459 foreach (IRequestHandler reqHandler in caps.CapsHandlers.GetCapsHandlers().Values)
409 { 460 {
@@ -439,15 +490,17 @@ namespace OpenSim.Region.CoreModules.Framework
439 } 490 }
440 } 491 }
441 ); 492 );
442 493
443 foreach (KeyValuePair<string, int> kvp in receivedStats.OrderByDescending(kp => kp.Value)) 494 foreach (KeyValuePair<string, int> kvp in receivedStats.OrderByDescending(kp => kp.Value))
444 cdt.AddRow(kvp.Key, kvp.Value, handledStats[kvp.Key]); 495 cdt.AddRow(kvp.Key, kvp.Value, handledStats[kvp.Key]);
445 496
446 sb.Append(cdt.ToString()); 497 sb.Append(cdt.ToString());
498 */
447 } 499 }
448 500
449 private void HandleShowCapsStatsByUserCommand(string module, string[] cmdParams) 501 private void HandleShowCapsStatsByUserCommand(string module, string[] cmdParams)
450 { 502 {
503 /*
451 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene) 504 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
452 return; 505 return;
453 506
@@ -478,10 +531,12 @@ namespace OpenSim.Region.CoreModules.Framework
478 } 531 }
479 532
480 MainConsole.Instance.Output(sb.ToString()); 533 MainConsole.Instance.Output(sb.ToString());
534 */
481 } 535 }
482 536
483 private void BuildDetailedStatsByUserReport(StringBuilder sb, ScenePresence sp) 537 private void BuildDetailedStatsByUserReport(StringBuilder sb, ScenePresence sp)
484 { 538 {
539 /*
485 sb.AppendFormat("Avatar name {0}, type {1}\n", sp.Name, sp.IsChildAgent ? "child" : "root"); 540 sb.AppendFormat("Avatar name {0}, type {1}\n", sp.Name, sp.IsChildAgent ? "child" : "root");
486 541
487 ConsoleDisplayTable cdt = new ConsoleDisplayTable(); 542 ConsoleDisplayTable cdt = new ConsoleDisplayTable();
@@ -504,13 +559,15 @@ namespace OpenSim.Region.CoreModules.Framework
504 capRows.Add(new CapTableRow(kvp.Key, kvp.Value.RequestsReceived, kvp.Value.RequestsHandled)); 559 capRows.Add(new CapTableRow(kvp.Key, kvp.Value.RequestsReceived, kvp.Value.RequestsHandled));
505 560
506 foreach (CapTableRow ctr in capRows.OrderByDescending(ctr => ctr.RequestsReceived)) 561 foreach (CapTableRow ctr in capRows.OrderByDescending(ctr => ctr.RequestsReceived))
507 cdt.AddRow(ctr.Name, ctr.RequestsReceived, ctr.RequestsHandled); 562 cdt.AddRow(ctr.Name, ctr.RequestsReceived, ctr.RequestsHandled);
508 563
509 sb.Append(cdt.ToString()); 564 sb.Append(cdt.ToString());
565 */
510 } 566 }
511 567
512 private void BuildSummaryStatsByUserReport(StringBuilder sb) 568 private void BuildSummaryStatsByUserReport(StringBuilder sb)
513 { 569 {
570 /*
514 ConsoleDisplayTable cdt = new ConsoleDisplayTable(); 571 ConsoleDisplayTable cdt = new ConsoleDisplayTable();
515 cdt.AddColumn("Name", 32); 572 cdt.AddColumn("Name", 32);
516 cdt.AddColumn("Type", 5); 573 cdt.AddColumn("Type", 5);
@@ -544,12 +601,13 @@ namespace OpenSim.Region.CoreModules.Framework
544 totalRequestsReceived += handler.RequestsReceived; 601 totalRequestsReceived += handler.RequestsReceived;
545 totalRequestsHandled += handler.RequestsHandled; 602 totalRequestsHandled += handler.RequestsHandled;
546 } 603 }
547 604
548 cdt.AddRow(sp.Name, sp.IsChildAgent ? "child" : "root", totalRequestsReceived, totalRequestsHandled); 605 cdt.AddRow(sp.Name, sp.IsChildAgent ? "child" : "root", totalRequestsReceived, totalRequestsHandled);
549 } 606 }
550 ); 607 );
551 608
552 sb.Append(cdt.ToString()); 609 sb.Append(cdt.ToString());
610 */
553 } 611 }
554 612
555 private class CapTableRow 613 private class CapTableRow
@@ -566,4 +624,4 @@ namespace OpenSim.Region.CoreModules.Framework
566 } 624 }
567 } 625 }
568 } 626 }
569} \ No newline at end of file 627}
diff --git a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs
index 0c632b1..d652f43 100644
--- a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs
@@ -53,12 +53,12 @@ namespace OpenSim.Region.CoreModules.Framework.DynamicAttributes.DAExampleModule
53 53
54 protected Scene m_scene; 54 protected Scene m_scene;
55 protected IDialogModule m_dialogMod; 55 protected IDialogModule m_dialogMod;
56 56
57 public string Name { get { return "DAExample Module"; } } 57 public string Name { get { return "DAExample Module"; } }
58 public Type ReplaceableInterface { get { return null; } } 58 public Type ReplaceableInterface { get { return null; } }
59 59
60 public void Initialise(IConfigSource source) {} 60 public void Initialise(IConfigSource source) {}
61 61
62 public void AddRegion(Scene scene) 62 public void AddRegion(Scene scene)
63 { 63 {
64 if (ENABLED) 64 if (ENABLED)
@@ -70,22 +70,22 @@ namespace OpenSim.Region.CoreModules.Framework.DynamicAttributes.DAExampleModule
70 m_log.DebugFormat("[DA EXAMPLE MODULE]: Added region {0}", m_scene.Name); 70 m_log.DebugFormat("[DA EXAMPLE MODULE]: Added region {0}", m_scene.Name);
71 } 71 }
72 } 72 }
73 73
74 public void RemoveRegion(Scene scene) 74 public void RemoveRegion(Scene scene)
75 { 75 {
76 if (ENABLED) 76 if (ENABLED)
77 { 77 {
78 m_scene.EventManager.OnSceneGroupMove -= OnSceneGroupMove; 78 m_scene.EventManager.OnSceneGroupMove -= OnSceneGroupMove;
79 } 79 }
80 } 80 }
81 81
82 public void RegionLoaded(Scene scene) {} 82 public void RegionLoaded(Scene scene) {}
83 83
84 public void Close() 84 public void Close()
85 { 85 {
86 RemoveRegion(m_scene); 86 RemoveRegion(m_scene);
87 } 87 }
88 88
89 protected bool OnSceneGroupMove(UUID groupId, Vector3 delta) 89 protected bool OnSceneGroupMove(UUID groupId, Vector3 delta)
90 { 90 {
91 OSDMap attrs = null; 91 OSDMap attrs = null;
@@ -96,28 +96,28 @@ namespace OpenSim.Region.CoreModules.Framework.DynamicAttributes.DAExampleModule
96 96
97 if (!sop.DynAttrs.TryGetStore(Namespace, StoreName, out attrs)) 97 if (!sop.DynAttrs.TryGetStore(Namespace, StoreName, out attrs))
98 attrs = new OSDMap(); 98 attrs = new OSDMap();
99 99
100 OSDInteger newValue; 100 OSDInteger newValue;
101 101
102 // We have to lock on the entire dynamic attributes map to avoid race conditions with serialization code. 102 // We have to lock on the entire dynamic attributes map to avoid race conditions with serialization code.
103 lock (sop.DynAttrs) 103 lock (sop.DynAttrs)
104 { 104 {
105 if (!attrs.ContainsKey("moves")) 105 if (!attrs.ContainsKey("moves"))
106 newValue = new OSDInteger(1); 106 newValue = new OSDInteger(1);
107 else 107 else
108 newValue = new OSDInteger(attrs["moves"].AsInteger() + 1); 108 newValue = new OSDInteger(attrs["moves"].AsInteger() + 1);
109 109
110 attrs["moves"] = newValue; 110 attrs["moves"] = newValue;
111 111
112 sop.DynAttrs.SetStore(Namespace, StoreName, attrs); 112 sop.DynAttrs.SetStore(Namespace, StoreName, attrs);
113 } 113 }
114 114
115 sop.ParentGroup.HasGroupChanged = true; 115 sop.ParentGroup.HasGroupChanged = true;
116 116
117 string msg = 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); 118 m_log.DebugFormat("[DA EXAMPLE MODULE]: {0}", msg);
119 m_dialogMod.SendGeneralAlert(msg); 119 m_dialogMod.SendGeneralAlert(msg);
120 120
121 return true; 121 return true;
122 } 122 }
123 } 123 }
diff --git a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs
index 166a994..3364cbc 100644
--- a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs
@@ -65,11 +65,11 @@ namespace OpenSim.Region.Framework.DynamicAttributes.DOExampleModule
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 "DO"; } } 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) {}
72 72
73 public void AddRegion(Scene scene) 73 public void AddRegion(Scene scene)
74 { 74 {
75 if (ENABLED) 75 if (ENABLED)
@@ -80,18 +80,18 @@ namespace OpenSim.Region.Framework.DynamicAttributes.DOExampleModule
80 m_dialogMod = m_scene.RequestModuleInterface<IDialogModule>(); 80 m_dialogMod = m_scene.RequestModuleInterface<IDialogModule>();
81 } 81 }
82 } 82 }
83 83
84 public void RemoveRegion(Scene scene) 84 public void RemoveRegion(Scene scene)
85 { 85 {
86 if (ENABLED) 86 if (ENABLED)
87 { 87 {
88 m_scene.EventManager.OnSceneGroupMove -= OnSceneGroupMove; 88 m_scene.EventManager.OnSceneGroupMove -= OnSceneGroupMove;
89 } 89 }
90 } 90 }
91 91
92 public void RegionLoaded(Scene scene) {} 92 public void RegionLoaded(Scene scene) {}
93 93
94 public void Close() 94 public void Close()
95 { 95 {
96 RemoveRegion(m_scene); 96 RemoveRegion(m_scene);
97 } 97 }
@@ -116,7 +116,7 @@ namespace OpenSim.Region.Framework.DynamicAttributes.DOExampleModule
116 116
117 rootPart.DynObjs.Add(DAExampleModule.Namespace, 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)
121 { 121 {
122 SceneObjectGroup so = m_scene.GetSceneObjectGroup(groupId); 122 SceneObjectGroup so = m_scene.GetSceneObjectGroup(groupId);
@@ -129,11 +129,11 @@ namespace OpenSim.Region.Framework.DynamicAttributes.DOExampleModule
129 if (rawObj != null) 129 if (rawObj != null)
130 { 130 {
131 MyObject myObj = (MyObject)rawObj; 131 MyObject myObj = (MyObject)rawObj;
132 132
133 m_dialogMod.SendGeneralAlert(string.Format("{0} {1} moved {2} times", so.Name, so.UUID, ++myObj.Moves)); 133 m_dialogMod.SendGeneralAlert(string.Format("{0} {1} moved {2} times", so.Name, so.UUID, ++myObj.Moves));
134 } 134 }
135 135
136 return true; 136 return true;
137 } 137 }
138 } 138 }
139} \ No newline at end of file 139} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index 1b4b5e6..2334e0b 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -54,9 +54,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
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 private static readonly string LogHeader = "[ENTITY TRANSFER MODULE]";
56 56
57 public const int DefaultMaxTransferDistance = 4095;
57 public const bool WaitForAgentArrivedAtDestinationDefault = true; 58 public const bool WaitForAgentArrivedAtDestinationDefault = true;
58 59
59 /// <summary> 60 /// <summary>
61 /// The maximum distance, in standard region units (256m) that an agent is allowed to transfer.
62 /// </summary>
63 public int MaxTransferDistance { get; set; }
64
65 /// <summary>
60 /// If true then on a teleport, the source region waits for a callback from the destination region. If 66 /// If true then on a teleport, the source region waits for a callback from the destination region. If
61 /// a callback fails to arrive within a set time then the user is pulled back into the source region. 67 /// a callback fails to arrive within a set time then the user is pulled back into the source region.
62 /// </summary> 68 /// </summary>
@@ -66,9 +72,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
66 /// If true then we ask the viewer to disable teleport cancellation and ignore teleport requests. 72 /// If true then we ask the viewer to disable teleport cancellation and ignore teleport requests.
67 /// </summary> 73 /// </summary>
68 /// <remarks> 74 /// <remarks>
69 /// This is useful in situations where teleport is very likely to always succeed and we want to avoid a 75 /// This is useful in situations where teleport is very likely to always succeed and we want to avoid a
70 /// situation where avatars can be come 'stuck' due to a failed teleport cancellation. Unfortunately, the 76 /// situation where avatars can be come 'stuck' due to a failed teleport cancellation. Unfortunately, the
71 /// nature of the teleport protocol makes it extremely difficult (maybe impossible) to make teleport 77 /// nature of the teleport protocol makes it extremely difficult (maybe impossible) to make teleport
72 /// cancellation consistently suceed. 78 /// cancellation consistently suceed.
73 /// </remarks> 79 /// </remarks>
74 public bool DisableInterRegionTeleportCancellation { get; set; } 80 public bool DisableInterRegionTeleportCancellation { get; set; }
@@ -130,7 +136,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
130 { 136 {
131 if (m_idCache.TryGetValue(pRegionHandle, out m_banUntil)) 137 if (m_idCache.TryGetValue(pRegionHandle, out m_banUntil))
132 { 138 {
133 if (DateTime.Now < m_banUntil) 139 if (DateTime.UtcNow < m_banUntil)
134 { 140 {
135 ret = true; 141 ret = true;
136 } 142 }
@@ -141,13 +147,19 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
141 // Add this agent in this region as a banned person 147 // Add this agent in this region as a banned person
142 public void Add(ulong pRegionHandle, UUID pAgentID) 148 public void Add(ulong pRegionHandle, UUID pAgentID)
143 { 149 {
150 this.Add(pRegionHandle, pAgentID, 45, 15);
151 }
152
153 public void Add(ulong pRegionHandle, UUID pAgentID, double newTime, double extendTime)
154 {
144 if (!m_bannedRegions.TryGetValue(pAgentID, out m_idCache)) 155 if (!m_bannedRegions.TryGetValue(pAgentID, out m_idCache))
145 { 156 {
146 m_idCache = new ExpiringCache<ulong, DateTime>(); 157 m_idCache = new ExpiringCache<ulong, DateTime>();
147 m_bannedRegions.Add(pAgentID, m_idCache, TimeSpan.FromSeconds(45)); 158 m_bannedRegions.Add(pAgentID, m_idCache, TimeSpan.FromSeconds(newTime));
148 } 159 }
149 m_idCache.Add(pRegionHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); 160 m_idCache.Add(pRegionHandle, DateTime.UtcNow + TimeSpan.FromSeconds(extendTime), extendTime);
150 } 161 }
162
151 // Remove the agent from the region's banned list 163 // Remove the agent from the region's banned list
152 public void Remove(ulong pRegionHandle, UUID pAgentID) 164 public void Remove(ulong pRegionHandle, UUID pAgentID)
153 { 165 {
@@ -157,10 +169,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
157 } 169 }
158 } 170 }
159 } 171 }
172
160 private BannedRegionCache m_bannedRegionCache = new BannedRegionCache(); 173 private BannedRegionCache m_bannedRegionCache = new BannedRegionCache();
161 174
162 private IEventQueue m_eqModule; 175 private IEventQueue m_eqModule;
163 private IRegionCombinerModule m_regionCombinerModule;
164 176
165 #region ISharedRegionModule 177 #region ISharedRegionModule
166 178
@@ -209,11 +221,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
209 IConfig transferConfig = source.Configs["EntityTransfer"]; 221 IConfig transferConfig = source.Configs["EntityTransfer"];
210 if (transferConfig != null) 222 if (transferConfig != null)
211 { 223 {
212 DisableInterRegionTeleportCancellation 224 DisableInterRegionTeleportCancellation
213 = transferConfig.GetBoolean("DisableInterRegionTeleportCancellation", false); 225 = transferConfig.GetBoolean("DisableInterRegionTeleportCancellation", false);
214 226
215 WaitForAgentArrivedAtDestination 227 WaitForAgentArrivedAtDestination
216 = transferConfig.GetBoolean("wait_for_callback", WaitForAgentArrivedAtDestinationDefault); 228 = transferConfig.GetBoolean("wait_for_callback", WaitForAgentArrivedAtDestinationDefault);
229
230 MaxTransferDistance = transferConfig.GetInt("max_distance", DefaultMaxTransferDistance);
231 }
232 else
233 {
234 MaxTransferDistance = DefaultMaxTransferDistance;
217 } 235 }
218 236
219 m_entityTransferStateMachine = new EntityTransferStateMachine(this); 237 m_entityTransferStateMachine = new EntityTransferStateMachine(this);
@@ -232,7 +250,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
232 250
233 Scene = scene; 251 Scene = scene;
234 252
235 m_interRegionTeleportAttempts = 253 m_interRegionTeleportAttempts =
236 new Stat( 254 new Stat(
237 "InterRegionTeleportAttempts", 255 "InterRegionTeleportAttempts",
238 "Number of inter-region teleports attempted.", 256 "Number of inter-region teleports attempted.",
@@ -245,7 +263,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
245 null, 263 null,
246 StatVerbosity.Debug); 264 StatVerbosity.Debug);
247 265
248 m_interRegionTeleportAborts = 266 m_interRegionTeleportAborts =
249 new Stat( 267 new Stat(
250 "InterRegionTeleportAborts", 268 "InterRegionTeleportAborts",
251 "Number of inter-region teleports aborted due to client actions.", 269 "Number of inter-region teleports aborted due to client actions.",
@@ -257,7 +275,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
257 null, 275 null,
258 StatVerbosity.Debug); 276 StatVerbosity.Debug);
259 277
260 m_interRegionTeleportCancels = 278 m_interRegionTeleportCancels =
261 new Stat( 279 new Stat(
262 "InterRegionTeleportCancels", 280 "InterRegionTeleportCancels",
263 "Number of inter-region teleports cancelled by the client.", 281 "Number of inter-region teleports cancelled by the client.",
@@ -269,7 +287,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
269 null, 287 null,
270 StatVerbosity.Debug); 288 StatVerbosity.Debug);
271 289
272 m_interRegionTeleportFailures = 290 m_interRegionTeleportFailures =
273 new Stat( 291 new Stat(
274 "InterRegionTeleportFailures", 292 "InterRegionTeleportFailures",
275 "Number of inter-region teleports that failed due to server/client/network issues.", 293 "Number of inter-region teleports that failed due to server/client/network issues.",
@@ -303,7 +321,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
303 321
304 public virtual void Close() {} 322 public virtual void Close() {}
305 323
306 public virtual void RemoveRegion(Scene scene) 324 public virtual void RemoveRegion(Scene scene)
307 { 325 {
308 if (m_Enabled) 326 if (m_Enabled)
309 { 327 {
@@ -320,7 +338,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
320 return; 338 return;
321 339
322 m_eqModule = Scene.RequestModuleInterface<IEventQueue>(); 340 m_eqModule = Scene.RequestModuleInterface<IEventQueue>();
323 m_regionCombinerModule = Scene.RequestModuleInterface<IRegionCombinerModule>();
324 } 341 }
325 342
326 #endregion 343 #endregion
@@ -332,7 +349,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
332 if (client.IsLoggingOut && m_entityTransferStateMachine.UpdateInTransit(client.AgentId, AgentTransferState.Aborting)) 349 if (client.IsLoggingOut && m_entityTransferStateMachine.UpdateInTransit(client.AgentId, AgentTransferState.Aborting))
333 { 350 {
334 m_log.DebugFormat( 351 m_log.DebugFormat(
335 "[ENTITY TRANSFER MODULE]: Aborted teleport request from {0} in {1} due to simultaneous logout", 352 "[ENTITY TRANSFER MODULE]: Aborted teleport request from {0} in {1} due to simultaneous logout",
336 client.Name, Scene.Name); 353 client.Name, Scene.Name);
337 } 354 }
338 } 355 }
@@ -354,7 +371,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
354 teleportFlags |= (uint)TeleportFlags.Godlike; 371 teleportFlags |= (uint)TeleportFlags.Godlike;
355 } 372 }
356 373
357 if (!sp.Scene.Permissions.CanTeleport(sp.UUID)) 374 else if (!sp.Scene.Permissions.CanTeleport(sp.UUID))
358 return; 375 return;
359 376
360 string destinationRegionName = "(not found)"; 377 string destinationRegionName = "(not found)";
@@ -374,17 +391,27 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
374 391
375 try 392 try
376 { 393 {
377 // Reset animations; the viewer does that in teleports.
378 sp.Animator.ResetAnimations();
379 394
380 if (regionHandle == sp.Scene.RegionInfo.RegionHandle) 395 if (regionHandle == sp.Scene.RegionInfo.RegionHandle)
381 { 396 {
397 if(!sp.AllowMovement)
398 {
399 sp.ControllingClient.SendTeleportFailed("You are frozen");
400 m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
401 return;
402 }
403
404 // Reset animations; the viewer does that in teleports.
405 sp.Animator.ResetAnimations();
382 destinationRegionName = sp.Scene.RegionInfo.RegionName; 406 destinationRegionName = sp.Scene.RegionInfo.RegionName;
383 407
384 TeleportAgentWithinRegion(sp, position, lookAt, teleportFlags); 408 TeleportAgentWithinRegion(sp, position, lookAt, teleportFlags);
385 } 409 }
386 else // Another region possibly in another simulator 410 else // Another region possibly in another simulator
387 { 411 {
412 // Reset animations; the viewer does that in teleports.
413 sp.Animator.ResetAnimations();
414
388 GridRegion finalDestination = null; 415 GridRegion finalDestination = null;
389 try 416 try
390 { 417 {
@@ -400,12 +427,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
400 } 427 }
401 catch (Exception e) 428 catch (Exception e)
402 { 429 {
430
403 m_log.ErrorFormat( 431 m_log.ErrorFormat(
404 "[ENTITY TRANSFER MODULE]: Exception on teleport of {0} from {1}@{2} to {3}@{4}: {5}{6}", 432 "[ENTITY TRANSFER MODULE]: Exception on teleport of {0} from {1}@{2} to {3}@{4}: {5}{6}",
405 sp.Name, sp.AbsolutePosition, sp.Scene.RegionInfo.RegionName, position, destinationRegionName, 433 sp.Name, sp.AbsolutePosition, sp.Scene.RegionInfo.RegionName, position, destinationRegionName,
406 e.Message, e.StackTrace); 434 e.Message, e.StackTrace);
407 435 if(sp != null && sp.ControllingClient != null && !sp.IsDeleted)
408 sp.ControllingClient.SendTeleportFailed("Internal error"); 436 sp.ControllingClient.SendTeleportFailed("Internal error");
409 } 437 }
410 finally 438 finally
411 { 439 {
@@ -438,17 +466,25 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
438 position = emergencyPos; 466 position = emergencyPos;
439 } 467 }
440 468
469 // Check Default Location (Also See ScenePresence.CompleteMovement)
470 if (position.X == 128f && position.Y == 128f && position.Z == 22.5f)
471 position = sp.Scene.RegionInfo.DefaultLandingPoint;
472
441 // TODO: Get proper AVG Height 473 // TODO: Get proper AVG Height
442 float localAVHeight = 1.56f; 474 float localHalfAVHeight = 0.8f;
475 if (sp.Appearance != null)
476 localHalfAVHeight = sp.Appearance.AvatarHeight / 2;
477
443 float posZLimit = 22; 478 float posZLimit = 22;
444 479
445 // TODO: Check other Scene HeightField 480 // TODO: Check other Scene HeightField
446 posZLimit = (float)sp.Scene.Heightmap[(int)position.X, (int)position.Y]; 481 posZLimit = (float)sp.Scene.Heightmap[(int)position.X, (int)position.Y];
447 482
448 float newPosZ = posZLimit + localAVHeight; 483 posZLimit += localHalfAVHeight + 0.1f;
449 if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) 484
485 if ((position.Z < posZLimit) && !(Single.IsInfinity(posZLimit) || Single.IsNaN(posZLimit)))
450 { 486 {
451 position.Z = newPosZ; 487 position.Z = posZLimit;
452 } 488 }
453 489
454 if (sp.Flying) 490 if (sp.Flying)
@@ -457,9 +493,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
457 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); 493 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring);
458 494
459 sp.ControllingClient.SendTeleportStart(teleportFlags); 495 sp.ControllingClient.SendTeleportStart(teleportFlags);
496 lookAt.Z = 0f;
497
498 if(Math.Abs(lookAt.X) < 0.01f && Math.Abs(lookAt.Y) < 0.01f)
499 {
500 lookAt.X = 1.0f;
501 lookAt.Y = 0;
502 }
460 503
461 sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); 504 sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags);
462 sp.TeleportFlags = (Constants.TeleportFlags)teleportFlags; 505 sp.TeleportFlags = (Constants.TeleportFlags)teleportFlags;
506 sp.RotateToLookAt(lookAt);
463 sp.Velocity = Vector3.Zero; 507 sp.Velocity = Vector3.Zero;
464 sp.Teleport(position); 508 sp.Teleport(position);
465 509
@@ -494,15 +538,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
494 { 538 {
495 string homeURI = Scene.GetAgentHomeURI(sp.ControllingClient.AgentId); 539 string homeURI = Scene.GetAgentHomeURI(sp.ControllingClient.AgentId);
496 540
497 string message; 541 string reason = String.Empty;
498 finalDestination = GetFinalDestination(reg, sp.ControllingClient.AgentId, homeURI, out message); 542 finalDestination = GetFinalDestination(reg, sp.ControllingClient.AgentId, homeURI, out reason);
499 543
500 if (finalDestination == null) 544 if (finalDestination == null)
501 { 545 {
502 m_log.WarnFormat( "{0} Final destination is having problems. Unable to teleport {1} {2}: {3}", 546 m_log.WarnFormat( "{0} Final destination is having problems. Unable to teleport {1} {2}: {3}",
503 LogHeader, sp.Name, sp.UUID, message); 547 LogHeader, sp.Name, sp.UUID, reason);
504 548
505 sp.ControllingClient.SendTeleportFailed(message); 549 sp.ControllingClient.SendTeleportFailed(reason);
506 return; 550 return;
507 } 551 }
508 552
@@ -515,17 +559,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
515 return; 559 return;
516 } 560 }
517 561
518 // Validate assorted conditions
519 string reason = string.Empty;
520 if (!ValidateGenericConditions(sp, reg, finalDestination, teleportFlags, out reason)) 562 if (!ValidateGenericConditions(sp, reg, finalDestination, teleportFlags, out reason))
521 { 563 {
522 sp.ControllingClient.SendTeleportFailed(reason); 564 sp.ControllingClient.SendTeleportFailed(reason);
523 return; 565 return;
524 } 566 }
525 567
526 if (message != null)
527 sp.ControllingClient.SendAgentAlertMessage(message, true);
528
529 // 568 //
530 // This is it 569 // This is it
531 // 570 //
@@ -547,9 +586,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
547 Util.RegionHandleToRegionLoc(regionHandle, out regX, out regY); 586 Util.RegionHandleToRegionLoc(regionHandle, out regX, out regY);
548 587
549 MapBlockData block = new MapBlockData(); 588 MapBlockData block = new MapBlockData();
550 block.X = (ushort)regX; 589 block.X = (ushort)(regX);
551 block.Y = (ushort)regY; 590 block.Y = (ushort)(regY);
552 block.Access = (byte)SimAccess.Down; 591 block.Access = (byte)SimAccess.Down; // == not there
553 592
554 List<MapBlockData> blocks = new List<MapBlockData>(); 593 List<MapBlockData> blocks = new List<MapBlockData>();
555 blocks.Add(block); 594 blocks.Add(block);
@@ -565,12 +604,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
565 uint x = 0, y = 0; 604 uint x = 0, y = 0;
566 Util.RegionHandleToWorldLoc(regionHandle, out x, out y); 605 Util.RegionHandleToWorldLoc(regionHandle, out x, out y);
567 606
607 GridRegion reg;
608
609 // handle legacy HG. linked regions are mapped into y = 0 and have no size information
610 // so we can only search by base handle
611 if( y == 0)
612 {
613 reg = gridService.GetRegionByPosition(scope, (int)x, (int)y);
614 return reg;
615 }
616
568 // Compute the world location we're teleporting to 617 // Compute the world location we're teleporting to
569 double worldX = (double)x + position.X; 618 double worldX = (double)x + position.X;
570 double worldY = (double)y + position.Y; 619 double worldY = (double)y + position.Y;
571 620
572 // Find the region that contains the position 621 // Find the region that contains the position
573 GridRegion reg = GetRegionContainingWorldLocation(gridService, scope, worldX, worldY); 622 reg = GetRegionContainingWorldLocation(gridService, scope, worldX, worldY);
574 623
575 if (reg != null) 624 if (reg != null)
576 { 625 {
@@ -589,6 +638,28 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
589 return true; 638 return true;
590 } 639 }
591 640
641 /// <summary>
642 /// Determines whether this instance is within the max transfer distance.
643 /// </summary>
644 /// <param name="sourceRegion"></param>
645 /// <param name="destRegion"></param>
646 /// <returns>
647 /// <c>true</c> if this instance is within max transfer distance; otherwise, <c>false</c>.
648 /// </returns>
649 private bool IsWithinMaxTeleportDistance(RegionInfo sourceRegion, GridRegion destRegion)
650 {
651 if(MaxTransferDistance == 0)
652 return true;
653
654// m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Source co-ords are x={0} y={1}", curRegionX, curRegionY);
655//
656// m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Final dest is x={0} y={1} {2}@{3}",
657// destRegionX, destRegionY, finalDestination.RegionID, finalDestination.ServerURI);
658
659 // Insanely, RegionLoc on RegionInfo is the 256m map co-ord whilst GridRegion.RegionLoc is the raw meters position.
660 return Math.Abs(sourceRegion.RegionLocX - destRegion.RegionCoordX) <= MaxTransferDistance
661 && Math.Abs(sourceRegion.RegionLocY - destRegion.RegionCoordY) <= MaxTransferDistance;
662 }
592 663
593 /// <summary> 664 /// <summary>
594 /// Wraps DoTeleportInternal() and manages the transfer state. 665 /// Wraps DoTeleportInternal() and manages the transfer state.
@@ -607,7 +678,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
607 sp.ControllingClient.SendTeleportFailed("Agent is already in transit."); 678 sp.ControllingClient.SendTeleportFailed("Agent is already in transit.");
608 return; 679 return;
609 } 680 }
610 681
611 try 682 try
612 { 683 {
613 DoTeleportInternal(sp, reg, finalDestination, position, lookAt, teleportFlags); 684 DoTeleportInternal(sp, reg, finalDestination, position, lookAt, teleportFlags);
@@ -650,10 +721,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
650 721
651 RegionInfo sourceRegion = sp.Scene.RegionInfo; 722 RegionInfo sourceRegion = sp.Scene.RegionInfo;
652 723
724 if (!IsWithinMaxTeleportDistance(sourceRegion, finalDestination))
725 {
726 sp.ControllingClient.SendTeleportFailed(
727 string.Format(
728 "Can't teleport to {0} ({1},{2}) from {3} ({4},{5}), destination is more than {6} regions way",
729 finalDestination.RegionName, finalDestination.RegionCoordX, finalDestination.RegionCoordY,
730 sourceRegion.RegionName, sourceRegion.RegionLocX, sourceRegion.RegionLocY,
731 MaxTransferDistance));
653 732
654 uint newRegionX, newRegionY, oldRegionX, oldRegionY; 733 return;
655 Util.RegionHandleToRegionLoc(reg.RegionHandle, out newRegionX, out newRegionY); 734 }
656 Util.RegionHandleToRegionLoc(sp.Scene.RegionInfo.RegionHandle, out oldRegionX, out oldRegionY);
657 735
658 ulong destinationHandle = finalDestination.RegionHandle; 736 ulong destinationHandle = finalDestination.RegionHandle;
659 737
@@ -663,8 +741,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
663 IPEndPoint endPoint = finalDestination.ExternalEndPoint; 741 IPEndPoint endPoint = finalDestination.ExternalEndPoint;
664 if (endPoint == null || endPoint.Address == null) 742 if (endPoint == null || endPoint.Address == null)
665 { 743 {
666 sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); 744 sp.ControllingClient.SendTeleportFailed("Could not resolve destination Address");
667
668 return; 745 return;
669 } 746 }
670 747
@@ -694,7 +771,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
694 m_interRegionTeleportAttempts.Value++; 771 m_interRegionTeleportAttempts.Value++;
695 772
696 m_log.DebugFormat( 773 m_log.DebugFormat(
697 "[ENTITY TRANSFER MODULE]: {0} transfer protocol version to {1} is {2} / {3}", 774 "[ENTITY TRANSFER MODULE]: {0} transfer protocol version to {1} is {2} / {3}",
698 sp.Scene.Name, finalDestination.RegionName, ctx.OutboundVersion, ctx.InboundVersion); 775 sp.Scene.Name, finalDestination.RegionName, ctx.OutboundVersion, ctx.InboundVersion);
699 776
700 // Fixing a bug where teleporting while sitting results in the avatar ending up removed from 777 // Fixing a bug where teleporting while sitting results in the avatar ending up removed from
@@ -704,27 +781,25 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
704 else if (sp.Flying) 781 else if (sp.Flying)
705 teleportFlags |= (uint)TeleportFlags.IsFlying; 782 teleportFlags |= (uint)TeleportFlags.IsFlying;
706 783
784 sp.IsInLocalTransit = finalDestination.RegionLocY != 0; // HG
785 sp.IsInTransit = true;
786
787
707 if (DisableInterRegionTeleportCancellation) 788 if (DisableInterRegionTeleportCancellation)
708 teleportFlags |= (uint)TeleportFlags.DisableCancel; 789 teleportFlags |= (uint)TeleportFlags.DisableCancel;
709 790
710 // At least on LL 3.3.4, this is not strictly necessary - a teleport will succeed without sending this to 791 // At least on LL 3.3.4, this is not strictly necessary - a teleport will succeed without sending this to
711 // the viewer. However, it might mean that the viewer does not see the black teleport screen (untested). 792 // the viewer. However, it might mean that the viewer does not see the black teleport screen (untested).
712 sp.ControllingClient.SendTeleportStart(teleportFlags); 793 sp.ControllingClient.SendTeleportStart(teleportFlags);
713 794
714 // the avatar.Close below will clear the child region list. We need this below for (possibly)
715 // closing the child agents, so save it here (we need a copy as it is Clear()-ed).
716 //List<ulong> childRegions = avatar.KnownRegionHandles;
717 // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport
718 // failure at this point (unlike a border crossing failure). So perhaps this can never fail
719 // once we reach here...
720 //avatar.Scene.RemoveCapsHandler(avatar.UUID);
721
722 AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); 795 AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
723 AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo(); 796 AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo();
724 agentCircuit.startpos = position; 797 agentCircuit.startpos = position;
725 agentCircuit.child = true; 798 agentCircuit.child = true;
799
726 agentCircuit.Appearance = new AvatarAppearance(); 800 agentCircuit.Appearance = new AvatarAppearance();
727 agentCircuit.Appearance.PackLegacyWearables = true; 801 agentCircuit.Appearance.AvatarHeight = sp.Appearance.AvatarHeight;
802
728 if (currentAgentCircuit != null) 803 if (currentAgentCircuit != null)
729 { 804 {
730 agentCircuit.ServiceURLs = currentAgentCircuit.ServiceURLs; 805 agentCircuit.ServiceURLs = currentAgentCircuit.ServiceURLs;
@@ -735,36 +810,64 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
735 agentCircuit.Id0 = currentAgentCircuit.Id0; 810 agentCircuit.Id0 = currentAgentCircuit.Id0;
736 } 811 }
737 812
738 // if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) 813 uint newRegionX, newRegionY, oldRegionX, oldRegionY;
739 float dist = (float)Math.Max(sp.Scene.DefaultDrawDistance, 814 Util.RegionHandleToRegionLoc(destinationHandle, out newRegionX, out newRegionY);
740 (float)Math.Max(sp.Scene.RegionInfo.RegionSizeX, sp.Scene.RegionInfo.RegionSizeY)); 815 Util.RegionHandleToRegionLoc(sourceRegion.RegionHandle, out oldRegionX, out oldRegionY);
741 if (NeedsNewAgent(dist, oldRegionX, newRegionX, oldRegionY, newRegionY)) 816 int oldSizeX = (int)sourceRegion.RegionSizeX;
817 int oldSizeY = (int)sourceRegion.RegionSizeY;
818 int newSizeX = finalDestination.RegionSizeX;
819 int newSizeY = finalDestination.RegionSizeY;
820
821 bool OutSideViewRange = NeedsNewAgent(sp.RegionViewDistance, oldRegionX, newRegionX, oldRegionY, newRegionY,
822 oldSizeX, oldSizeY, newSizeX, newSizeY);
823
824 if (OutSideViewRange)
742 { 825 {
743 // brand new agent, let's create a new caps seed 826 m_log.DebugFormat(
827 "[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} size {3},{4} needs new child agent for agent {5} from {6}",
828 finalDestination.RegionName, newRegionX, newRegionY,newSizeX, newSizeY, sp.Name, Scene.Name);
829
830 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent...");
744 agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); 831 agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath();
745 } 832 }
833 else
834 {
835 agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle);
836 if (agentCircuit.CapsPath == null)
837 agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath();
838 }
746 839
747 // We're going to fallback to V1 if the destination gives us anything smaller than 0.2 840 // We're going to fallback to V1 if the destination gives us anything smaller than 0.2
748 if (ctx.OutboundVersion >= 0.2f) 841 if (ctx.OutboundVersion >= 0.2f)
749 TransferAgent_V2(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, oldRegionX, newRegionX, oldRegionY, newRegionY, ctx, out reason); 842 TransferAgent_V2(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, OutSideViewRange , ctx, out reason);
750 else 843 else
751 TransferAgent_V1(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, oldRegionX, newRegionX, oldRegionY, newRegionY, ctx, out reason); 844 TransferAgent_V1(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, OutSideViewRange, ctx, out reason);
752 } 845 }
753 846
754 private void TransferAgent_V1(ScenePresence sp, AgentCircuitData agentCircuit, GridRegion reg, GridRegion finalDestination, 847 private void TransferAgent_V1(ScenePresence sp, AgentCircuitData agentCircuit, GridRegion reg, GridRegion finalDestination,
755 IPEndPoint endPoint, uint teleportFlags, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, EntityTransferContext ctx, out string reason) 848 IPEndPoint endPoint, uint teleportFlags, bool OutSideViewRange, EntityTransferContext ctx, out string reason)
756 { 849 {
757 ulong destinationHandle = finalDestination.RegionHandle; 850 ulong destinationHandle = finalDestination.RegionHandle;
758 AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); 851 AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
759 852
760 m_log.DebugFormat( 853 m_log.DebugFormat(
761 "[ENTITY TRANSFER MODULE]: Using TP V1 for {0} going from {1} to {2}", 854 "[ENTITY TRANSFER MODULE]: Using TP V1 for {0} going from {1} to {2}",
762 sp.Name, Scene.Name, finalDestination.RegionName); 855 sp.Name, Scene.Name, finalDestination.RegionName);
763 856
764 // Let's create an agent there if one doesn't exist yet. 857 string capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
858 List<ulong> childRegionsToClose = sp.GetChildAgentsToClose(destinationHandle, finalDestination.RegionSizeX, finalDestination.RegionSizeY);
859 if(agentCircuit.ChildrenCapSeeds != null)
860 {
861 foreach(ulong handler in childRegionsToClose)
862 {
863 agentCircuit.ChildrenCapSeeds.Remove(handler);
864 }
865 }
866
867 // Let's create an agent there if one doesn't exist yet.
765 // NOTE: logout will always be false for a non-HG teleport. 868 // NOTE: logout will always be false for a non-HG teleport.
766 bool logout = false; 869 bool logout = false;
767 if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout)) 870 if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, ctx, out reason, out logout))
768 { 871 {
769 m_interRegionTeleportFailures.Value++; 872 m_interRegionTeleportFailures.Value++;
770 873
@@ -773,7 +876,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
773 sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason); 876 sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason);
774 877
775 sp.ControllingClient.SendTeleportFailed(reason); 878 sp.ControllingClient.SendTeleportFailed(reason);
776 879 sp.IsInTransit = false;
777 return; 880 return;
778 } 881 }
779 882
@@ -784,7 +887,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
784 m_log.DebugFormat( 887 m_log.DebugFormat(
785 "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after CreateAgent on client request", 888 "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after CreateAgent on client request",
786 sp.Name, finalDestination.RegionName, sp.Scene.Name); 889 sp.Name, finalDestination.RegionName, sp.Scene.Name);
787 890 sp.IsInTransit = false;
788 return; 891 return;
789 } 892 }
790 else if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting) 893 else if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
@@ -794,7 +897,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
794 m_log.DebugFormat( 897 m_log.DebugFormat(
795 "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after CreateAgent due to previous client close.", 898 "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after CreateAgent due to previous client close.",
796 sp.Name, finalDestination.RegionName, sp.Scene.Name); 899 sp.Name, finalDestination.RegionName, sp.Scene.Name);
797 900 sp.IsInTransit = false;
798 return; 901 return;
799 } 902 }
800 903
@@ -802,28 +905,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
802 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); 905 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring);
803 906
804 // OK, it got this agent. Let's close some child agents 907 // OK, it got this agent. Let's close some child agents
805 sp.CloseChildAgents(newRegionX, newRegionY);
806 908
807 IClientIPEndpoint ipepClient; 909 if (OutSideViewRange)
808 string capsPath = String.Empty;
809 float dist = (float)Math.Max(sp.Scene.DefaultDrawDistance,
810 (float)Math.Max(sp.Scene.RegionInfo.RegionSizeX, sp.Scene.RegionInfo.RegionSizeY));
811 if (NeedsNewAgent(dist, oldRegionX, newRegionX, oldRegionY, newRegionY))
812 { 910 {
813 m_log.DebugFormat(
814 "[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} needs new child agent for incoming agent {3} from {4}",
815 finalDestination.RegionName, newRegionX, newRegionY, sp.Name, Scene.Name);
816
817 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent...");
818 #region IP Translation for NAT
819 // Uses ipepClient above
820 if (sp.ClientView.TryGet(out ipepClient))
821 {
822 endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address);
823 }
824 #endregion
825 capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
826
827 if (m_eqModule != null) 911 if (m_eqModule != null)
828 { 912 {
829 // The EnableSimulator message makes the client establish a connection with the destination 913 // The EnableSimulator message makes the client establish a connection with the destination
@@ -853,22 +937,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
853 sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint); 937 sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint);
854 } 938 }
855 } 939 }
856 else
857 {
858 agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle);
859 capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
860 }
861 940
862 // Let's send a full update of the agent. This is a synchronous call. 941 // Let's send a full update of the agent. This is a synchronous call.
863 AgentData agent = new AgentData(); 942 AgentData agent = new AgentData();
864 sp.CopyTo(agent); 943 sp.CopyTo(agent,false);
865 if (ctx.OutboundVersion < 0.5f) 944
866 agent.Appearance.PackLegacyWearables = true; 945 if ((teleportFlags & (uint)TeleportFlags.IsFlying) != 0)
946 agent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY;
947
867 agent.Position = agentCircuit.startpos; 948 agent.Position = agentCircuit.startpos;
868 SetCallbackURL(agent, sp.Scene.RegionInfo); 949 SetCallbackURL(agent, sp.Scene.RegionInfo);
869 950
870 951 // We will check for an abort before UpdateAgent since UpdateAgent will require an active viewer to
871 // We will check for an abort before UpdateAgent since UpdateAgent will require an active viewer to
872 // establish th econnection to the destination which makes it return true. 952 // establish th econnection to the destination which makes it return true.
873 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting) 953 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
874 { 954 {
@@ -877,15 +957,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
877 m_log.DebugFormat( 957 m_log.DebugFormat(
878 "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} before UpdateAgent", 958 "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} before UpdateAgent",
879 sp.Name, finalDestination.RegionName, sp.Scene.Name); 959 sp.Name, finalDestination.RegionName, sp.Scene.Name);
880 960 sp.IsInTransit = false;
881 return; 961 return;
882 } 962 }
883 963
884 // A common teleport failure occurs when we can send CreateAgent to the 964 // A common teleport failure occurs when we can send CreateAgent to the
885 // destination region but the viewer cannot establish the connection (e.g. due to network issues between 965 // destination region but the viewer cannot establish the connection (e.g. due to network issues between
886 // the viewer and the destination). In this case, UpdateAgent timesout after 10 seconds, although then 966 // the viewer and the destination). In this case, UpdateAgent timesout after 10 seconds, although then
887 // there's a further 10 second wait whilst we attempt to tell the destination to delete the agent in Fail(). 967 // there's a further 10 second wait whilst we attempt to tell the destination to delete the agent in Fail().
888 if (!UpdateAgent(reg, finalDestination, agent, sp)) 968 if (!UpdateAgent(reg, finalDestination, agent, sp, ctx))
889 { 969 {
890 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting) 970 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
891 { 971 {
@@ -894,7 +974,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
894 m_log.DebugFormat( 974 m_log.DebugFormat(
895 "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after UpdateAgent due to previous client close.", 975 "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after UpdateAgent due to previous client close.",
896 sp.Name, finalDestination.RegionName, sp.Scene.Name); 976 sp.Name, finalDestination.RegionName, sp.Scene.Name);
897 977 sp.IsInTransit = false;
898 return; 978 return;
899 } 979 }
900 980
@@ -903,6 +983,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
903 sp.Name, finalDestination.RegionName, sp.Scene.Name); 983 sp.Name, finalDestination.RegionName, sp.Scene.Name);
904 984
905 Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Connection between viewer and destination region could not be established."); 985 Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Connection between viewer and destination region could not be established.");
986 sp.IsInTransit = false;
906 return; 987 return;
907 } 988 }
908 989
@@ -915,7 +996,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
915 sp.Name, finalDestination.RegionName, sp.Scene.Name); 996 sp.Name, finalDestination.RegionName, sp.Scene.Name);
916 997
917 CleanupFailedInterRegionTeleport(sp, currentAgentCircuit.SessionID.ToString(), finalDestination); 998 CleanupFailedInterRegionTeleport(sp, currentAgentCircuit.SessionID.ToString(), finalDestination);
918 999 sp.IsInTransit = false;
919 return; 1000 return;
920 } 1001 }
921 1002
@@ -924,7 +1005,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
924 capsPath, sp.Scene.RegionInfo.RegionName, sp.Name); 1005 capsPath, sp.Scene.RegionInfo.RegionName, sp.Name);
925 1006
926 // We need to set this here to avoid an unlikely race condition when teleporting to a neighbour simulator, 1007 // We need to set this here to avoid an unlikely race condition when teleporting to a neighbour simulator,
927 // where that neighbour simulator could otherwise request a child agent create on the source which then 1008 // where that neighbour simulator could otherwise request a child agent create on the source which then
928 // closes our existing agent which is still signalled as root. 1009 // closes our existing agent which is still signalled as root.
929 sp.IsChildAgent = true; 1010 sp.IsChildAgent = true;
930 1011
@@ -952,7 +1033,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
952 m_log.DebugFormat( 1033 m_log.DebugFormat(
953 "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after WaitForAgentArrivedAtDestination due to previous client close.", 1034 "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after WaitForAgentArrivedAtDestination due to previous client close.",
954 sp.Name, finalDestination.RegionName, sp.Scene.Name); 1035 sp.Name, finalDestination.RegionName, sp.Scene.Name);
955 1036 sp.IsInTransit = false;
956 return; 1037 return;
957 } 1038 }
958 1039
@@ -961,12 +1042,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
961 sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); 1042 sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName);
962 1043
963 Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Destination region did not signal teleport completion."); 1044 Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Destination region did not signal teleport completion.");
964 1045 sp.IsInTransit = false;
965 return; 1046 return;
966 } 1047 }
967 1048
968 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp);
969
970/* 1049/*
971 // TODO: This may be 0.6. Check if still needed 1050 // TODO: This may be 0.6. Check if still needed
972 // For backwards compatibility 1051 // For backwards compatibility
@@ -978,18 +1057,26 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
978 } 1057 }
979*/ 1058*/
980 1059
981 // May need to logout or other cleanup 1060 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp);
1061
1062 if(logout)
1063 sp.closeAllChildAgents();
1064 else
1065 sp.CloseChildAgents(childRegionsToClose);
1066
1067 // call HG hook
982 AgentHasMovedAway(sp, logout); 1068 AgentHasMovedAway(sp, logout);
983 1069
984 // Well, this is it. The agent is over there. 1070 sp.HasMovedAway(!(OutSideViewRange || logout));
985 KillEntity(sp.Scene, sp.LocalId);
986 1071
987 // Now let's make it officially a child agent 1072// ulong sourceRegionHandle = sp.RegionHandle;
988 sp.MakeChildAgent(); 1073
1074 // Now let's make it officially a child agent
1075 sp.MakeChildAgent(destinationHandle);
989 1076
990 // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone 1077 // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone
991 1078
992 if (NeedsClosing(sp.Scene.DefaultDrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) 1079 if (NeedsClosing(reg, OutSideViewRange))
993 { 1080 {
994 if (!sp.Scene.IncomingPreCloseClient(sp)) 1081 if (!sp.Scene.IncomingPreCloseClient(sp))
995 return; 1082 return;
@@ -1001,26 +1088,32 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1001 // This sleep can be increased if necessary. However, whilst it's active, 1088 // This sleep can be increased if necessary. However, whilst it's active,
1002 // an agent cannot teleport back to this region if it has teleported away. 1089 // an agent cannot teleport back to this region if it has teleported away.
1003 Thread.Sleep(2000); 1090 Thread.Sleep(2000);
1004
1005 sp.Scene.CloseAgent(sp.UUID, false); 1091 sp.Scene.CloseAgent(sp.UUID, false);
1006 } 1092 }
1007 else 1093 sp.IsInTransit = false;
1008 {
1009 // now we have a child agent in this region.
1010 sp.Reset();
1011 }
1012 } 1094 }
1013 1095
1014 private void TransferAgent_V2(ScenePresence sp, AgentCircuitData agentCircuit, GridRegion reg, GridRegion finalDestination, 1096 private void TransferAgent_V2(ScenePresence sp, AgentCircuitData agentCircuit, GridRegion reg, GridRegion finalDestination,
1015 IPEndPoint endPoint, uint teleportFlags, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, EntityTransferContext ctx, out string reason) 1097 IPEndPoint endPoint, uint teleportFlags, bool OutSideViewRange, EntityTransferContext ctx, out string reason)
1016 { 1098 {
1017 ulong destinationHandle = finalDestination.RegionHandle; 1099 ulong destinationHandle = finalDestination.RegionHandle;
1018 AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
1019 1100
1020 // Let's create an agent there if one doesn't exist yet. 1101 List<ulong> childRegionsToClose = sp.GetChildAgentsToClose(destinationHandle, finalDestination.RegionSizeX, finalDestination.RegionSizeY);
1102
1103 if(agentCircuit.ChildrenCapSeeds != null)
1104 {
1105 foreach(ulong handler in childRegionsToClose)
1106 {
1107 agentCircuit.ChildrenCapSeeds.Remove(handler);
1108 }
1109 }
1110
1111 string capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);;
1112
1113 // Let's create an agent there if one doesn't exist yet.
1021 // NOTE: logout will always be false for a non-HG teleport. 1114 // NOTE: logout will always be false for a non-HG teleport.
1022 bool logout = false; 1115 bool logout = false;
1023 if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout)) 1116 if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, ctx, out reason, out logout))
1024 { 1117 {
1025 m_interRegionTeleportFailures.Value++; 1118 m_interRegionTeleportFailures.Value++;
1026 1119
@@ -1029,7 +1122,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1029 sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason); 1122 sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason);
1030 1123
1031 sp.ControllingClient.SendTeleportFailed(reason); 1124 sp.ControllingClient.SendTeleportFailed(reason);
1032 1125 sp.IsInTransit = false;
1033 return; 1126 return;
1034 } 1127 }
1035 1128
@@ -1041,6 +1134,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1041 "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after CreateAgent on client request", 1134 "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after CreateAgent on client request",
1042 sp.Name, finalDestination.RegionName, sp.Scene.Name); 1135 sp.Name, finalDestination.RegionName, sp.Scene.Name);
1043 1136
1137 sp.IsInTransit = false;
1044 return; 1138 return;
1045 } 1139 }
1046 else if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting) 1140 else if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
@@ -1051,40 +1145,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1051 "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after CreateAgent due to previous client close.", 1145 "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after CreateAgent due to previous client close.",
1052 sp.Name, finalDestination.RegionName, sp.Scene.Name); 1146 sp.Name, finalDestination.RegionName, sp.Scene.Name);
1053 1147
1148 sp.IsInTransit = false;
1054 return; 1149 return;
1055 } 1150 }
1056 1151
1057 // Past this point we have to attempt clean up if the teleport fails, so update transfer state. 1152 // Past this point we have to attempt clean up if the teleport fails, so update transfer state.
1058 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); 1153 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring);
1059 1154
1060 IClientIPEndpoint ipepClient;
1061 string capsPath = String.Empty;
1062 float dist = (float)Math.Max(sp.Scene.DefaultDrawDistance,
1063 (float)Math.Max(sp.Scene.RegionInfo.RegionSizeX, sp.Scene.RegionInfo.RegionSizeY));
1064 if (NeedsNewAgent(dist, oldRegionX, newRegionX, oldRegionY, newRegionY))
1065 {
1066 m_log.DebugFormat(
1067 "[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} needs new child agent for agent {3} from {4}",
1068 finalDestination.RegionName, newRegionX, newRegionY, sp.Name, Scene.Name);
1069
1070 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent...");
1071 #region IP Translation for NAT
1072 // Uses ipepClient above
1073 if (sp.ClientView.TryGet(out ipepClient))
1074 {
1075 endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address);
1076 }
1077 #endregion
1078 capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
1079 }
1080 else
1081 {
1082 agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle);
1083 capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
1084 }
1085
1086 // We need to set this here to avoid an unlikely race condition when teleporting to a neighbour simulator, 1155 // We need to set this here to avoid an unlikely race condition when teleporting to a neighbour simulator,
1087 // where that neighbour simulator could otherwise request a child agent create on the source which then 1156 // where that neighbour simulator could otherwise request a child agent create on the source which then
1088 // closes our existing agent which is still signalled as root. 1157 // closes our existing agent which is still signalled as root.
1089 //sp.IsChildAgent = true; 1158 //sp.IsChildAgent = true;
1090 1159
@@ -1100,13 +1169,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1100 "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} from {1} to {2}", 1169 "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} from {1} to {2}",
1101 capsPath, sp.Scene.RegionInfo.RegionName, sp.Name); 1170 capsPath, sp.Scene.RegionInfo.RegionName, sp.Name);
1102 1171
1103 // Let's send a full update of the agent. 1172 // Let's send a full update of the agent.
1104 AgentData agent = new AgentData(); 1173 AgentData agent = new AgentData();
1105 sp.CopyTo(agent); 1174 sp.CopyTo(agent,false);
1106 if (ctx.OutboundVersion < 0.5f)
1107 agent.Appearance.PackLegacyWearables = true;
1108 agent.Position = agentCircuit.startpos; 1175 agent.Position = agentCircuit.startpos;
1176
1177 if ((teleportFlags & (uint)TeleportFlags.IsFlying) != 0)
1178 agent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY;
1179
1109 agent.SenderWantsToWaitForRoot = true; 1180 agent.SenderWantsToWaitForRoot = true;
1181
1110 //SetCallbackURL(agent, sp.Scene.RegionInfo); 1182 //SetCallbackURL(agent, sp.Scene.RegionInfo);
1111 1183
1112 // Reset the do not close flag. This must be done before the destination opens child connections (here 1184 // Reset the do not close flag. This must be done before the destination opens child connections (here
@@ -1118,7 +1190,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1118 // Send the Update. If this returns true, we know the client has contacted the destination 1190 // Send the Update. If this returns true, we know the client has contacted the destination
1119 // via CompleteMovementIntoRegion, so we can let go. 1191 // via CompleteMovementIntoRegion, so we can let go.
1120 // If it returns false, something went wrong, and we need to abort. 1192 // If it returns false, something went wrong, and we need to abort.
1121 if (!UpdateAgent(reg, finalDestination, agent, sp)) 1193 if (!UpdateAgent(reg, finalDestination, agent, sp, ctx))
1122 { 1194 {
1123 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting) 1195 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
1124 { 1196 {
@@ -1127,7 +1199,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1127 m_log.DebugFormat( 1199 m_log.DebugFormat(
1128 "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after UpdateAgent due to previous client close.", 1200 "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after UpdateAgent due to previous client close.",
1129 sp.Name, finalDestination.RegionName, sp.Scene.Name); 1201 sp.Name, finalDestination.RegionName, sp.Scene.Name);
1130 1202 sp.IsInTransit = false;
1131 return; 1203 return;
1132 } 1204 }
1133 1205
@@ -1135,31 +1207,31 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1135 "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1}. Keeping avatar in {2}", 1207 "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1}. Keeping avatar in {2}",
1136 sp.Name, finalDestination.RegionName, sp.Scene.Name); 1208 sp.Name, finalDestination.RegionName, sp.Scene.Name);
1137 1209
1138 Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Connection between viewer and destination region could not be established."); 1210 Fail(sp, finalDestination, logout, agentCircuit.SessionID.ToString(), "Connection between viewer and destination region could not be established.");
1211 sp.IsInTransit = false;
1139 return; 1212 return;
1140 } 1213 }
1141 1214
1142 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); 1215 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp);
1143 1216
1144 // Need to signal neighbours whether child agents may need closing irrespective of whether this 1217 if(logout)
1145 // one needed closing. We also need to close child agents as quickly as possible to avoid complicated 1218 sp.closeAllChildAgents();
1146 // race conditions with rapid agent releporting (e.g. from A1 to a non-neighbour B, back 1219 else
1147 // to a neighbour A2 then off to a non-neighbour C). Closing child agents any later requires complex 1220 sp.CloseChildAgents(childRegionsToClose);
1148 // distributed checks to avoid problems in rapid reteleporting scenarios and where child agents are
1149 // abandoned without proper close by viewer but then re-used by an incoming connection.
1150 sp.CloseChildAgents(newRegionX, newRegionY);
1151 1221
1152 // May need to logout or other cleanup 1222 sp.HasMovedAway(!(OutSideViewRange || logout));
1223
1224 //HG hook
1153 AgentHasMovedAway(sp, logout); 1225 AgentHasMovedAway(sp, logout);
1154 1226
1155 // Well, this is it. The agent is over there. 1227// ulong sourceRegionHandle = sp.RegionHandle;
1156 KillEntity(sp.Scene, sp.LocalId);
1157 1228
1158 // Now let's make it officially a child agent 1229 // Now let's make it officially a child agent
1159 sp.MakeChildAgent(); 1230 sp.MakeChildAgent(destinationHandle);
1160 1231
1161 // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone 1232 // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone
1162 if (NeedsClosing(sp.Scene.DefaultDrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) 1233 // go by HG hook
1234 if (NeedsClosing(reg, OutSideViewRange))
1163 { 1235 {
1164 if (!sp.Scene.IncomingPreCloseClient(sp)) 1236 if (!sp.Scene.IncomingPreCloseClient(sp))
1165 return; 1237 return;
@@ -1170,21 +1242,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1170 // BEFORE THEY SETTLE IN THE NEW REGION. 1242 // BEFORE THEY SETTLE IN THE NEW REGION.
1171 // DECREASING THE WAIT TIME HERE WILL EITHER RESULT IN A VIEWER CRASH OR 1243 // DECREASING THE WAIT TIME HERE WILL EITHER RESULT IN A VIEWER CRASH OR
1172 // IN THE AVIE BEING PLACED IN INFINITY FOR A COUPLE OF SECONDS. 1244 // IN THE AVIE BEING PLACED IN INFINITY FOR A COUPLE OF SECONDS.
1245
1173 Thread.Sleep(15000); 1246 Thread.Sleep(15000);
1174 1247
1175 // OK, it got this agent. Let's close everything 1248 // OK, it got this agent. Let's close everything
1176 // If we shouldn't close the agent due to some other region renewing the connection 1249 // If we shouldn't close the agent due to some other region renewing the connection
1177 // then this will be handled in IncomingCloseAgent under lock conditions 1250 // then this will be handled in IncomingCloseAgent under lock conditions
1178 m_log.DebugFormat( 1251 m_log.DebugFormat(
1179 "[ENTITY TRANSFER MODULE]: Closing agent {0} in {1} after teleport", sp.Name, Scene.Name); 1252 "[ENTITY TRANSFER MODULE]: Closing agent {0} in {1} after teleport", sp.Name, Scene.Name);
1180 1253
1181 sp.Scene.CloseAgent(sp.UUID, false); 1254 sp.Scene.CloseAgent(sp.UUID, false);
1182 } 1255 }
1183 else 1256 sp.IsInTransit = false;
1184 {
1185 // now we have a child agent in this region.
1186 sp.Reset();
1187 }
1188 } 1257 }
1189 1258
1190 /// <summary> 1259 /// <summary>
@@ -1232,13 +1301,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1232 sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout); 1301 sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout);
1233 } 1302 }
1234 1303
1235 protected virtual bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout) 1304 protected virtual bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, EntityTransferContext ctx, out string reason, out bool logout)
1236 { 1305 {
1237 GridRegion source = new GridRegion(Scene.RegionInfo); 1306 GridRegion source = new GridRegion(Scene.RegionInfo);
1238 source.RawServerURI = m_GatekeeperURI; 1307 source.RawServerURI = m_GatekeeperURI;
1239 1308
1240 logout = false; 1309 logout = false;
1241 bool success = Scene.SimulationService.CreateAgent(source, finalDestination, agentCircuit, teleportFlags, out reason); 1310 bool success = Scene.SimulationService.CreateAgent(source, finalDestination, agentCircuit, teleportFlags, ctx, out reason);
1242 1311
1243 if (success) 1312 if (success)
1244 sp.Scene.EventManager.TriggerTeleportStart(sp.ControllingClient, reg, finalDestination, teleportFlags, logout); 1313 sp.Scene.EventManager.TriggerTeleportStart(sp.ControllingClient, reg, finalDestination, teleportFlags, logout);
@@ -1246,9 +1315,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1246 return success; 1315 return success;
1247 } 1316 }
1248 1317
1249 protected virtual bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agent, ScenePresence sp) 1318 protected virtual bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agent, ScenePresence sp, EntityTransferContext ctx)
1250 { 1319 {
1251 return Scene.SimulationService.UpdateAgent(finalDestination, agent); 1320 return Scene.SimulationService.UpdateAgent(finalDestination, agent, ctx);
1252 } 1321 }
1253 1322
1254 protected virtual void SetCallbackURL(AgentData agent, RegionInfo region) 1323 protected virtual void SetCallbackURL(AgentData agent, RegionInfo region)
@@ -1265,10 +1334,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1265 /// </summary> 1334 /// </summary>
1266 /// <param name='sp'></param> 1335 /// <param name='sp'></param>
1267 /// <param name='logout'></param> 1336 /// <param name='logout'></param>
1337 ///
1338 /// now just a HG hook
1268 protected virtual void AgentHasMovedAway(ScenePresence sp, bool logout) 1339 protected virtual void AgentHasMovedAway(ScenePresence sp, bool logout)
1269 { 1340 {
1270 if (sp.Scene.AttachmentsModule != null) 1341// if (sp.Scene.AttachmentsModule != null)
1271 sp.Scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, true); 1342// sp.Scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, logout);
1272 } 1343 }
1273 1344
1274 protected void KillEntity(Scene scene, uint localID) 1345 protected void KillEntity(Scene scene, uint localID)
@@ -1276,6 +1347,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1276 scene.SendKillObject(new List<uint> { localID }); 1347 scene.SendKillObject(new List<uint> { localID });
1277 } 1348 }
1278 1349
1350 // HG hook
1279 protected virtual GridRegion GetFinalDestination(GridRegion region, UUID agentID, string agentHomeURI, out string message) 1351 protected virtual GridRegion GetFinalDestination(GridRegion region, UUID agentID, string agentHomeURI, out string message)
1280 { 1352 {
1281 message = null; 1353 message = null;
@@ -1285,28 +1357,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1285 // This returns 'true' if the new region already has a child agent for our 1357 // This returns 'true' if the new region already has a child agent for our
1286 // incoming agent. The implication is that, if 'false', we have to create the 1358 // incoming agent. The implication is that, if 'false', we have to create the
1287 // child and then teleport into the region. 1359 // child and then teleport into the region.
1288 protected virtual bool NeedsNewAgent(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY) 1360 protected virtual bool NeedsNewAgent(float viewdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY,
1361 int oldsizeX, int oldsizeY, int newsizeX, int newsizeY)
1289 { 1362 {
1290 if (m_regionCombinerModule != null && m_regionCombinerModule.IsRootForMegaregion(Scene.RegionInfo.RegionID)) 1363 return Util.IsOutsideView(viewdist, oldRegionX, newRegionX, oldRegionY, newRegionY,
1291 { 1364 oldsizeX, oldsizeY, newsizeX, newsizeY);
1292 Vector2 swCorner, neCorner;
1293 GetMegaregionViewRange(out swCorner, out neCorner);
1294
1295 m_log.DebugFormat(
1296 "[ENTITY TRANSFER MODULE]: Megaregion view of {0} is from {1} to {2} with new agent check for {3},{4}",
1297 Scene.Name, swCorner, neCorner, newRegionX, newRegionY);
1298
1299 return !(newRegionX >= swCorner.X && newRegionX <= neCorner.X && newRegionY >= swCorner.Y && newRegionY <= neCorner.Y);
1300 }
1301 else
1302 {
1303 return Util.IsOutsideView(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY);
1304 }
1305 } 1365 }
1306 1366
1307 protected virtual bool NeedsClosing(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, GridRegion reg) 1367 // HG Hook
1368 protected virtual bool NeedsClosing(GridRegion reg, bool OutViewRange)
1369
1308 { 1370 {
1309 return Util.IsOutsideView(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY); 1371 return OutViewRange;
1310 } 1372 }
1311 1373
1312 #endregion 1374 #endregion
@@ -1328,11 +1390,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1328 remoteClient.SendTeleportFailed("The teleport destination could not be found."); 1390 remoteClient.SendTeleportFailed("The teleport destination could not be found.");
1329 return; 1391 return;
1330 } 1392 }
1331 ((Scene)(remoteClient.Scene)).RequestTeleportLocation(remoteClient, info.RegionHandle, lm.Position, 1393 ((Scene)(remoteClient.Scene)).RequestTeleportLocation(remoteClient, info.RegionHandle, lm.Position,
1332 Vector3.Zero, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark)); 1394 Vector3.Zero, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark));
1333 } 1395 }
1334 1396
1335 #endregion 1397 #endregion
1336 1398
1337 #region Teleport Home 1399 #region Teleport Home
1338 1400
@@ -1366,7 +1428,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1366 client.SendTeleportFailed("Your home region could not be found."); 1428 client.SendTeleportFailed("Your home region could not be found.");
1367 return false; 1429 return false;
1368 } 1430 }
1369 1431
1370 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Home region of {0} is {1} ({2}-{3})", 1432 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Home region of {0} is {1} ({2}-{3})",
1371 client.Name, regionInfo.RegionName, regionInfo.RegionCoordX, regionInfo.RegionCoordY); 1433 client.Name, regionInfo.RegionName, regionInfo.RegionCoordX, regionInfo.RegionCoordY);
1372 1434
@@ -1389,105 +1451,146 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1389 1451
1390 #region Agent Crossings 1452 #region Agent Crossings
1391 1453
1392 // Given a position relative to the current region (which has previously been tested to 1454 public bool checkAgentAccessToRegion(ScenePresence agent, GridRegion destiny, Vector3 position,
1393 // see that it is actually outside the current region), find the new region that the 1455 EntityTransferContext ctx, out string reason)
1394 // point is actually in. 1456 {
1395 // Returns the coordinates and information of the new region or 'null' of it doesn't exist. 1457 reason = String.Empty;
1458
1459 UUID agentID = agent.UUID;
1460 ulong destinyHandle = destiny.RegionHandle;
1461
1462 if (m_bannedRegionCache.IfBanned(destinyHandle, agentID))
1463 {
1464 return false;
1465 }
1466
1467 Scene ascene = agent.Scene;
1468 string homeURI = ascene.GetAgentHomeURI(agentID);
1469
1470
1471 if (!ascene.SimulationService.QueryAccess(destiny, agentID, homeURI, false, position,
1472 agent.Scene.GetFormatsOffered(), ctx, out reason))
1473 {
1474 m_bannedRegionCache.Add(destinyHandle, agentID, 30.0, 30.0);
1475 return false;
1476 }
1477 return true;
1478 }
1479
1480
1481 // Given a position relative to the current region and outside of it
1482 // find the new region that the point is actually in.
1483 // returns 'null' if new region not found or if information
1484 // and new position relative to it
1485 // now only works for crossings
1486
1396 public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, 1487 public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos,
1397 EntityTransferContext ctx, out Vector3 newpos, out string failureReason) 1488 EntityTransferContext ctx, out Vector3 newpos, out string failureReason)
1398 { 1489 {
1399 newpos = pos; 1490 newpos = pos;
1400 failureReason = string.Empty; 1491 failureReason = string.Empty;
1401 string homeURI = scene.GetAgentHomeURI(agentID);
1402 1492
1403// m_log.DebugFormat( 1493// m_log.DebugFormat(
1404// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name); 1494// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name);
1405 1495
1406 // Compute world location of the object's position 1496 // Compute world location of the agent's position
1407 double presenceWorldX = (double)scene.RegionInfo.WorldLocX + pos.X; 1497 double presenceWorldX = (double)scene.RegionInfo.WorldLocX + pos.X;
1408 double presenceWorldY = (double)scene.RegionInfo.WorldLocY + pos.Y; 1498 double presenceWorldY = (double)scene.RegionInfo.WorldLocY + pos.Y;
1409 1499
1410 // Call the grid service to lookup the region containing the new position. 1500 // Call the grid service to lookup the region containing the new position.
1411 GridRegion neighbourRegion = GetRegionContainingWorldLocation(scene.GridService, scene.RegionInfo.ScopeID, 1501 GridRegion neighbourRegion = GetRegionContainingWorldLocation(
1412 presenceWorldX, presenceWorldY, 1502 scene.GridService, scene.RegionInfo.ScopeID,
1413 Math.Max(scene.RegionInfo.RegionSizeX, scene.RegionInfo.RegionSizeY)); 1503 presenceWorldX, presenceWorldY,
1504 Math.Max(scene.RegionInfo.RegionSizeX, scene.RegionInfo.RegionSizeY));
1505
1506 if (neighbourRegion == null)
1507 return null;
1414 1508
1415 if (neighbourRegion != null) 1509 if (m_bannedRegionCache.IfBanned(neighbourRegion.RegionHandle, agentID))
1416 { 1510 {
1417 // Compute the entity's position relative to the new region 1511 failureReason = "Access Denied or Temporary not possible";
1418 newpos = new Vector3((float)(presenceWorldX - (double)neighbourRegion.RegionLocX), 1512 return null;
1513 }
1514
1515 m_bannedRegionCache.Remove(neighbourRegion.RegionHandle, agentID);
1516
1517 // Compute the entity's position relative to the new region
1518 newpos = new Vector3((float)(presenceWorldX - (double)neighbourRegion.RegionLocX),
1419 (float)(presenceWorldY - (double)neighbourRegion.RegionLocY), 1519 (float)(presenceWorldY - (double)neighbourRegion.RegionLocY),
1420 pos.Z); 1520 pos.Z);
1421 1521
1422 if (m_bannedRegionCache.IfBanned(neighbourRegion.RegionHandle, agentID)) 1522 string homeURI = scene.GetAgentHomeURI(agentID);
1423 { 1523
1424 failureReason = "Cannot region cross into banned parcel"; 1524 if (!scene.SimulationService.QueryAccess(
1425 neighbourRegion = null; 1525 neighbourRegion, agentID, homeURI, false, newpos,
1426 } 1526 scene.GetFormatsOffered(), ctx, out failureReason))
1427 else 1527 {
1428 { 1528 // remember the fail
1429 // If not banned, make sure this agent is not in the list. 1529 m_bannedRegionCache.Add(neighbourRegion.RegionHandle, agentID);
1430 m_bannedRegionCache.Remove(neighbourRegion.RegionHandle, agentID); 1530 if(String.IsNullOrWhiteSpace(failureReason))
1431 } 1531 failureReason = "Access Denied";
1432 1532 return null;
1433 // Check to see if we have access to the target region.
1434 if (neighbourRegion != null
1435 && !scene.SimulationService.QueryAccess(neighbourRegion, agentID, homeURI, false, newpos, scene.GetFormatsOffered(), ctx, out failureReason))
1436 {
1437 // remember banned
1438 m_bannedRegionCache.Add(neighbourRegion.RegionHandle, agentID);
1439 neighbourRegion = null;
1440 }
1441 } 1533 }
1442 else 1534
1535 return neighbourRegion;
1536 }
1537
1538 public bool Cross(ScenePresence agent, bool isFlying)
1539 {
1540 agent.IsInLocalTransit = true;
1541 agent.IsInTransit = true;
1542 CrossAsyncDelegate d = CrossAsync;
1543 d.BeginInvoke(agent, isFlying, CrossCompleted, d);
1544 return true;
1545 }
1546
1547 private void CrossCompleted(IAsyncResult iar)
1548 {
1549 CrossAsyncDelegate icon = (CrossAsyncDelegate)iar.AsyncState;
1550 ScenePresence agent = icon.EndInvoke(iar);
1551
1552 if(agent == null || agent.IsDeleted)
1553 return;
1554
1555 if(!agent.IsChildAgent)
1443 { 1556 {
1444 // The destination region just doesn't exist 1557 // crossing failed
1445 failureReason = "Cannot cross into non-existent region"; 1558 agent.CrossToNewRegionFail();
1446 } 1559 }
1447
1448 if (neighbourRegion == null)
1449 m_log.DebugFormat("{0} GetDestination: region not found. Old region name={1} at <{2},{3}> of size <{4},{5}>. Old pos={6}",
1450 LogHeader, scene.RegionInfo.RegionName,
1451 scene.RegionInfo.RegionLocX, scene.RegionInfo.RegionLocY,
1452 scene.RegionInfo.RegionSizeX, scene.RegionInfo.RegionSizeY,
1453 pos);
1454 else 1560 else
1455 m_log.DebugFormat("{0} GetDestination: new region={1} at <{2},{3}> of size <{4},{5}>, newpos=<{6},{7}>", 1561 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} completed.", agent.Firstname, agent.Lastname);
1456 LogHeader, neighbourRegion.RegionName,
1457 neighbourRegion.RegionLocX, neighbourRegion.RegionLocY, neighbourRegion.RegionSizeX, neighbourRegion.RegionSizeY,
1458 newpos.X, newpos.Y);
1459 1562
1460 return neighbourRegion; 1563 agent.IsInTransit = false;
1461 } 1564 }
1462 1565
1463 public bool Cross(ScenePresence agent, bool isFlying) 1566 public ScenePresence CrossAsync(ScenePresence agent, bool isFlying)
1464 { 1567 {
1465 Vector3 newpos; 1568 Vector3 newpos;
1466 EntityTransferContext ctx = new EntityTransferContext(); 1569 EntityTransferContext ctx = new EntityTransferContext();
1467 string failureReason; 1570 string failureReason;
1468 1571
1469 GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition, 1572 // We need this because of decimal number parsing of the protocols.
1573 Culture.SetCurrentCulture();
1574
1575 Vector3 pos = agent.AbsolutePosition + agent.Velocity * 0.2f;
1576
1577 GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, pos,
1470 ctx, out newpos, out failureReason); 1578 ctx, out newpos, out failureReason);
1471 if (neighbourRegion == null) 1579 if (neighbourRegion == null)
1472 { 1580 {
1473 agent.ControllingClient.SendAlertMessage(failureReason); 1581 if (!agent.IsDeleted && failureReason != String.Empty && agent.ControllingClient != null)
1474 return false; 1582 agent.ControllingClient.SendAlertMessage(failureReason);
1583 return agent;
1475 } 1584 }
1476 1585
1477 agent.IsInTransit = true; 1586// agent.IsInTransit = true;
1478
1479 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync;
1480 d.BeginInvoke(agent, newpos, neighbourRegion, isFlying, ctx, CrossAgentToNewRegionCompleted, d);
1481
1482 Scene.EventManager.TriggerCrossAgentToNewRegion(agent, isFlying, neighbourRegion);
1483 1587
1484 return true; 1588 CrossAgentToNewRegionAsync(agent, newpos, neighbourRegion, isFlying, ctx);
1589 agent.IsInTransit = false;
1590 return agent;
1485 } 1591 }
1486 1592
1487 1593 public delegate void InformClientToInitiateTeleportToLocationDelegate(ScenePresence agent, uint regionX, uint regionY, Vector3 position, Scene initiatingScene);
1488 public delegate void InformClientToInitiateTeleportToLocationDelegate(ScenePresence agent, uint regionX, uint regionY,
1489 Vector3 position,
1490 Scene initiatingScene);
1491 1594
1492 private void InformClientToInitiateTeleportToLocation(ScenePresence agent, uint regionX, uint regionY, Vector3 position, Scene initiatingScene) 1595 private void InformClientToInitiateTeleportToLocation(ScenePresence agent, uint regionX, uint regionY, Vector3 position, Scene initiatingScene)
1493 { 1596 {
@@ -1506,14 +1609,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1506 Thread.Sleep(10000); 1609 Thread.Sleep(10000);
1507 1610
1508 m_log.DebugFormat( 1611 m_log.DebugFormat(
1509 "[ENTITY TRANSFER MODULE]: Auto-reteleporting {0} to correct megaregion location {1},{2},{3} from {4}", 1612 "[ENTITY TRANSFER MODULE]: Auto-reteleporting {0} to correct megaregion location {1},{2},{3} from {4}",
1510 agent.Name, regionX, regionY, position, initiatingScene.Name); 1613 agent.Name, regionX, regionY, position, initiatingScene.Name);
1511 1614
1512 agent.Scene.RequestTeleportLocation( 1615 agent.Scene.RequestTeleportLocation(
1513 agent.ControllingClient, 1616 agent.ControllingClient,
1514 Util.RegionLocToHandle(regionX, regionY), 1617 Util.RegionGridLocToHandle(regionX, regionY),
1515 position, 1618 position,
1516 agent.Lookat, 1619 agent.Lookat,
1517 (uint)Constants.TeleportFlags.ViaLocation); 1620 (uint)Constants.TeleportFlags.ViaLocation);
1518 1621
1519 /* 1622 /*
@@ -1557,15 +1660,71 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1557 icon.EndInvoke(iar); 1660 icon.EndInvoke(iar);
1558 } 1661 }
1559 1662
1560 public bool CrossAgentToNewRegionPrep(ScenePresence agent, GridRegion neighbourRegion) 1663 public bool CrossAgentCreateFarChild(ScenePresence agent, GridRegion neighbourRegion, Vector3 pos, EntityTransferContext ctx)
1561 { 1664 {
1562 if (neighbourRegion == null) 1665 ulong regionhandler = neighbourRegion.RegionHandle;
1666
1667 if(agent.knowsNeighbourRegion(regionhandler))
1668 return true;
1669
1670 string reason;
1671 ulong currentRegionHandler = agent.Scene.RegionInfo.RegionHandle;
1672 GridRegion source = new GridRegion(agent.Scene.RegionInfo);
1673
1674 AgentCircuitData currentAgentCircuit =
1675 agent.Scene.AuthenticateHandler.GetAgentCircuitData(agent.ControllingClient.CircuitCode);
1676 AgentCircuitData agentCircuit = agent.ControllingClient.RequestClientInfo();
1677 agentCircuit.startpos = pos;
1678 agentCircuit.child = true;
1679
1680 agentCircuit.Appearance = new AvatarAppearance();
1681 agentCircuit.Appearance.AvatarHeight = agent.Appearance.AvatarHeight;
1682
1683 if (currentAgentCircuit != null)
1684 {
1685 agentCircuit.ServiceURLs = currentAgentCircuit.ServiceURLs;
1686 agentCircuit.IPAddress = currentAgentCircuit.IPAddress;
1687 agentCircuit.Viewer = currentAgentCircuit.Viewer;
1688 agentCircuit.Channel = currentAgentCircuit.Channel;
1689 agentCircuit.Mac = currentAgentCircuit.Mac;
1690 agentCircuit.Id0 = currentAgentCircuit.Id0;
1691 }
1692
1693 agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath();
1694 agent.AddNeighbourRegion(neighbourRegion, agentCircuit.CapsPath);
1695
1696 IPEndPoint endPoint = neighbourRegion.ExternalEndPoint;
1697 if(endPoint == null)
1698 {
1699 m_log.DebugFormat("CrossAgentCreateFarChild failed to resolve neighbour address {0}", neighbourRegion.ExternalHostName);
1563 return false; 1700 return false;
1564 1701 }
1565 m_entityTransferStateMachine.SetInTransit(agent.UUID); 1702 if (!Scene.SimulationService.CreateAgent(source, neighbourRegion, agentCircuit, (int)TeleportFlags.Default, ctx, out reason))
1703 {
1704 agent.RemoveNeighbourRegion(regionhandler);
1705 return false;
1706 }
1707
1708 string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
1709 int newSizeX = neighbourRegion.RegionSizeX;
1710 int newSizeY = neighbourRegion.RegionSizeY;
1566 1711
1567 agent.RemoveFromPhysicalScene(); 1712 if (m_eqModule != null)
1713 {
1714 m_log.DebugFormat("{0} {1} is sending {2} EnableSimulator for neighbour region {3}(loc=<{4},{5}>,siz=<{6},{7}>) " +
1715 "and EstablishAgentCommunication with seed cap {8}", LogHeader,
1716 source.RegionName, agent.Name,
1717 neighbourRegion.RegionName, neighbourRegion.RegionLocX, neighbourRegion.RegionLocY, newSizeX, newSizeY , capsPath);
1568 1718
1719 m_eqModule.EnableSimulator(regionhandler,
1720 endPoint, agent.UUID, newSizeX, newSizeY);
1721 m_eqModule.EstablishAgentCommunication(agent.UUID, endPoint, capsPath,
1722 regionhandler, newSizeX, newSizeY);
1723 }
1724 else
1725 {
1726 agent.ControllingClient.InformClientOfNeighbour(regionhandler, endPoint);
1727 }
1569 return true; 1728 return true;
1570 } 1729 }
1571 1730
@@ -1582,37 +1741,56 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1582 m_log.DebugFormat("{0}: CrossAgentToNewRegionAsync: new region={1} at <{2},{3}>. newpos={4}", 1741 m_log.DebugFormat("{0}: CrossAgentToNewRegionAsync: new region={1} at <{2},{3}>. newpos={4}",
1583 LogHeader, neighbourRegion.RegionName, neighbourRegion.RegionLocX, neighbourRegion.RegionLocY, pos); 1742 LogHeader, neighbourRegion.RegionName, neighbourRegion.RegionLocX, neighbourRegion.RegionLocY, pos);
1584 1743
1585 if (!CrossAgentToNewRegionPrep(agent, neighbourRegion)) 1744 if (neighbourRegion == null)
1586 { 1745 {
1587 m_log.DebugFormat("{0}: CrossAgentToNewRegionAsync: prep failed. Resetting transfer state", LogHeader); 1746 m_log.DebugFormat("{0}: CrossAgentToNewRegionAsync: invalid destiny", LogHeader);
1588 m_entityTransferStateMachine.ResetFromTransit(agent.UUID); 1747 return agent;
1748 }
1749
1750 IPEndPoint endpoint = neighbourRegion.ExternalEndPoint;
1751 if(endpoint == null)
1752 {
1753 m_log.DebugFormat("{0}: CrossAgentToNewRegionAsync: failed to resolve neighbour address {0} ",neighbourRegion.ExternalHostName);
1754 return agent;
1589 } 1755 }
1590 1756
1591 if (!CrossAgentIntoNewRegionMain(agent, pos, neighbourRegion, isFlying, ctx)) 1757 m_entityTransferStateMachine.SetInTransit(agent.UUID);
1758 agent.RemoveFromPhysicalScene();
1759
1760 if (!CrossAgentIntoNewRegionMain(agent, pos, neighbourRegion, endpoint, isFlying, ctx))
1592 { 1761 {
1593 m_log.DebugFormat("{0}: CrossAgentToNewRegionAsync: cross main failed. Resetting transfer state", LogHeader); 1762 m_log.DebugFormat("{0}: CrossAgentToNewRegionAsync: cross main failed. Resetting transfer state", LogHeader);
1594 m_entityTransferStateMachine.ResetFromTransit(agent.UUID); 1763 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1595 } 1764 }
1596
1597 CrossAgentToNewRegionPost(agent, pos, neighbourRegion, isFlying, ctx);
1598 } 1765 }
1599 catch (Exception e) 1766 catch (Exception e)
1600 { 1767 {
1601 m_log.Error(string.Format("{0}: CrossAgentToNewRegionAsync: failed with exception ", LogHeader), e); 1768 m_log.Error(string.Format("{0}: CrossAgentToNewRegionAsync: failed with exception ", LogHeader), e);
1602 } 1769 }
1603
1604 return agent; 1770 return agent;
1605 } 1771 }
1606 1772
1607 public bool CrossAgentIntoNewRegionMain(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, EntityTransferContext ctx) 1773 public bool CrossAgentIntoNewRegionMain(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion,
1774 IPEndPoint endpoint, bool isFlying, EntityTransferContext ctx)
1608 { 1775 {
1776 int ts = Util.EnvironmentTickCount();
1777 bool sucess = true;
1778 string reason = String.Empty;
1779 List<ulong> childRegionsToClose = null;
1609 try 1780 try
1610 { 1781 {
1611 AgentData cAgent = new AgentData(); 1782 AgentData cAgent = new AgentData();
1612 agent.CopyTo(cAgent); 1783 agent.CopyTo(cAgent,true);
1613 if (ctx.OutboundVersion < 0.5f) 1784
1614 cAgent.Appearance.PackLegacyWearables = true;
1615 cAgent.Position = pos; 1785 cAgent.Position = pos;
1786 cAgent.ChildrenCapSeeds = agent.KnownRegions;
1787
1788 childRegionsToClose = agent.GetChildAgentsToClose(neighbourRegion.RegionHandle, neighbourRegion.RegionSizeX, neighbourRegion.RegionSizeY);
1789 if(cAgent.ChildrenCapSeeds != null)
1790 {
1791 foreach(ulong regh in childRegionsToClose)
1792 cAgent.ChildrenCapSeeds.Remove(regh);
1793 }
1616 1794
1617 if (isFlying) 1795 if (isFlying)
1618 cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; 1796 cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY;
@@ -1623,21 +1801,31 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1623 // Beyond this point, extra cleanup is needed beyond removing transit state 1801 // Beyond this point, extra cleanup is needed beyond removing transit state
1624 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring); 1802 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring);
1625 1803
1626 if (!agent.Scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) 1804 if (sucess && !agent.Scene.SimulationService.UpdateAgent(neighbourRegion, cAgent, ctx))
1805 {
1806 sucess = false;
1807 reason = "agent update failed";
1808 }
1809
1810 if(!sucess)
1627 { 1811 {
1628 // region doesn't take it 1812 // region doesn't take it
1629 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); 1813 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
1630 1814
1631 m_log.WarnFormat( 1815 m_log.WarnFormat(
1632 "[ENTITY TRANSFER MODULE]: Region {0} would not accept update for agent {1} on cross attempt. Returning to original region.", 1816 "[ENTITY TRANSFER MODULE]: agent {0} crossing to {1} failed: {2}",
1633 neighbourRegion.RegionName, agent.Name); 1817 agent.Name, neighbourRegion.RegionName, reason);
1634 1818
1635 ReInstantiateScripts(agent); 1819 ReInstantiateScripts(agent);
1636 agent.AddToPhysicalScene(isFlying); 1820 if(agent.ParentID == 0 && agent.ParentUUID == UUID.Zero)
1821 {
1822 agent.AddToPhysicalScene(isFlying);
1823 }
1637 1824
1638 return false; 1825 return false;
1639 } 1826 }
1640 1827
1828 m_log.DebugFormat("[CrossAgentIntoNewRegionMain] ok, time {0}ms",Util.EnvironmentTickCountSubtract(ts));
1641 } 1829 }
1642 catch (Exception e) 1830 catch (Exception e)
1643 { 1831 {
@@ -1649,44 +1837,38 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1649 return false; 1837 return false;
1650 } 1838 }
1651 1839
1652 return true;
1653 }
1654
1655 public void CrossAgentToNewRegionPost(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion,
1656 bool isFlying, EntityTransferContext ctx)
1657 {
1658 agent.ControllingClient.RequestClientInfo();
1659
1660 string agentcaps; 1840 string agentcaps;
1661 if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps)) 1841 if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps))
1662 { 1842 {
1663 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.", 1843 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.",
1664 neighbourRegion.RegionHandle); 1844 neighbourRegion.RegionHandle);
1665 return; 1845 return false;
1666 } 1846 }
1667 1847
1668 // No turning back 1848 // No turning back
1849
1669 agent.IsChildAgent = true; 1850 agent.IsChildAgent = true;
1670 1851
1671 string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); 1852 string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps);
1672 1853
1673 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); 1854 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID);
1674 1855
1675 Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0); 1856 Vector3 vel2 = Vector3.Zero;
1857 if((agent.crossingFlags & 2) != 0)
1858 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0);
1676 1859
1677 if (m_eqModule != null) 1860 if (m_eqModule != null)
1678 { 1861 {
1679 m_eqModule.CrossRegion( 1862 m_eqModule.CrossRegion(
1680 neighbourRegion.RegionHandle, pos + agent.Velocity, vel2 /* agent.Velocity */, 1863 neighbourRegion.RegionHandle, pos, vel2 /* agent.Velocity */,
1681 neighbourRegion.ExternalEndPoint, 1864 endpoint, capsPath, agent.UUID, agent.ControllingClient.SessionId,
1682 capsPath, agent.UUID, agent.ControllingClient.SessionId,
1683 neighbourRegion.RegionSizeX, neighbourRegion.RegionSizeY); 1865 neighbourRegion.RegionSizeX, neighbourRegion.RegionSizeY);
1684 } 1866 }
1685 else 1867 else
1686 { 1868 {
1687 m_log.ErrorFormat("{0} Using old CrossRegion packet. Varregion will not work!!", LogHeader); 1869 m_log.ErrorFormat("{0} Using old CrossRegion packet. Varregion will not work!!", LogHeader);
1688 agent.ControllingClient.CrossRegion(neighbourRegion.RegionHandle, pos + agent.Velocity, agent.Velocity, neighbourRegion.ExternalEndPoint, 1870 agent.ControllingClient.CrossRegion(neighbourRegion.RegionHandle, pos, agent.Velocity,
1689 capsPath); 1871 endpoint,capsPath);
1690 } 1872 }
1691 1873
1692 // SUCCESS! 1874 // SUCCESS!
@@ -1695,51 +1877,23 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1695 // Unlike a teleport, here we do not wait for the destination region to confirm the receipt. 1877 // Unlike a teleport, here we do not wait for the destination region to confirm the receipt.
1696 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); 1878 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
1697 1879
1698 agent.MakeChildAgent(); 1880 if(childRegionsToClose != null)
1881 agent.CloseChildAgents(childRegionsToClose);
1699 1882
1700 // FIXME: Possibly this should occur lower down after other commands to close other agents, 1883 if((agent.crossingFlags & 8) == 0)
1701 // but not sure yet what the side effects would be. 1884 agent.ClearControls(); // don't let attachments delete (called in HasMovedAway) disturb taken controls on viewers
1702 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1703
1704 // now we have a child agent in this region. Request all interesting data about other (root) agents
1705 agent.SendOtherAgentsAvatarDataToClient();
1706 agent.SendOtherAgentsAppearanceToClient();
1707
1708 // TODO: Check since what version this wasn't needed anymore. May be as old as 0.6
1709/*
1710 // Backwards compatibility. Best effort
1711 if (version == 0f)
1712 {
1713 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one...");
1714 Thread.Sleep(3000); // wait a little now that we're not waiting for the callback
1715 CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true);
1716 }
1717*/
1718 // Next, let's close the child agent connections that are too far away.
1719 uint neighbourx;
1720 uint neighboury;
1721 Util.RegionHandleToRegionLoc(neighbourRegion.RegionHandle, out neighbourx, out neighboury);
1722 1885
1723 agent.CloseChildAgents(neighbourx, neighboury); 1886 agent.HasMovedAway((agent.crossingFlags & 8) == 0);
1724 1887
1725 AgentHasMovedAway(agent, false); 1888 agent.MakeChildAgent(neighbourRegion.RegionHandle);
1726 1889
1727 // the user may change their profile information in other region, 1890 // FIXME: Possibly this should occur lower down after other commands to close other agents,
1728 // so the userinfo in UserProfileCache is not reliable any more, delete it 1891 // but not sure yet what the side effects would be.
1729 // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! 1892 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1730// if (agent.Scene.NeedSceneCacheClear(agent.UUID))
1731// {
1732// m_log.DebugFormat(
1733// "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID);
1734// }
1735
1736 //m_log.Debug("AFTER CROSS");
1737 //Scene.DumpChildrenSeeds(UUID);
1738 //DumpKnownRegions();
1739 1893
1740 return; 1894 return true;
1741 } 1895 }
1742 1896
1743 private void CrossAgentToNewRegionCompleted(IAsyncResult iar) 1897 private void CrossAgentToNewRegionCompleted(IAsyncResult iar)
1744 { 1898 {
1745 CrossAgentToNewRegionDelegate icon = (CrossAgentToNewRegionDelegate)iar.AsyncState; 1899 CrossAgentToNewRegionDelegate icon = (CrossAgentToNewRegionDelegate)iar.AsyncState;
@@ -1754,7 +1908,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1754 // In any case 1908 // In any case
1755 agent.IsInTransit = false; 1909 agent.IsInTransit = false;
1756 1910
1757 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} completed.", agent.Firstname, agent.Lastname); 1911// m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} completed.", agent.Firstname, agent.Lastname);
1758 } 1912 }
1759 1913
1760 #endregion 1914 #endregion
@@ -1762,7 +1916,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1762 #region Enable Child Agent 1916 #region Enable Child Agent
1763 1917
1764 /// <summary> 1918 /// <summary>
1765 /// This informs a single neighbouring region about agent "avatar". 1919 /// This informs a single neighbouring region about agent "avatar", and avatar about it
1766 /// Calls an asynchronous method to do so.. so it doesn't lag the sim. 1920 /// Calls an asynchronous method to do so.. so it doesn't lag the sim.
1767 /// </summary> 1921 /// </summary>
1768 /// <param name="sp"></param> 1922 /// <param name="sp"></param>
@@ -1771,42 +1925,46 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1771 { 1925 {
1772 m_log.DebugFormat("[ENTITY TRANSFER]: Enabling child agent in new neighbour {0}", region.RegionName); 1926 m_log.DebugFormat("[ENTITY TRANSFER]: Enabling child agent in new neighbour {0}", region.RegionName);
1773 1927
1928 ulong currentRegionHandler = sp.Scene.RegionInfo.RegionHandle;
1929 ulong regionhandler = region.RegionHandle;
1930
1931 Dictionary<ulong, string> seeds = new Dictionary<ulong, string>(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID));
1932
1933 if (seeds.ContainsKey(regionhandler))
1934 seeds.Remove(regionhandler);
1935/*
1936 List<ulong> oldregions = new List<ulong>(seeds.Keys);
1937
1938 if (oldregions.Contains(currentRegionHandler))
1939 oldregions.Remove(currentRegionHandler);
1940*/
1941 if (!seeds.ContainsKey(currentRegionHandler))
1942 seeds.Add(currentRegionHandler, sp.ControllingClient.RequestClientInfo().CapsPath);
1943
1774 AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); 1944 AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
1775 AgentCircuitData agent = sp.ControllingClient.RequestClientInfo(); 1945 AgentCircuitData agent = sp.ControllingClient.RequestClientInfo();
1776 agent.BaseFolder = UUID.Zero; 1946 agent.BaseFolder = UUID.Zero;
1777 agent.InventoryFolder = UUID.Zero; 1947 agent.InventoryFolder = UUID.Zero;
1778 agent.startpos = new Vector3(128, 128, 70); 1948 agent.startpos = sp.AbsolutePosition + CalculateOffset(sp, region);
1779 agent.child = true; 1949 agent.child = true;
1780 agent.Appearance = new AvatarAppearance(); 1950 agent.Appearance = new AvatarAppearance();
1781 agent.Appearance.PackLegacyWearables = true; 1951 agent.Appearance.AvatarHeight = sp.Appearance.AvatarHeight;
1782 agent.CapsPath = CapsUtil.GetRandomCapsObjectPath();
1783
1784 agent.ChildrenCapSeeds = new Dictionary<ulong, string>(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID));
1785 //m_log.DebugFormat("[XXX] Seeds 1 {0}", agent.ChildrenCapSeeds.Count);
1786 1952
1787 if (!agent.ChildrenCapSeeds.ContainsKey(sp.Scene.RegionInfo.RegionHandle)) 1953 agent.CapsPath = CapsUtil.GetRandomCapsObjectPath();
1788 agent.ChildrenCapSeeds.Add(sp.Scene.RegionInfo.RegionHandle, sp.ControllingClient.RequestClientInfo().CapsPath);
1789 //m_log.DebugFormat("[XXX] Seeds 2 {0}", agent.ChildrenCapSeeds.Count);
1790 1954
1791 sp.AddNeighbourRegion(region.RegionHandle, agent.CapsPath); 1955 seeds.Add(regionhandler, agent.CapsPath);
1792 //foreach (ulong h in agent.ChildrenCapSeeds.Keys)
1793 // m_log.DebugFormat("[XXX] --> {0}", h);
1794 //m_log.DebugFormat("[XXX] Adding {0}", region.RegionHandle);
1795 if (agent.ChildrenCapSeeds.ContainsKey(region.RegionHandle))
1796 {
1797 m_log.WarnFormat(
1798 "[ENTITY TRANSFER]: Overwriting caps seed {0} with {1} for region {2} (handle {3}) for {4} in {5}",
1799 agent.ChildrenCapSeeds[region.RegionHandle], agent.CapsPath,
1800 region.RegionName, region.RegionHandle, sp.Name, Scene.Name);
1801 }
1802 1956
1803 agent.ChildrenCapSeeds[region.RegionHandle] = agent.CapsPath; 1957// agent.ChildrenCapSeeds = new Dictionary<ulong, string>(seeds);
1958 agent.ChildrenCapSeeds = null;
1804 1959
1805 if (sp.Scene.CapsModule != null) 1960 if (sp.Scene.CapsModule != null)
1806 { 1961 {
1807 sp.Scene.CapsModule.SetChildrenSeed(sp.UUID, agent.ChildrenCapSeeds); 1962 sp.Scene.CapsModule.SetChildrenSeed(sp.UUID, seeds);
1808 } 1963 }
1809 1964
1965 sp.KnownRegions = seeds;
1966 sp.AddNeighbourRegionSizeInfo(region);
1967
1810 if (currentAgentCircuit != null) 1968 if (currentAgentCircuit != null)
1811 { 1969 {
1812 agent.ServiceURLs = currentAgentCircuit.ServiceURLs; 1970 agent.ServiceURLs = currentAgentCircuit.ServiceURLs;
@@ -1816,7 +1974,24 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1816 agent.Mac = currentAgentCircuit.Mac; 1974 agent.Mac = currentAgentCircuit.Mac;
1817 agent.Id0 = currentAgentCircuit.Id0; 1975 agent.Id0 = currentAgentCircuit.Id0;
1818 } 1976 }
1819 1977/*
1978 AgentPosition agentpos = null;
1979
1980 if (oldregions.Count > 0)
1981 {
1982 agentpos = new AgentPosition();
1983 agentpos.AgentID = new UUID(sp.UUID.Guid);
1984 agentpos.SessionID = sp.ControllingClient.SessionId;
1985 agentpos.Size = sp.Appearance.AvatarSize;
1986 agentpos.Center = sp.CameraPosition;
1987 agentpos.Far = sp.DrawDistance;
1988 agentpos.Position = sp.AbsolutePosition;
1989 agentpos.Velocity = sp.Velocity;
1990 agentpos.RegionHandle = currentRegionHandler;
1991 agentpos.Throttles = sp.ControllingClient.GetThrottlesPacked(1);
1992 agentpos.ChildrenCapSeeds = seeds;
1993 }
1994*/
1820 IPEndPoint external = region.ExternalEndPoint; 1995 IPEndPoint external = region.ExternalEndPoint;
1821 if (external != null) 1996 if (external != null)
1822 { 1997 {
@@ -1825,7 +2000,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1825 InformClientOfNeighbourCompleted, 2000 InformClientOfNeighbourCompleted,
1826 d); 2001 d);
1827 } 2002 }
2003/*
2004 if(oldregions.Count >0)
2005 {
2006 uint neighbourx;
2007 uint neighboury;
2008 UUID scope = sp.Scene.RegionInfo.ScopeID;
2009 foreach (ulong handler in oldregions)
2010 {
2011 Utils.LongToUInts(handler, out neighbourx, out neighboury);
2012 GridRegion neighbour = sp.Scene.GridService.GetRegionByPosition(scope, (int)neighbourx, (int)neighboury);
2013 sp.Scene.SimulationService.UpdateAgent(neighbour, agentpos);
2014 }
2015 }
2016 */
1828 } 2017 }
2018
1829 #endregion 2019 #endregion
1830 2020
1831 #region Enable Child Agents 2021 #region Enable Child Agents
@@ -1835,167 +2025,175 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1835 2025
1836 /// <summary> 2026 /// <summary>
1837 /// This informs all neighbouring regions about agent "avatar". 2027 /// This informs all neighbouring regions about agent "avatar".
2028 /// and as important informs the avatar about then
1838 /// </summary> 2029 /// </summary>
1839 /// <param name="sp"></param> 2030 /// <param name="sp"></param>
1840 public void EnableChildAgents(ScenePresence sp) 2031 public void EnableChildAgents(ScenePresence sp)
1841 { 2032 {
2033 // assumes that out of view range regions are disconnected by the previus region
2034
1842 List<GridRegion> neighbours = new List<GridRegion>(); 2035 List<GridRegion> neighbours = new List<GridRegion>();
1843 RegionInfo m_regionInfo = sp.Scene.RegionInfo; 2036 Scene spScene = sp.Scene;
2037 RegionInfo m_regionInfo = spScene.RegionInfo;
1844 2038
1845 if (m_regionInfo != null) 2039 if (m_regionInfo != null)
1846 { 2040 {
1847 neighbours = GetNeighbours(sp, m_regionInfo.RegionLocX, m_regionInfo.RegionLocY); 2041 neighbours = GetNeighbors(sp, m_regionInfo.RegionLocX, m_regionInfo.RegionLocY);
1848 } 2042 }
1849 else 2043 else
1850 { 2044 {
1851 m_log.Debug("[ENTITY TRANSFER MODULE]: m_regionInfo was null in EnableChildAgents, is this a NPC?"); 2045 m_log.Debug("[ENTITY TRANSFER MODULE]: m_regionInfo was null in EnableChildAgents, is this a NPC?");
1852 } 2046 }
1853 2047
1854 /// We need to find the difference between the new regions where there are no child agents 2048 ulong currentRegionHandler = m_regionInfo.RegionHandle;
1855 /// and the regions where there are already child agents. We only send notification to the former.
1856 List<ulong> neighbourHandles = NeighbourHandles(neighbours); // on this region
1857 neighbourHandles.Add(sp.Scene.RegionInfo.RegionHandle); // add this region too
1858 List<ulong> previousRegionNeighbourHandles;
1859 2049
1860 if (sp.Scene.CapsModule != null) 2050 LinkedList<ulong> previousRegionNeighbourHandles;
2051 Dictionary<ulong, string> seeds;
2052 ICapabilitiesModule capsModule = spScene.CapsModule;
2053
2054 if (capsModule != null)
1861 { 2055 {
1862 previousRegionNeighbourHandles = 2056 seeds = new Dictionary<ulong, string>(capsModule.GetChildrenSeeds(sp.UUID));
1863 new List<ulong>(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID).Keys); 2057 previousRegionNeighbourHandles = new LinkedList<ulong>(seeds.Keys);
1864 } 2058 }
1865 else 2059 else
1866 { 2060 {
1867 previousRegionNeighbourHandles = new List<ulong>(); 2061 seeds = new Dictionary<ulong, string>();
2062 previousRegionNeighbourHandles = new LinkedList<ulong>();
1868 } 2063 }
1869 2064
1870 List<ulong> newRegions = NewNeighbours(neighbourHandles, previousRegionNeighbourHandles); 2065 IClientAPI spClient = sp.ControllingClient;
1871 List<ulong> oldRegions = OldNeighbours(neighbourHandles, previousRegionNeighbourHandles);
1872
1873// Dump("Current Neighbors", neighbourHandles);
1874// Dump("Previous Neighbours", previousRegionNeighbourHandles);
1875// Dump("New Neighbours", newRegions);
1876// Dump("Old Neighbours", oldRegions);
1877 2066
1878 /// Update the scene presence's known regions here on this region 2067 // This will fail if the user aborts login
1879 sp.DropOldNeighbours(oldRegions); 2068 try
1880 2069 {
1881 /// Collect as many seeds as possible 2070 if (!seeds.ContainsKey(currentRegionHandler))
1882 Dictionary<ulong, string> seeds; 2071 seeds.Add(currentRegionHandler, spClient.RequestClientInfo().CapsPath);
1883 if (sp.Scene.CapsModule != null) 2072 }
1884 seeds = new Dictionary<ulong, string>(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID)); 2073 catch
1885 else 2074 {
1886 seeds = new Dictionary<ulong, string>(); 2075 return;
2076 }
1887 2077
1888 //m_log.Debug(" !!! No. of seeds: " + seeds.Count); 2078 AgentCircuitData currentAgentCircuit =
1889 if (!seeds.ContainsKey(sp.Scene.RegionInfo.RegionHandle)) 2079 spScene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
1890 seeds.Add(sp.Scene.RegionInfo.RegionHandle, sp.ControllingClient.RequestClientInfo().CapsPath);
1891 2080
1892 /// Create the necessary child agents
1893 List<AgentCircuitData> cagents = new List<AgentCircuitData>(); 2081 List<AgentCircuitData> cagents = new List<AgentCircuitData>();
2082 List<ulong> newneighbours = new List<ulong>();
2083
1894 foreach (GridRegion neighbour in neighbours) 2084 foreach (GridRegion neighbour in neighbours)
1895 { 2085 {
1896 if (neighbour.RegionHandle != sp.Scene.RegionInfo.RegionHandle) 2086 ulong handler = neighbour.RegionHandle;
2087
2088 if (previousRegionNeighbourHandles.Contains(handler))
1897 { 2089 {
1898 AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); 2090 // agent already knows this region
1899 AgentCircuitData agent = sp.ControllingClient.RequestClientInfo(); 2091 previousRegionNeighbourHandles.Remove(handler);
1900 agent.BaseFolder = UUID.Zero; 2092 continue;
1901 agent.InventoryFolder = UUID.Zero; 2093 }
1902 agent.startpos = sp.AbsolutePosition + CalculateOffset(sp, neighbour);
1903 agent.child = true;
1904 agent.Appearance = new AvatarAppearance();
1905 agent.Appearance.PackLegacyWearables = true;
1906 if (currentAgentCircuit != null)
1907 {
1908 agent.ServiceURLs = currentAgentCircuit.ServiceURLs;
1909 agent.IPAddress = currentAgentCircuit.IPAddress;
1910 agent.Viewer = currentAgentCircuit.Viewer;
1911 agent.Channel = currentAgentCircuit.Channel;
1912 agent.Mac = currentAgentCircuit.Mac;
1913 agent.Id0 = currentAgentCircuit.Id0;
1914 }
1915 2094
1916 if (newRegions.Contains(neighbour.RegionHandle)) 2095 if (handler == currentRegionHandler)
1917 { 2096 continue;
1918 agent.CapsPath = CapsUtil.GetRandomCapsObjectPath();
1919 sp.AddNeighbourRegion(neighbour.RegionHandle, agent.CapsPath);
1920 seeds.Add(neighbour.RegionHandle, agent.CapsPath);
1921 }
1922 else
1923 {
1924 agent.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, neighbour.RegionHandle);
1925 }
1926 2097
1927 cagents.Add(agent); 2098 // a new region to add
2099 AgentCircuitData agent = spClient.RequestClientInfo();
2100 agent.BaseFolder = UUID.Zero;
2101 agent.InventoryFolder = UUID.Zero;
2102 agent.startpos = sp.AbsolutePosition + CalculateOffset(sp, neighbour);
2103 agent.child = true;
2104 agent.Appearance = new AvatarAppearance();
2105 agent.Appearance.AvatarHeight = sp.Appearance.AvatarHeight;
2106
2107 if (currentAgentCircuit != null)
2108 {
2109 agent.ServiceURLs = currentAgentCircuit.ServiceURLs;
2110 agent.IPAddress = currentAgentCircuit.IPAddress;
2111 agent.Viewer = currentAgentCircuit.Viewer;
2112 agent.Channel = currentAgentCircuit.Channel;
2113 agent.Mac = currentAgentCircuit.Mac;
2114 agent.Id0 = currentAgentCircuit.Id0;
1928 } 2115 }
1929 }
1930 2116
1931 /// Update all child agent with everyone's seeds 2117 newneighbours.Add(handler);
1932 foreach (AgentCircuitData a in cagents) 2118 agent.CapsPath = CapsUtil.GetRandomCapsObjectPath();
1933 { 2119 seeds.Add(handler, agent.CapsPath);
1934 a.ChildrenCapSeeds = new Dictionary<ulong, string>(seeds);
1935 }
1936 2120
1937 if (sp.Scene.CapsModule != null) 2121 agent.ChildrenCapSeeds = null;
1938 { 2122 cagents.Add(agent);
1939 sp.Scene.CapsModule.SetChildrenSeed(sp.UUID, seeds);
1940 } 2123 }
1941 sp.KnownRegions = seeds;
1942 //avatar.Scene.DumpChildrenSeeds(avatar.UUID);
1943 //avatar.DumpKnownRegions();
1944 2124
1945 bool newAgent = false; 2125 if (previousRegionNeighbourHandles.Contains(currentRegionHandler))
1946 int count = 0; 2126 previousRegionNeighbourHandles.Remove(currentRegionHandler);
1947 foreach (GridRegion neighbour in neighbours)
1948 {
1949 //m_log.WarnFormat("--> Going to send child agent to {0}", neighbour.RegionName);
1950 // Don't do it if there's already an agent in that region
1951 if (newRegions.Contains(neighbour.RegionHandle))
1952 newAgent = true;
1953 else
1954 newAgent = false;
1955// continue;
1956 2127
1957 if (neighbour.RegionHandle != sp.Scene.RegionInfo.RegionHandle) 2128 // previousRegionNeighbourHandles now contains regions to forget
1958 { 2129 foreach (ulong handler in previousRegionNeighbourHandles)
1959 try 2130 seeds.Remove(handler);
1960 {
1961 // Let's put this back at sync, so that it doesn't clog
1962 // the network, especially for regions in the same physical server.
1963 // We're really not in a hurry here.
1964 InformClientOfNeighbourAsync(sp, cagents[count], neighbour, neighbour.ExternalEndPoint, newAgent);
1965 //InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync;
1966 //d.BeginInvoke(sp, cagents[count], neighbour, neighbour.ExternalEndPoint, newAgent,
1967 // InformClientOfNeighbourCompleted,
1968 // d);
1969 }
1970 2131
1971 catch (ArgumentOutOfRangeException) 2132 /// Update all child agent with everyone's seeds
1972 { 2133 // foreach (AgentCircuitData a in cagents)
1973 m_log.ErrorFormat( 2134 // a.ChildrenCapSeeds = new Dictionary<ulong, string>(seeds);
1974 "[ENTITY TRANSFER MODULE]: Neighbour Regions response included the current region in the neighbour list. The following region will not display to the client: {0} for region {1} ({2}, {3}).",
1975 neighbour.ExternalHostName,
1976 neighbour.RegionHandle,
1977 neighbour.RegionLocX,
1978 neighbour.RegionLocY);
1979 }
1980 catch (Exception e)
1981 {
1982 m_log.ErrorFormat(
1983 "[ENTITY TRANSFER MODULE]: Could not resolve external hostname {0} for region {1} ({2}, {3}). {4}",
1984 neighbour.ExternalHostName,
1985 neighbour.RegionHandle,
1986 neighbour.RegionLocX,
1987 neighbour.RegionLocY,
1988 e);
1989 2135
1990 // FIXME: Okay, even though we've failed, we're still going to throw the exception on, 2136 if (capsModule != null)
1991 // since I don't know what will happen if we just let the client continue 2137 capsModule.SetChildrenSeed(sp.UUID, seeds);
1992 2138
1993 // XXX: Well, decided to swallow the exception instead for now. Let us see how that goes. 2139 sp.KnownRegions = seeds;
1994 // throw e; 2140 sp.SetNeighbourRegionSizeInfo(neighbours);
2141
2142 if(newneighbours.Count > 0 || previousRegionNeighbourHandles.Count > 0)
2143 {
2144 AgentPosition agentpos = new AgentPosition();
2145 agentpos.AgentID = new UUID(sp.UUID.Guid);
2146 agentpos.SessionID = spClient.SessionId;
2147 agentpos.Size = sp.Appearance.AvatarSize;
2148 agentpos.Center = sp.CameraPosition;
2149 agentpos.Far = sp.DrawDistance;
2150 agentpos.Position = sp.AbsolutePosition;
2151 agentpos.Velocity = sp.Velocity;
2152 agentpos.RegionHandle = currentRegionHandler;
2153 //agentpos.GodLevel = sp.GodLevel;
2154 agentpos.GodData = sp.GodController.State();
2155 agentpos.Throttles = spClient.GetThrottlesPacked(1);
2156 // agentpos.ChildrenCapSeeds = seeds;
2157
2158 Util.FireAndForget(delegate
2159 {
2160 Thread.Sleep(200); // the original delay that was at InformClientOfNeighbourAsync start
2161 int count = 0;
2162 IPEndPoint ipe;
1995 2163
2164 foreach (GridRegion neighbour in neighbours)
2165 {
2166 ulong handler = neighbour.RegionHandle;
2167 try
2168 {
2169 if (newneighbours.Contains(handler))
2170 {
2171 ipe = neighbour.ExternalEndPoint;
2172 if (ipe != null)
2173 InformClientOfNeighbourAsync(sp, cagents[count], neighbour, ipe, true);
2174 else
2175 {
2176 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: lost DNS resolution for neighbour {0}", neighbour.ExternalHostName);
2177 }
2178 count++;
2179 }
2180 else if (!previousRegionNeighbourHandles.Contains(handler))
2181 {
2182 spScene.SimulationService.UpdateAgent(neighbour, agentpos);
2183 }
2184 }
2185 catch (Exception e)
2186 {
2187 m_log.ErrorFormat(
2188 "[ENTITY TRANSFER MODULE]: Error creating child agent at {0} ({1} ({2}, {3}). {4}",
2189 neighbour.ExternalHostName,
2190 neighbour.RegionHandle,
2191 neighbour.RegionLocX,
2192 neighbour.RegionLocY,
2193 e);
2194 }
1996 } 2195 }
1997 } 2196 });
1998 count++;
1999 } 2197 }
2000 } 2198 }
2001 2199
@@ -2004,26 +2202,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2004 // The first region is the home region of the passed scene presence. 2202 // The first region is the home region of the passed scene presence.
2005 Vector3 CalculateOffset(ScenePresence sp, GridRegion neighbour) 2203 Vector3 CalculateOffset(ScenePresence sp, GridRegion neighbour)
2006 { 2204 {
2007 /* 2205 return new Vector3(sp.Scene.RegionInfo.WorldLocX - neighbour.RegionLocX,
2008 int rRegionX = (int)sp.Scene.RegionInfo.LegacyRegionLocX;
2009 int rRegionY = (int)sp.Scene.RegionInfo.LegacyRegionLocY;
2010 int tRegionX = neighbour.RegionLocX / (int)Constants.RegionSize;
2011 int tRegionY = neighbour.RegionLocY / (int)Constants.RegionSize;
2012 int shiftx = (rRegionX - tRegionX) * (int)Constants.RegionSize;
2013 int shifty = (rRegionY - tRegionY) * (int)Constants.RegionSize;
2014 return new Vector3(shiftx, shifty, 0f);
2015 */
2016 return new Vector3( sp.Scene.RegionInfo.WorldLocX - neighbour.RegionLocX,
2017 sp.Scene.RegionInfo.WorldLocY - neighbour.RegionLocY, 2206 sp.Scene.RegionInfo.WorldLocY - neighbour.RegionLocY,
2018 0f); 2207 0f);
2019 } 2208 }
2020 2209 #endregion
2021 public GridRegion GetRegionContainingWorldLocation(IGridService pGridService, UUID pScopeID, double px, double py)
2022 {
2023 // Since we don't know how big the regions could be, we have to search a very large area
2024 // to find possible regions.
2025 return GetRegionContainingWorldLocation(pGridService, pScopeID, px, py, Constants.MaximumRegionSize);
2026 }
2027 2210
2028 #region NotFoundLocationCache class 2211 #region NotFoundLocationCache class
2029 // A collection of not found locations to make future lookups 'not found' lookups quick. 2212 // A collection of not found locations to make future lookups 'not found' lookups quick.
@@ -2032,162 +2215,131 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2032 // contains that point. A conservitive estimate. 2215 // contains that point. A conservitive estimate.
2033 private class NotFoundLocationCache 2216 private class NotFoundLocationCache
2034 { 2217 {
2035 private struct NotFoundLocation 2218 private Dictionary<ulong, DateTime> m_notFoundLocations = new Dictionary<ulong, DateTime>();
2036 {
2037 public double minX, maxX, minY, maxY;
2038 public DateTime expireTime;
2039 }
2040 private List<NotFoundLocation> m_notFoundLocations = new List<NotFoundLocation>();
2041 public NotFoundLocationCache() 2219 public NotFoundLocationCache()
2042 { 2220 {
2043 } 2221 }
2044 // Add an area to the list of 'not found' places. The area is the snapped region 2222 // just use normal regions handlers and sizes
2045 // area around the added point.
2046 public void Add(double pX, double pY) 2223 public void Add(double pX, double pY)
2047 { 2224 {
2225 ulong psh = (ulong)pX & 0xffffff00ul;
2226 psh <<= 32;
2227 psh |= (ulong)pY & 0xffffff00ul;
2228
2048 lock (m_notFoundLocations) 2229 lock (m_notFoundLocations)
2049 { 2230 m_notFoundLocations[psh] = DateTime.UtcNow + TimeSpan.FromSeconds(30);
2050 if (!LockedContains(pX, pY))
2051 {
2052 NotFoundLocation nfl = new NotFoundLocation();
2053 // A not found location is not found for at least a whole region sized area
2054 nfl.minX = pX - (pX % (double)Constants.RegionSize);
2055 nfl.minY = pY - (pY % (double)Constants.RegionSize);
2056 nfl.maxX = nfl.minX + (double)Constants.RegionSize;
2057 nfl.maxY = nfl.minY + (double)Constants.RegionSize;
2058 nfl.expireTime = DateTime.Now + TimeSpan.FromSeconds(30);
2059 m_notFoundLocations.Add(nfl);
2060 }
2061 }
2062
2063 } 2231 }
2064 // Test to see of this point is in any of the 'not found' areas. 2232 // Test to see of this point is in any of the 'not found' areas.
2065 // Return 'true' if the point is found inside the 'not found' areas. 2233 // Return 'true' if the point is found inside the 'not found' areas.
2066 public bool Contains(double pX, double pY) 2234 public bool Contains(double pX, double pY)
2067 { 2235 {
2068 bool ret = false; 2236 ulong psh = (ulong)pX & 0xffffff00ul;
2237 psh <<= 32;
2238 psh |= (ulong)pY & 0xffffff00ul;
2239
2069 lock (m_notFoundLocations) 2240 lock (m_notFoundLocations)
2070 ret = LockedContains(pX, pY);
2071 return ret;
2072 }
2073 private bool LockedContains(double pX, double pY)
2074 {
2075 bool ret = false;
2076 this.DoExpiration();
2077 foreach (NotFoundLocation nfl in m_notFoundLocations)
2078 { 2241 {
2079 if (pX >= nfl.minX && pX < nfl.maxX && pY >= nfl.minY && pY < nfl.maxY) 2242 if(m_notFoundLocations.ContainsKey(psh))
2080 { 2243 {
2081 ret = true; 2244 if(m_notFoundLocations[psh] > DateTime.UtcNow)
2082 break; 2245 return true;
2246 m_notFoundLocations.Remove(psh);
2083 } 2247 }
2248 return false;
2084 } 2249 }
2085 return ret;
2086 } 2250 }
2251
2087 private void DoExpiration() 2252 private void DoExpiration()
2088 { 2253 {
2089 List<NotFoundLocation> m_toRemove = null; 2254 List<ulong> m_toRemove = new List<ulong>();;
2090 DateTime now = DateTime.Now; 2255 DateTime now = DateTime.UtcNow;
2091 foreach (NotFoundLocation nfl in m_notFoundLocations) 2256 lock (m_notFoundLocations)
2092 { 2257 {
2093 if (nfl.expireTime < now) 2258 foreach (KeyValuePair<ulong, DateTime> kvp in m_notFoundLocations)
2094 { 2259 {
2095 if (m_toRemove == null) 2260 if (kvp.Value < now)
2096 m_toRemove = new List<NotFoundLocation>(); 2261 m_toRemove.Add(kvp.Key);
2097 m_toRemove.Add(nfl); 2262 }
2263
2264 if (m_toRemove.Count > 0)
2265 {
2266 foreach (ulong u in m_toRemove)
2267 m_notFoundLocations.Remove(u);
2268 m_toRemove.Clear();
2098 } 2269 }
2099 }
2100 if (m_toRemove != null)
2101 {
2102 foreach (NotFoundLocation nfl in m_toRemove)
2103 m_notFoundLocations.Remove(nfl);
2104 m_toRemove.Clear();
2105 } 2270 }
2106 } 2271 }
2107 } 2272 }
2273
2108 #endregion // NotFoundLocationCache class 2274 #endregion // NotFoundLocationCache class
2275 #region getregions
2109 private NotFoundLocationCache m_notFoundLocationCache = new NotFoundLocationCache(); 2276 private NotFoundLocationCache m_notFoundLocationCache = new NotFoundLocationCache();
2110 2277
2111 // Given a world position (fractional meter coordinate), get the GridRegion info for 2278 protected GridRegion GetRegionContainingWorldLocation(IGridService pGridService, UUID pScopeID, double px, double py)
2279 {
2280 // Since we don't know how big the regions could be, we have to search a very large area
2281 // to find possible regions.
2282 return GetRegionContainingWorldLocation(pGridService, pScopeID, px, py, Constants.MaximumRegionSize);
2283 }
2284
2285 // Given a world position, get the GridRegion info for
2112 // the region containing that point. 2286 // the region containing that point.
2113 // Someday this should be a method on GridService. 2287 // for compatibility with old grids it does a scan to find large regions
2114 // 'pSizeHint' is the size of the source region but since the destination point can be anywhere 2288 // 0.9 grids to that
2115 // the size of the target region is unknown thus the search area might have to be very large. 2289
2116 // Return 'null' if no such region exists. 2290 protected GridRegion GetRegionContainingWorldLocation(IGridService pGridService, UUID pScopeID,
2117 public GridRegion GetRegionContainingWorldLocation(IGridService pGridService, UUID pScopeID,
2118 double px, double py, uint pSizeHint) 2291 double px, double py, uint pSizeHint)
2119 { 2292 {
2120 m_log.DebugFormat("{0} GetRegionContainingWorldLocation: query, loc=<{1},{2}>", LogHeader, px, py); 2293// m_log.DebugFormat("{0} GetRegionContainingWorldLocation: call, XY=<{1},{2}>", LogHeader, px, py);
2121 GridRegion ret = null; 2294 GridRegion ret = null;
2122 const double fudge = 2.0;
2123 2295
2124 // One problem with this routine is negative results. That is, this can be called lots of times
2125 // for regions that don't exist. m_notFoundLocationCache remembers 'not found' results so they
2126 // will be quick 'not found's next time.
2127 // NotFoundLocationCache is an expiring cache so it will eventually forget about 'not found' and
2128 // thus re-ask the GridService about the location.
2129 if (m_notFoundLocationCache.Contains(px, py)) 2296 if (m_notFoundLocationCache.Contains(px, py))
2130 { 2297 {
2131 m_log.DebugFormat("{0} GetRegionContainingWorldLocation: Not found via cache. loc=<{1},{2}>", LogHeader, px, py); 2298// m_log.DebugFormat("{0} GetRegionContainingWorldLocation: Not found via cache. loc=<{1},{2}>", LogHeader, px, py);
2132 return null; 2299 return null;
2133 } 2300 }
2134 2301
2135 // As an optimization, since most regions will be legacy sized regions (256x256), first try to get 2302 // As an optimization, since most regions will be legacy sized regions (256x256), first try to get
2136 // the region at the appropriate legacy region location. 2303 // the region at the appropriate legacy region location.
2137 uint possibleX = (uint)Math.Floor(px); 2304 // this is all that is needed on 0.9 grids
2138 possibleX -= possibleX % Constants.RegionSize; 2305 uint possibleX = (uint)px & 0xffffff00u;
2139 uint possibleY = (uint)Math.Floor(py); 2306 uint possibleY = (uint)py & 0xffffff00u;
2140 possibleY -= possibleY % Constants.RegionSize;
2141 ret = pGridService.GetRegionByPosition(pScopeID, (int)possibleX, (int)possibleY); 2307 ret = pGridService.GetRegionByPosition(pScopeID, (int)possibleX, (int)possibleY);
2142 if (ret != null) 2308 if (ret != null)
2143 { 2309 {
2144 m_log.DebugFormat("{0} GetRegionContainingWorldLocation: Found region using legacy size. rloc=<{1},{2}>. Rname={3}", 2310// m_log.DebugFormat("{0} GetRegionContainingWorldLocation: Found region using legacy size. rloc=<{1},{2}>. Rname={3}",
2145 LogHeader, possibleX, possibleY, ret.RegionName); 2311// LogHeader, possibleX, possibleY, ret.RegionName);
2312 return ret;
2146 } 2313 }
2147 2314
2148 if (ret == null) 2315 // for 0.8 regions just make a BIG area request. old code whould do it plus 4 more smaller on region open edges
2316 // this is what 0.9 grids now do internally
2317 List<GridRegion> possibleRegions = pGridService.GetRegionRange(pScopeID,
2318 (int)(px - Constants.MaximumRegionSize), (int)(px + 1), // +1 bc left mb not part of range
2319 (int)(py - Constants.MaximumRegionSize), (int)(py + 1));
2320// m_log.DebugFormat("{0} GetRegionContainingWorldLocation: possibleRegions cnt={1}, range={2}",
2321// LogHeader, possibleRegions.Count, range);
2322 if (possibleRegions != null && possibleRegions.Count > 0)
2149 { 2323 {
2150 // If the simple lookup failed, search the larger area for a region that contains this point 2324 // If we found some regions, check to see if the point is within
2151 double range = (double)pSizeHint + fudge; 2325 foreach (GridRegion gr in possibleRegions)
2152 while (ret == null && range <= (Constants.MaximumRegionSize + Constants.RegionSize))
2153 { 2326 {
2154 // Get from the grid service a list of regions that might contain this point. 2327// m_log.DebugFormat("{0} GetRegionContainingWorldLocation: possibleRegion nm={1}, regionLoc=<{2},{3}>, regionSize=<{4},{5}>",
2155 // The region origin will be in the zero direction so only subtract the range. 2328// LogHeader, gr.RegionName, gr.RegionLocX, gr.RegionLocY, gr.RegionSizeX, gr.RegionSizeY);
2156 List<GridRegion> possibleRegions = pGridService.GetRegionRange(pScopeID, 2329 if (px >= (double)gr.RegionLocX && px < (double)(gr.RegionLocX + gr.RegionSizeX)
2157 (int)(px - range), (int)(px),
2158 (int)(py - range), (int)(py));
2159 m_log.DebugFormat("{0} GetRegionContainingWorldLocation: possibleRegions cnt={1}, range={2}",
2160 LogHeader, possibleRegions.Count, range);
2161 if (possibleRegions != null && possibleRegions.Count > 0)
2162 {
2163 // If we found some regions, check to see if the point is within
2164 foreach (GridRegion gr in possibleRegions)
2165 {
2166 m_log.DebugFormat("{0} GetRegionContainingWorldLocation: possibleRegion nm={1}, regionLoc=<{2},{3}>, regionSize=<{4},{5}>",
2167 LogHeader, gr.RegionName, gr.RegionLocX, gr.RegionLocY, gr.RegionSizeX, gr.RegionSizeY);
2168 if (px >= (double)gr.RegionLocX && px < (double)(gr.RegionLocX + gr.RegionSizeX)
2169 && py >= (double)gr.RegionLocY && py < (double)(gr.RegionLocY + gr.RegionSizeY)) 2330 && py >= (double)gr.RegionLocY && py < (double)(gr.RegionLocY + gr.RegionSizeY))
2170 { 2331 {
2171 // Found a region that contains the point 2332 // Found a region that contains the point
2172 ret = gr; 2333 return gr;
2173 m_log.DebugFormat("{0} GetRegionContainingWorldLocation: found. RegionName={1}", LogHeader, ret.RegionName); 2334// m_log.DebugFormat("{0} GetRegionContainingWorldLocation: found. RegionName={1}", LogHeader, ret.RegionName);
2174 break;
2175 }
2176 }
2177 } 2335 }
2178 // Larger search area for next time around if not found
2179 range *= 2;
2180 } 2336 }
2181 } 2337 }
2182 2338
2183 if (ret == null) 2339 // remember this location was not found so we can quickly not find it next time
2184 { 2340 m_notFoundLocationCache.Add(px, py);
2185 // remember this location was not found so we can quickly not find it next time 2341// m_log.DebugFormat("{0} GetRegionContainingWorldLocation: Not found. Remembering loc=<{1},{2}>", LogHeader, px, py);
2186 m_notFoundLocationCache.Add(px, py); 2342 return null;
2187 m_log.DebugFormat("{0} GetRegionContainingWorldLocation: Not found. Remembering loc=<{1},{2}>", LogHeader, px, py);
2188 }
2189
2190 return ret;
2191 } 2343 }
2192 2344
2193 private void InformClientOfNeighbourCompleted(IAsyncResult iar) 2345 private void InformClientOfNeighbourCompleted(IAsyncResult iar)
@@ -2207,81 +2359,65 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2207 /// <param name="a"></param> 2359 /// <param name="a"></param>
2208 /// <param name="regionHandle"></param> 2360 /// <param name="regionHandle"></param>
2209 /// <param name="endPoint"></param> 2361 /// <param name="endPoint"></param>
2210 private void InformClientOfNeighbourAsync(ScenePresence sp, AgentCircuitData a, GridRegion reg, 2362 private void InformClientOfNeighbourAsync(ScenePresence sp, AgentCircuitData agentCircData, GridRegion reg,
2211 IPEndPoint endPoint, bool newAgent) 2363 IPEndPoint endPoint, bool newAgent)
2212 { 2364 {
2213 // Let's wait just a little to give time to originating regions to catch up with closing child agents
2214 // after a cross here
2215 Thread.Sleep(500);
2216 2365
2217 Scene scene = sp.Scene; 2366 if (newAgent)
2218 2367 {
2219 m_log.DebugFormat( 2368 // we may already had lost this sp
2220 "[ENTITY TRANSFER MODULE]: Informing {0} {1} about neighbour {2} {3} at ({4},{5})", 2369 if(sp == null || sp.IsDeleted || sp.ClientView == null) // something bad already happened
2221 sp.Name, sp.UUID, reg.RegionName, endPoint, reg.RegionCoordX, reg.RegionCoordY); 2370 return;
2222 2371
2223 string capsPath = reg.ServerURI + CapsUtil.GetCapsSeedPath(a.CapsPath); 2372 Scene scene = sp.Scene;
2224 2373
2225 string reason = String.Empty; 2374 m_log.DebugFormat(
2375 "[ENTITY TRANSFER MODULE]: Informing {0} {1} about neighbour {2} {3} at ({4},{5})",
2376 sp.Name, sp.UUID, reg.RegionName, endPoint, reg.RegionCoordX, reg.RegionCoordY);
2226 2377
2227 bool regionAccepted = scene.SimulationService.CreateAgent(null, reg, a, (uint)TeleportFlags.Default, out reason); 2378 string capsPath = reg.ServerURI + CapsUtil.GetCapsSeedPath(agentCircData.CapsPath);
2228 2379
2229 if (regionAccepted && newAgent) 2380 string reason = String.Empty;
2230 { 2381
2231 if (m_eqModule != null) 2382 EntityTransferContext ctx = new EntityTransferContext();
2383 bool regionAccepted = scene.SimulationService.CreateAgent(reg, reg, agentCircData, (uint)TeleportFlags.Default, ctx, out reason);
2384
2385 if (regionAccepted)
2232 { 2386 {
2233 #region IP Translation for NAT 2387 // give time for createAgent to finish, since it is async and does grid services access
2234 IClientIPEndpoint ipepClient; 2388 Thread.Sleep(500);
2235 if (sp.ClientView.TryGet(out ipepClient)) 2389
2390 if (m_eqModule != null)
2236 { 2391 {
2237 endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); 2392 if(sp == null || sp.IsDeleted || sp.ClientView == null) // something bad already happened
2238 } 2393 return;
2239 #endregion
2240 2394
2241 m_log.DebugFormat("{0} {1} is sending {2} EnableSimulator for neighbour region {3}(loc=<{4},{5}>,siz=<{6},{7}>) " + 2395 m_log.DebugFormat("{0} {1} is sending {2} EnableSimulator for neighbour region {3}(loc=<{4},{5}>,siz=<{6},{7}>) " +
2242 "and EstablishAgentCommunication with seed cap {8}", LogHeader, 2396 "and EstablishAgentCommunication with seed cap {8}", LogHeader,
2243 scene.RegionInfo.RegionName, sp.Name, 2397 scene.RegionInfo.RegionName, sp.Name,
2244 reg.RegionName, reg.RegionLocX, reg.RegionLocY, reg.RegionSizeX, reg.RegionSizeY , capsPath); 2398 reg.RegionName, reg.RegionLocX, reg.RegionLocY, reg.RegionSizeX, reg.RegionSizeY, capsPath);
2399
2400 m_eqModule.EnableSimulator(reg.RegionHandle, endPoint, sp.UUID, reg.RegionSizeX, reg.RegionSizeY);
2401 m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath, reg.RegionHandle, reg.RegionSizeX, reg.RegionSizeY);
2402 }
2403 else
2404 {
2405 sp.ControllingClient.InformClientOfNeighbour(reg.RegionHandle, endPoint);
2406 // TODO: make Event Queue disablable!
2407 }
2245 2408
2246 m_eqModule.EnableSimulator(reg.RegionHandle, endPoint, sp.UUID, reg.RegionSizeX, reg.RegionSizeY); 2409 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Completed inform {0} {1} about neighbour {2}", sp.Name, sp.UUID, endPoint);
2247 m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath, reg.RegionHandle, reg.RegionSizeX, reg.RegionSizeY);
2248 } 2410 }
2411
2249 else 2412 else
2250 { 2413 {
2251 sp.ControllingClient.InformClientOfNeighbour(reg.RegionHandle, endPoint); 2414 sp.RemoveNeighbourRegion(reg.RegionHandle);
2252 // TODO: make Event Queue disablable! 2415 m_log.WarnFormat(
2416 "[ENTITY TRANSFER MODULE]: Region {0} did not accept {1} {2}: {3}",
2417 reg.RegionName, sp.Name, sp.UUID, reason);
2253 } 2418 }
2254
2255 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Completed inform {0} {1} about neighbour {2}", sp.Name, sp.UUID, endPoint);
2256 } 2419 }
2257 2420
2258 if (!regionAccepted)
2259 m_log.WarnFormat(
2260 "[ENTITY TRANSFER MODULE]: Region {0} did not accept {1} {2}: {3}",
2261 reg.RegionName, sp.Name, sp.UUID, reason);
2262 }
2263
2264 /// <summary>
2265 /// Gets the range considered in view of this megaregion (assuming this is a megaregion).
2266 /// </summary>
2267 /// <remarks>Expressed in 256m units</remarks>
2268 /// <param name='swCorner'></param>
2269 /// <param name='neCorner'></param>
2270 private void GetMegaregionViewRange(out Vector2 swCorner, out Vector2 neCorner)
2271 {
2272 Vector2 extent = Vector2.Zero;
2273
2274 if (m_regionCombinerModule != null)
2275 {
2276 Vector2 megaRegionSize = m_regionCombinerModule.GetSizeOfMegaregion(Scene.RegionInfo.RegionID);
2277 extent.X = (float)Util.WorldToRegionLoc((uint)megaRegionSize.X);
2278 extent.Y = (float)Util.WorldToRegionLoc((uint)megaRegionSize.Y);
2279 }
2280
2281 swCorner.X = Scene.RegionInfo.RegionLocX - 1;
2282 swCorner.Y = Scene.RegionInfo.RegionLocY - 1;
2283 neCorner.X = Scene.RegionInfo.RegionLocX + extent.X;
2284 neCorner.Y = Scene.RegionInfo.RegionLocY + extent.Y;
2285 } 2421 }
2286 2422
2287 /// <summary> 2423 /// <summary>
@@ -2290,98 +2426,42 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2290 /// <param name="avatar"></param> 2426 /// <param name="avatar"></param>
2291 /// <param name="pRegionLocX"></param> 2427 /// <param name="pRegionLocX"></param>
2292 /// <param name="pRegionLocY"></param> 2428 /// <param name="pRegionLocY"></param>
2293 /// <returns></returns> 2429 /// <returns></returns>
2294 protected List<GridRegion> GetNeighbours(ScenePresence avatar, uint pRegionLocX, uint pRegionLocY) 2430 protected List<GridRegion> GetNeighbors(ScenePresence avatar, uint pRegionLocX, uint pRegionLocY)
2295 { 2431 {
2296 Scene pScene = avatar.Scene; 2432 Scene pScene = avatar.Scene;
2297 RegionInfo m_regionInfo = pScene.RegionInfo; 2433 RegionInfo m_regionInfo = pScene.RegionInfo;
2298 List<GridRegion> neighbours; 2434 List<GridRegion> neighbours;
2299 2435
2300 // Leaving this as a "megaregions" computation vs "non-megaregions" computation; it isn't 2436 uint dd = (uint)avatar.RegionViewDistance;
2301 // clear what should be done with a "far view" given that megaregions already extended the
2302 // view to include everything in the megaregion
2303 if (m_regionCombinerModule == null || !m_regionCombinerModule.IsRootForMegaregion(Scene.RegionInfo.RegionID))
2304 {
2305 // The area to check is as big as the current region.
2306 // We presume all adjacent regions are the same size as this region.
2307 uint dd = Math.Max((uint)avatar.Scene.DefaultDrawDistance,
2308 Math.Max(Scene.RegionInfo.RegionSizeX, Scene.RegionInfo.RegionSizeY));
2309 2437
2310 uint startX = Util.RegionToWorldLoc(pRegionLocX) - dd + Constants.RegionSize/2; 2438 // until avatar movement updates client connections, we need to seend at least this current region imediate neighbors
2311 uint startY = Util.RegionToWorldLoc(pRegionLocY) - dd + Constants.RegionSize/2; 2439 uint ddX = Math.Max(dd, Constants.RegionSize);
2440 uint ddY = Math.Max(dd, Constants.RegionSize);
2312 2441
2313 uint endX = Util.RegionToWorldLoc(pRegionLocX) + dd + Constants.RegionSize/2; 2442 ddX--;
2314 uint endY = Util.RegionToWorldLoc(pRegionLocY) + dd + Constants.RegionSize/2; 2443 ddY--;
2315 2444
2316 neighbours 2445 // reference to region edges. Should be avatar position
2317 = avatar.Scene.GridService.GetRegionRange( 2446 uint startX = Util.RegionToWorldLoc(pRegionLocX);
2318 m_regionInfo.ScopeID, (int)startX, (int)endX, (int)startY, (int)endY); 2447 uint endX = startX + m_regionInfo.RegionSizeX;
2319 } 2448 uint startY = Util.RegionToWorldLoc(pRegionLocY);
2320 else 2449 uint endY = startY + m_regionInfo.RegionSizeY;
2321 {
2322 Vector2 swCorner, neCorner;
2323 GetMegaregionViewRange(out swCorner, out neCorner);
2324 2450
2325 neighbours 2451 startX -= ddX;
2326 = pScene.GridService.GetRegionRange( 2452 startY -= ddY;
2327 m_regionInfo.ScopeID, 2453 endX += ddX;
2328 (int)Util.RegionToWorldLoc((uint)swCorner.X), (int)Util.RegionToWorldLoc((uint)neCorner.X), 2454 endY += ddY;
2329 (int)Util.RegionToWorldLoc((uint)swCorner.Y), (int)Util.RegionToWorldLoc((uint)neCorner.Y));
2330 }
2331 2455
2332// neighbours.ForEach( 2456 neighbours
2333// n => 2457 = avatar.Scene.GridService.GetRegionRange(
2334// m_log.DebugFormat( 2458 m_regionInfo.ScopeID, (int)startX, (int)endX, (int)startY, (int)endY);
2335// "[ENTITY TRANSFER MODULE]: Region flags for {0} as seen by {1} are {2}",
2336// n.RegionName, Scene.Name, n.RegionFlags != null ? n.RegionFlags.ToString() : "not present"));
2337 2459
2338 // The r.RegionFlags == null check only needs to be made for simulators before 2015-01-14 (pre 0.8.1). 2460 // The r.RegionFlags == null check only needs to be made for simulators before 2015-01-14 (pre 0.8.1).
2339 neighbours.RemoveAll( 2461 neighbours.RemoveAll( r => r.RegionID == m_regionInfo.RegionID );
2340 r =>
2341 r.RegionID == m_regionInfo.RegionID
2342 || (r.RegionFlags != null && (r.RegionFlags & OpenSim.Framework.RegionFlags.RegionOnline) == 0));
2343 2462
2344 return neighbours; 2463 return neighbours;
2345 } 2464 }
2346
2347 private List<ulong> NewNeighbours(List<ulong> currentNeighbours, List<ulong> previousNeighbours)
2348 {
2349 return currentNeighbours.FindAll(delegate(ulong handle) { return !previousNeighbours.Contains(handle); });
2350 }
2351
2352 // private List<ulong> CommonNeighbours(List<ulong> currentNeighbours, List<ulong> previousNeighbours)
2353 // {
2354 // return currentNeighbours.FindAll(delegate(ulong handle) { return previousNeighbours.Contains(handle); });
2355 // }
2356
2357 private List<ulong> OldNeighbours(List<ulong> currentNeighbours, List<ulong> previousNeighbours)
2358 {
2359 return previousNeighbours.FindAll(delegate(ulong handle) { return !currentNeighbours.Contains(handle); });
2360 }
2361
2362 private List<ulong> NeighbourHandles(List<GridRegion> neighbours)
2363 {
2364 List<ulong> handles = new List<ulong>();
2365 foreach (GridRegion reg in neighbours)
2366 {
2367 handles.Add(reg.RegionHandle);
2368 }
2369 return handles;
2370 }
2371
2372// private void Dump(string msg, List<ulong> handles)
2373// {
2374// m_log.InfoFormat("-------------- HANDLE DUMP ({0}) ---------", msg);
2375// foreach (ulong handle in handles)
2376// {
2377// uint x, y;
2378// Utils.LongToUInts(handle, out x, out y);
2379// x = x / Constants.RegionSize;
2380// y = y / Constants.RegionSize;
2381// m_log.InfoFormat("({0}, {1})", x, y);
2382// }
2383// }
2384
2385 #endregion 2465 #endregion
2386 2466
2387 #region Agent Arrived 2467 #region Agent Arrived
@@ -2395,83 +2475,47 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2395 2475
2396 #region Object Transfers 2476 #region Object Transfers
2397 2477
2398 /// <summary> 2478 public GridRegion GetObjectDestination(SceneObjectGroup grp, Vector3 targetPosition,out Vector3 newpos)
2399 /// Move the given scene object into a new region depending on which region its absolute position has moved
2400 /// into.
2401 ///
2402 /// Using the objects new world location, ask the grid service for a the new region and adjust the prim
2403 /// position to be relative to the new region.
2404 /// </summary>
2405 /// <param name="grp">the scene object that we're crossing</param>
2406 /// <param name="attemptedPosition">the attempted out of region position of the scene object. This position is
2407 /// relative to the region the object currently is in.</param>
2408 /// <param name="silent">if 'true', the deletion of the client from the region is not broadcast to the clients</param>
2409 public void Cross(SceneObjectGroup grp, Vector3 attemptedPosition, bool silent)
2410 { 2479 {
2411 if (grp == null) 2480 newpos = targetPosition;
2412 return;
2413 if (grp.IsDeleted)
2414 return;
2415 2481
2416 Scene scene = grp.Scene; 2482 Scene scene = grp.Scene;
2417 if (scene == null) 2483 if (scene == null)
2418 return; 2484 return null;
2419
2420 if (grp.RootPart.DIE_AT_EDGE)
2421 {
2422 // We remove the object here
2423 try
2424 {
2425 scene.DeleteSceneObject(grp, false);
2426 }
2427 catch (Exception)
2428 {
2429 m_log.Warn("[DATABASE]: exception when trying to remove the prim that crossed the border.");
2430 }
2431 return;
2432 }
2433
2434 // Remember the old group position in case the region lookup fails so position can be restored.
2435 Vector3 oldGroupPosition = grp.RootPart.GroupPosition;
2436 2485
2437 // Compute the absolute position of the object. 2486 int x = (int)targetPosition.X + (int)scene.RegionInfo.WorldLocX;
2438 double objectWorldLocX = (double)scene.RegionInfo.WorldLocX + attemptedPosition.X; 2487 if (targetPosition.X >= 0)
2439 double objectWorldLocY = (double)scene.RegionInfo.WorldLocY + attemptedPosition.Y; 2488 x++;
2489 else
2490 x--;
2440 2491
2441 // Ask the grid service for the region that contains the passed address 2492 int y = (int)targetPosition.Y + (int)scene.RegionInfo.WorldLocY;
2442 GridRegion destination = GetRegionContainingWorldLocation(scene.GridService, scene.RegionInfo.ScopeID, 2493 if (targetPosition.Y >= 0)
2443 objectWorldLocX, objectWorldLocY); 2494 y++;
2495 else
2496 y--;
2444 2497
2445 Vector3 pos = Vector3.Zero; 2498 GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID,x,y);
2446 if (destination != null) 2499 if (neighbourRegion == null)
2447 { 2500 {
2448 // Adjust the object's relative position from the old region (attemptedPosition) 2501 return null;
2449 // to be relative to the new region (pos).
2450 pos = new Vector3( (float)(objectWorldLocX - (double)destination.RegionLocX),
2451 (float)(objectWorldLocY - (double)destination.RegionLocY),
2452 attemptedPosition.Z);
2453 } 2502 }
2454 2503
2455 if (destination == null || !CrossPrimGroupIntoNewRegion(destination, pos, grp, silent)) 2504 float newRegionSizeX = neighbourRegion.RegionSizeX;
2456 { 2505 float newRegionSizeY = neighbourRegion.RegionSizeY;
2457 m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}", grp.UUID); 2506 if (newRegionSizeX == 0)
2458 2507 newRegionSizeX = Constants.RegionSize;
2459 // We are going to move the object back to the old position so long as the old position 2508 if (newRegionSizeY == 0)
2460 // is in the region 2509 newRegionSizeY = Constants.RegionSize;
2461 oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X, 1.0f, (float)(scene.RegionInfo.RegionSizeX - 1));
2462 oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y, 1.0f, (float)(scene.RegionInfo.RegionSizeY - 1));
2463 oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z, 1.0f, Constants.RegionHeight);
2464 2510
2465 grp.AbsolutePosition = oldGroupPosition; 2511 newpos.X = targetPosition.X - (neighbourRegion.RegionLocX - (int)scene.RegionInfo.WorldLocX);
2466 grp.Velocity = Vector3.Zero; 2512 newpos.Y = targetPosition.Y - (neighbourRegion.RegionLocY - (int)scene.RegionInfo.WorldLocY);
2467 if (grp.RootPart.PhysActor != null)
2468 grp.RootPart.PhysActor.CrossingFailure();
2469 2513
2470 if (grp.RootPart.KeyframeMotion != null) 2514 const float enterDistance = 0.2f;
2471 grp.RootPart.KeyframeMotion.CrossingFailure(); 2515 newpos.X = Util.Clamp(newpos.X, enterDistance, newRegionSizeX - enterDistance);
2516 newpos.Y = Util.Clamp(newpos.Y, enterDistance, newRegionSizeY - enterDistance);
2472 2517
2473 grp.ScheduleGroupForFullUpdate(); 2518 return neighbourRegion;
2474 }
2475 } 2519 }
2476 2520
2477 /// <summary> 2521 /// <summary>
@@ -2483,10 +2527,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2483 /// true if the crossing itself was successful, false on failure 2527 /// true if the crossing itself was successful, false on failure
2484 /// FIMXE: we still return true if the crossing object was not successfully deleted from the originating region 2528 /// FIMXE: we still return true if the crossing object was not successfully deleted from the originating region
2485 /// </returns> 2529 /// </returns>
2486 protected bool CrossPrimGroupIntoNewRegion(GridRegion destination, Vector3 newPosition, SceneObjectGroup grp, bool silent) 2530 public bool CrossPrimGroupIntoNewRegion(GridRegion destination, Vector3 newPosition, SceneObjectGroup grp, bool silent, bool removeScripts)
2487 { 2531 {
2488 //m_log.Debug(" >>> CrossPrimGroupIntoNewRegion <<<"); 2532 //m_log.Debug(" >>> CrossPrimGroupIntoNewRegion <<<");
2489 2533
2534 Culture.SetCurrentCulture();
2535
2490 bool successYN = false; 2536 bool successYN = false;
2491 grp.RootPart.ClearUpdateSchedule(); 2537 grp.RootPart.ClearUpdateSchedule();
2492 //int primcrossingXMLmethod = 0; 2538 //int primcrossingXMLmethod = 0;
@@ -2515,7 +2561,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2515 // We remove the object here 2561 // We remove the object here
2516 try 2562 try
2517 { 2563 {
2518 grp.Scene.DeleteSceneObject(grp, silent); 2564 grp.Scene.DeleteSceneObject(grp, silent, removeScripts);
2519 } 2565 }
2520 catch (Exception e) 2566 catch (Exception e)
2521 { 2567 {
@@ -2524,30 +2570,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2524 grp, e); 2570 grp, e);
2525 } 2571 }
2526 } 2572 }
2527/*
2528 * done on caller ( not in attachments crossing for now)
2529 else
2530 {
2531
2532 if (!grp.IsDeleted)
2533 {
2534 PhysicsActor pa = grp.RootPart.PhysActor;
2535 if (pa != null)
2536 {
2537 pa.CrossingFailure();
2538 if (grp.RootPart.KeyframeMotion != null)
2539 {
2540 // moved to KeyframeMotion.CrossingFailure
2541// grp.RootPart.Velocity = Vector3.Zero;
2542 grp.RootPart.KeyframeMotion.CrossingFailure();
2543// grp.SendGroupRootTerseUpdate();
2544 }
2545 }
2546 }
2547
2548 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp);
2549 }
2550 */
2551 } 2573 }
2552 else 2574 else
2553 { 2575 {
@@ -2589,7 +2611,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2589 "[ENTITY TRANSFER MODULE]: Sending attachment {0} to region {1}", 2611 "[ENTITY TRANSFER MODULE]: Sending attachment {0} to region {1}",
2590 clone.UUID, destination.RegionName); 2612 clone.UUID, destination.RegionName);
2591 2613
2592 CrossPrimGroupIntoNewRegion(destination, Vector3.Zero, clone, silent); 2614 CrossPrimGroupIntoNewRegion(destination, Vector3.Zero, clone, silent,true);
2593 } 2615 }
2594 } 2616 }
2595 2617
@@ -2639,7 +2661,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2639 if (Scene.RegionInfo.EstateSettings.IsBanned(so.OwnerID)) 2661 if (Scene.RegionInfo.EstateSettings.IsBanned(so.OwnerID))
2640 { 2662 {
2641 m_log.DebugFormat( 2663 m_log.DebugFormat(
2642 "[ENTITY TRANSFER MODULE]: Denied prim crossing of {0} {1} into {2} for banned avatar {3}", 2664 "[ENTITY TRANSFER MODULE]: Denied prim crossing of {0} {1} into {2} for banned avatar {3}",
2643 so.Name, so.UUID, Scene.Name, so.OwnerID); 2665 so.Name, so.UUID, Scene.Name, so.OwnerID);
2644 2666
2645 return false; 2667 return false;
@@ -2651,7 +2673,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2651 if (!Scene.AddSceneObject(so)) 2673 if (!Scene.AddSceneObject(so))
2652 { 2674 {
2653 m_log.DebugFormat( 2675 m_log.DebugFormat(
2654 "[ENTITY TRANSFER MODULE]: Problem adding scene object {0} {1} into {2} ", 2676 "[ENTITY TRANSFER MODULE]: Problem adding scene object {0} {1} into {2} ",
2655 so.Name, so.UUID, Scene.Name); 2677 so.Name, so.UUID, Scene.Name);
2656 2678
2657 return false; 2679 return false;
@@ -2661,7 +2683,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2661 { 2683 {
2662 // FIXME: It would be better to never add the scene object at all rather than add it and then delete 2684 // FIXME: It would be better to never add the scene object at all rather than add it and then delete
2663 // it 2685 // it
2664 if (!Scene.Permissions.CanObjectEntry(so.UUID, true, so.AbsolutePosition)) 2686 if (!Scene.Permissions.CanObjectEntry(so, true, so.AbsolutePosition))
2665 { 2687 {
2666 // Deny non attachments based on parcel settings 2688 // Deny non attachments based on parcel settings
2667 // 2689 //
@@ -2679,8 +2701,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2679 2701
2680 so.ResumeScripts(); 2702 so.ResumeScripts();
2681 2703
2682 if (so.RootPart.KeyframeMotion != null) 2704 // AddSceneObject already does this and doing it again messes
2683 so.RootPart.KeyframeMotion.UpdateSceneObject(so); 2705 //if (so.RootPart.KeyframeMotion != null)
2706 // so.RootPart.KeyframeMotion.UpdateSceneObject(so);
2684 } 2707 }
2685 2708
2686 return true; 2709 return true;
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
index a3109e0..0a24555 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
@@ -101,7 +101,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
101 /// <returns>true if the agent was not already in transit, false if it was</returns> 101 /// <returns>true if the agent was not already in transit, false if it was</returns>
102 internal bool SetInTransit(UUID id) 102 internal bool SetInTransit(UUID id)
103 { 103 {
104 m_log.DebugFormat("{0} SetInTransit. agent={1}, newState=Preparing", LogHeader, id); 104// m_log.DebugFormat("{0} SetInTransit. agent={1}, newState=Preparing", LogHeader, id);
105 lock (m_agentsInTransit) 105 lock (m_agentsInTransit)
106 { 106 {
107 if (!m_agentsInTransit.ContainsKey(id)) 107 if (!m_agentsInTransit.ContainsKey(id))
@@ -123,7 +123,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
123 /// <exception cref='Exception'>Illegal transitions will throw an Exception</exception> 123 /// <exception cref='Exception'>Illegal transitions will throw an Exception</exception>
124 internal bool UpdateInTransit(UUID id, AgentTransferState newState) 124 internal bool UpdateInTransit(UUID id, AgentTransferState newState)
125 { 125 {
126 m_log.DebugFormat("{0} UpdateInTransit. agent={1}, newState={2}", LogHeader, id, newState); 126 // m_log.DebugFormat("{0} UpdateInTransit. agent={1}, newState={2}", LogHeader, id, newState);
127 127
128 bool transitionOkay = false; 128 bool transitionOkay = false;
129 129
@@ -169,7 +169,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
169 } 169 }
170 else 170 else
171 { 171 {
172 if (newState == AgentTransferState.Cancelling 172 if (newState == AgentTransferState.Cancelling
173 && (oldState == AgentTransferState.Preparing || oldState == AgentTransferState.Transferring)) 173 && (oldState == AgentTransferState.Preparing || oldState == AgentTransferState.Transferring))
174 { 174 {
175 transitionOkay = true; 175 transitionOkay = true;
@@ -181,7 +181,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
181 } 181 }
182 182
183 if (!transitionOkay) 183 if (!transitionOkay)
184 failureMessage 184 failureMessage
185 = string.Format( 185 = string.Format(
186 "Agent with ID {0} is not allowed to move from old transit state {1} to new state {2} in {3}", 186 "Agent with ID {0} is not allowed to move from old transit state {1} to new state {2} in {3}",
187 id, oldState, newState, m_mod.Scene.RegionInfo.RegionName); 187 id, oldState, newState, m_mod.Scene.RegionInfo.RegionName);
@@ -192,7 +192,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
192 m_agentsInTransit[id] = newState; 192 m_agentsInTransit[id] = newState;
193 193
194// m_log.DebugFormat( 194// m_log.DebugFormat(
195// "[ENTITY TRANSFER STATE MACHINE]: Changed agent with id {0} from state {1} to {2} in {3}", 195// "[ENTITY TRANSFER STATE MACHINE]: Changed agent with id {0} from state {1} to {2} in {3}",
196// id, oldState, newState, m_mod.Scene.Name); 196// id, oldState, newState, m_mod.Scene.Name);
197 } 197 }
198 else if (failIfNotOkay) 198 else if (failIfNotOkay)
@@ -204,11 +204,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
204// { 204// {
205// if (oldState != null) 205// if (oldState != null)
206// m_log.DebugFormat( 206// m_log.DebugFormat(
207// "[ENTITY TRANSFER STATE MACHINE]: Ignored change of agent with id {0} from state {1} to {2} in {3}", 207// "[ENTITY TRANSFER STATE MACHINE]: Ignored change of agent with id {0} from state {1} to {2} in {3}",
208// id, oldState, newState, m_mod.Scene.Name); 208// id, oldState, newState, m_mod.Scene.Name);
209// else 209// else
210// m_log.DebugFormat( 210// m_log.DebugFormat(
211// "[ENTITY TRANSFER STATE MACHINE]: Ignored change of agent with id {0} to state {1} in {2} since agent not in transit", 211// "[ENTITY TRANSFER STATE MACHINE]: Ignored change of agent with id {0} to state {1} in {2} since agent not in transit",
212// id, newState, m_mod.Scene.Name); 212// id, newState, m_mod.Scene.Name);
213// } 213// }
214 } 214 }
@@ -247,32 +247,32 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
247 { 247 {
248 AgentTransferState state = m_agentsInTransit[id]; 248 AgentTransferState state = m_agentsInTransit[id];
249 249
250 if (state == AgentTransferState.Transferring || state == AgentTransferState.ReceivedAtDestination) 250// if (state == AgentTransferState.Transferring || state == AgentTransferState.ReceivedAtDestination)
251 { 251// {
252 // FIXME: For now, we allow exit from any state since a thrown exception in teleport is now guranteed 252 // FIXME: For now, we allow exit from any state since a thrown exception in teleport is now guranteed
253 // to be handled properly - ResetFromTransit() could be invoked at any step along the process 253 // to be handled properly - ResetFromTransit() could be invoked at any step along the process
254 m_log.WarnFormat( 254// m_log.WarnFormat(
255 "[ENTITY TRANSFER STATE MACHINE]: Agent with ID {0} should not exit directly from state {1}, should go to {2} state first in {3}", 255// "[ENTITY TRANSFER STATE MACHINE]: Agent with ID {0} should not exit directly from state {1}, should go to {2} state first in {3}",
256 id, state, AgentTransferState.CleaningUp, m_mod.Scene.RegionInfo.RegionName); 256// id, state, AgentTransferState.CleaningUp, m_mod.Scene.RegionInfo.RegionName);
257 257
258// throw new Exception( 258// throw new Exception(
259// "Agent with ID {0} cannot exit directly from state {1}, it must go to {2} state first", 259// "Agent with ID {0} cannot exit directly from state {1}, it must go to {2} state first",
260// state, AgentTransferState.CleaningUp); 260// state, AgentTransferState.CleaningUp);
261 } 261// }
262 262
263 m_agentsInTransit.Remove(id); 263 m_agentsInTransit.Remove(id);
264 264
265 m_log.DebugFormat( 265// m_log.DebugFormat(
266 "[ENTITY TRANSFER STATE MACHINE]: Agent {0} cleared from transit in {1}", 266// "[ENTITY TRANSFER STATE MACHINE]: Agent {0} cleared from transit in {1}",
267 id, m_mod.Scene.RegionInfo.RegionName); 267// id, m_mod.Scene.RegionInfo.RegionName);
268 268
269 return true; 269 return true;
270 } 270 }
271 } 271 }
272 272
273 m_log.WarnFormat( 273// m_log.WarnFormat(
274 "[ENTITY TRANSFER STATE MACHINE]: Agent {0} requested to clear from transit in {1} but was already cleared", 274// "[ENTITY TRANSFER STATE MACHINE]: Agent {0} requested to clear from transit in {1} but was already cleared",
275 id, m_mod.Scene.RegionInfo.RegionName); 275// id, m_mod.Scene.RegionInfo.RegionName);
276 276
277 return false; 277 return false;
278 } 278 }
@@ -281,7 +281,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
281 { 281 {
282 if (!m_mod.WaitForAgentArrivedAtDestination) 282 if (!m_mod.WaitForAgentArrivedAtDestination)
283 return true; 283 return true;
284 284
285 lock (m_agentsInTransit) 285 lock (m_agentsInTransit)
286 { 286 {
287 AgentTransferState? currentState = GetAgentTransferState(id); 287 AgentTransferState? currentState = GetAgentTransferState(id);
@@ -299,7 +299,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
299 id, m_mod.Scene.RegionInfo.RegionName, currentState)); 299 id, m_mod.Scene.RegionInfo.RegionName, currentState));
300 } 300 }
301 301
302 int count = 200; 302 int count = 400;
303 303
304 // There should be no race condition here since no other code should be removing the agent transfer or 304 // There should be no race condition here since no other code should be removing the agent transfer or
305 // changing the state to another other than Transferring => ReceivedAtDestination. 305 // changing the state to another other than Transferring => ReceivedAtDestination.
@@ -354,4 +354,4 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
354 } 354 }
355 } 355 }
356 } 356 }
357} \ No newline at end of file 357}
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
index fa23590..56c654f 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
@@ -95,8 +95,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
95 95
96 foreach (AvatarAttachment att in a.GetAttachments()) 96 foreach (AvatarAttachment att in a.GetAttachments())
97 { 97 {
98 InventoryItemBase item = new InventoryItemBase(att.ItemID, account.PrincipalID); 98 InventoryItemBase item = Scene.InventoryService.GetItem(account.PrincipalID, att.ItemID);
99 item = Scene.InventoryService.GetItem(item);
100 if (item != null) 99 if (item != null)
101 a.SetAttachment(att.AttachPoint, att.ItemID, item.AssetID); 100 a.SetAttachment(att.AttachPoint, att.ItemID, item.AssetID);
102 else 101 else
@@ -161,10 +160,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
161 scene.RegisterModuleInterface<IUserAgentVerificationModule>(this); 160 scene.RegisterModuleInterface<IUserAgentVerificationModule>(this);
162 //scene.EventManager.OnIncomingSceneObject += OnIncomingSceneObject; 161 //scene.EventManager.OnIncomingSceneObject += OnIncomingSceneObject;
163 162
164 m_incomingSceneObjectEngine 163 m_incomingSceneObjectEngine
165 = new JobEngine( 164 = new JobEngine(
166 string.Format("HG Incoming Scene Object Engine ({0})", scene.Name), 165 string.Format("HG Incoming Scene Object Engine ({0})", scene.Name),
167 "HG INCOMING SCENE OBJECT ENGINE"); 166 "HG INCOMING SCENE OBJECT ENGINE", 30000);
168 167
169 StatsManager.RegisterStat( 168 StatsManager.RegisterStat(
170 new Stat( 169 new Stat(
@@ -239,13 +238,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
239 return region; 238 return region;
240 } 239 }
241 240
242 protected override bool NeedsClosing(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, GridRegion reg) 241 protected override bool NeedsClosing(GridRegion reg, bool OutViewRange)
243 { 242 {
244 if (base.NeedsClosing(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) 243 if (OutViewRange)
245 return true; 244 return true;
246 245
247 int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, reg.RegionID); 246 int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, reg.RegionID);
248 if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Framework.RegionFlags.Hyperlink) != 0) 247 if (flags == -1 || (flags & (int)OpenSim.Framework.RegionFlags.Hyperlink) != 0)
249 return true; 248 return true;
250 249
251 return false; 250 return false;
@@ -263,7 +262,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
263 } 262 }
264 } 263 }
265 264
266 protected override bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout) 265 protected override bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, EntityTransferContext ctx, out string reason, out bool logout)
267 { 266 {
268 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: CreateAgent {0} {1}", reg.ServerURI, finalDestination.ServerURI); 267 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: CreateAgent {0} {1}", reg.ServerURI, finalDestination.ServerURI);
269 reason = string.Empty; 268 reason = string.Empty;
@@ -273,7 +272,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
273 { 272 {
274 // this user is going to another grid 273 // this user is going to another grid
275 // for local users, check if HyperGrid teleport is allowed, based on user level 274 // for local users, check if HyperGrid teleport is allowed, based on user level
276 if (Scene.UserManagementModule.IsLocalGridUser(sp.UUID) && sp.UserLevel < m_levelHGTeleport) 275 if (Scene.UserManagementModule.IsLocalGridUser(sp.UUID) && sp.GodController.UserLevel < m_levelHGTeleport)
277 { 276 {
278 m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: Unable to HG teleport agent due to insufficient UserLevel."); 277 m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: Unable to HG teleport agent due to insufficient UserLevel.");
279 reason = "Hypergrid teleport not allowed"; 278 reason = "Hypergrid teleport not allowed";
@@ -292,7 +291,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
292 291
293 GridRegion source = new GridRegion(Scene.RegionInfo); 292 GridRegion source = new GridRegion(Scene.RegionInfo);
294 source.RawServerURI = m_GatekeeperURI; 293 source.RawServerURI = m_GatekeeperURI;
295 294
296 bool success = connector.LoginAgentToGrid(source, agentCircuit, reg, finalDestination, false, out reason); 295 bool success = connector.LoginAgentToGrid(source, agentCircuit, reg, finalDestination, false, out reason);
297 logout = success; // flag for later logout from this grid; this is an HG TP 296 logout = success; // flag for later logout from this grid; this is an HG TP
298 297
@@ -308,7 +307,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
308 } 307 }
309 } 308 }
310 309
311 return base.CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout); 310 return base.CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, ctx, out reason, out logout);
311 }
312
313 public override void TriggerTeleportHome(UUID id, IClientAPI client)
314 {
315 TeleportHome(id, client);
312 } 316 }
313 317
314 protected override bool ValidateGenericConditions(ScenePresence sp, GridRegion reg, GridRegion finalDestination, uint teleportFlags, out string reason) 318 protected override bool ValidateGenericConditions(ScenePresence sp, GridRegion reg, GridRegion finalDestination, uint teleportFlags, out string reason)
@@ -328,7 +332,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
328 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: RestrictAppearanceAbroad is ON. Checking generic appearance"); 332 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: RestrictAppearanceAbroad is ON. Checking generic appearance");
329 333
330 // Check wearables 334 // Check wearables
331 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++) 335 for (int i = 0; i < sp.Appearance.Wearables.Length ; i++)
332 { 336 {
333 for (int j = 0; j < sp.Appearance.Wearables[i].Count; j++) 337 for (int j = 0; j < sp.Appearance.Wearables[i].Count; j++)
334 { 338 {
@@ -337,13 +341,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
337 341
338 bool found = false; 342 bool found = false;
339 foreach (AvatarAppearance a in ExportedAppearance) 343 foreach (AvatarAppearance a in ExportedAppearance)
340 if (a.Wearables[i] != null) 344 if (i < a.Wearables.Length && a.Wearables[i] != null)
341 { 345 {
342 found = true; 346 found = true;
343 break; 347 break;
344 } 348 }
345 349
346 if (!found) 350 if (!found)
347 { 351 {
348 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Wearable not allowed to go outside {0}", i); 352 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Wearable not allowed to go outside {0}", i);
349 return false; 353 return false;
@@ -351,7 +355,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
351 355
352 found = false; 356 found = false;
353 foreach (AvatarAppearance a in ExportedAppearance) 357 foreach (AvatarAppearance a in ExportedAppearance)
354 if (sp.Appearance.Wearables[i][j].AssetID == a.Wearables[i][j].AssetID) 358 if (i < a.Wearables.Length && sp.Appearance.Wearables[i][j].AssetID == a.Wearables[i][j].AssetID)
355 { 359 {
356 found = true; 360 found = true;
357 break; 361 break;
@@ -412,7 +416,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
412 // // Rez needed npc attachments 416 // // Rez needed npc attachments
413 // Scene.AttachmentsModule.RezAttachments(sp); 417 // Scene.AttachmentsModule.RezAttachments(sp);
414 418
415 419
416 // IAvatarFactoryModule module = Scene.RequestModuleInterface<IAvatarFactoryModule>(); 420 // IAvatarFactoryModule module = Scene.RequestModuleInterface<IAvatarFactoryModule>();
417 // //module.SendAppearance(sp.UUID); 421 // //module.SendAppearance(sp.UUID);
418 // module.RequestRebake(sp, false); 422 // module.RequestRebake(sp, false);
@@ -429,11 +433,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
429 // return base.UpdateAgent(reg, finalDestination, agentData, sp); 433 // return base.UpdateAgent(reg, finalDestination, agentData, sp);
430 //} 434 //}
431 435
432 public override void TriggerTeleportHome(UUID id, IClientAPI client) 436
433 {
434 TeleportHome(id, client);
435 }
436
437 public override bool TeleportHome(UUID id, IClientAPI client) 437 public override bool TeleportHome(UUID id, IClientAPI client)
438 { 438 {
439 m_log.DebugFormat( 439 m_log.DebugFormat(
@@ -449,7 +449,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
449 } 449 }
450 450
451 // Foreign user wants to go home 451 // Foreign user wants to go home
452 // 452 //
453 AgentCircuitData aCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode); 453 AgentCircuitData aCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode);
454 if (aCircuit == null || (aCircuit != null && !aCircuit.ServiceURLs.ContainsKey("HomeURI"))) 454 if (aCircuit == null || (aCircuit != null && !aCircuit.ServiceURLs.ContainsKey("HomeURI")))
455 { 455 {
@@ -470,7 +470,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
470 { 470 {
471 m_log.Debug("[HG ENTITY TRANSFER MODULE]: GetHomeRegion call failed ", e); 471 m_log.Debug("[HG ENTITY TRANSFER MODULE]: GetHomeRegion call failed ", e);
472 } 472 }
473 473
474 if (finalDestination == null) 474 if (finalDestination == null)
475 { 475 {
476 client.SendTeleportFailed("Your home region could not be found"); 476 client.SendTeleportFailed("Your home region could not be found");
@@ -487,13 +487,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
487 } 487 }
488 488
489 GridRegion homeGatekeeper = MakeRegion(aCircuit); 489 GridRegion homeGatekeeper = MakeRegion(aCircuit);
490 490
491 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: teleporting user {0} {1} home to {2} via {3}:{4}", 491 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: teleporting user {0} {1} home to {2} via {3}:{4}",
492 aCircuit.firstname, aCircuit.lastname, finalDestination.RegionName, homeGatekeeper.ServerURI, homeGatekeeper.RegionName); 492 aCircuit.firstname, aCircuit.lastname, finalDestination.RegionName, homeGatekeeper.ServerURI, homeGatekeeper.RegionName);
493 493
494 DoTeleport( 494 DoTeleport(sp, homeGatekeeper, finalDestination, position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
495 sp, homeGatekeeper, finalDestination,
496 position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
497 return true; 495 return true;
498 } 496 }
499 497
@@ -505,7 +503,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
505 /// <param name="position"></param> 503 /// <param name="position"></param>
506 public override void RequestTeleportLandmark(IClientAPI remoteClient, AssetLandmark lm) 504 public override void RequestTeleportLandmark(IClientAPI remoteClient, AssetLandmark lm)
507 { 505 {
508 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Teleporting agent via landmark to {0} region {1} position {2}", 506 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Teleporting agent via landmark to {0} region {1} position {2}",
509 (lm.Gatekeeper == string.Empty) ? "local" : lm.Gatekeeper, lm.RegionID, lm.Position); 507 (lm.Gatekeeper == string.Empty) ? "local" : lm.Gatekeeper, lm.RegionID, lm.Position);
510 508
511 if (lm.Gatekeeper == string.Empty) 509 if (lm.Gatekeeper == string.Empty)
@@ -523,7 +521,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
523 remoteClient, info.RegionHandle, lm.Position, 521 remoteClient, info.RegionHandle, lm.Position,
524 Vector3.Zero, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark)); 522 Vector3.Zero, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark));
525 } 523 }
526 else 524 else
527 { 525 {
528 // Foreign region 526 // Foreign region
529 GatekeeperServiceConnector gConn = new GatekeeperServiceConnector(); 527 GatekeeperServiceConnector gConn = new GatekeeperServiceConnector();
@@ -583,7 +581,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
583 jobsRemoved, commonIdToRemove, jobsToReinsert.Count); 581 jobsRemoved, commonIdToRemove, jobsToReinsert.Count);
584 582
585 if (jobsToReinsert.Count > 0) 583 if (jobsToReinsert.Count > 0)
586 { 584 {
587 foreach (JobEngine.Job jobToReinsert in jobsToReinsert) 585 foreach (JobEngine.Job jobToReinsert in jobsToReinsert)
588 m_incomingSceneObjectEngine.QueueJob(jobToReinsert); 586 m_incomingSceneObjectEngine.QueueJob(jobToReinsert);
589 } 587 }
@@ -613,16 +611,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
613 if (aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("AssetServerURI")) 611 if (aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("AssetServerURI"))
614 { 612 {
615 m_incomingSceneObjectEngine.QueueJob( 613 m_incomingSceneObjectEngine.QueueJob(
616 string.Format("HG UUID Gather for attachment {0} for {1}", so.Name, aCircuit.Name), 614 string.Format("HG UUID Gather for attachment {0} for {1}", so.Name, aCircuit.Name),
617 () => 615 () =>
618 { 616 {
619 string url = aCircuit.ServiceURLs["AssetServerURI"].ToString(); 617 string url = aCircuit.ServiceURLs["AssetServerURI"].ToString();
620 // m_log.DebugFormat( 618 // m_log.DebugFormat(
621 // "[HG ENTITY TRANSFER MODULE]: Incoming attachment {0} for HG user {1} with asset service {2}", 619 // "[HG ENTITY TRANSFER MODULE]: Incoming attachment {0} for HG user {1} with asset service {2}",
622 // so.Name, so.AttachedAvatar, url); 620 // so.Name, so.AttachedAvatar, url);
623 621
624 IDictionary<UUID, sbyte> ids = new Dictionary<UUID, sbyte>(); 622 IDictionary<UUID, sbyte> ids = new Dictionary<UUID, sbyte>();
625 HGUuidGatherer uuidGatherer 623 HGUuidGatherer uuidGatherer
626 = new HGUuidGatherer(Scene.AssetService, url, ids); 624 = new HGUuidGatherer(Scene.AssetService, url, ids);
627 uuidGatherer.AddForInspection(so); 625 uuidGatherer.AddForInspection(so);
628 626
@@ -648,7 +646,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
648 RemoveIncomingSceneObjectJobs(so.OwnerID.ToString()); 646 RemoveIncomingSceneObjectJobs(so.OwnerID.ToString());
649 647
650 return; 648 return;
651 } 649 }
652 } 650 }
653 651
654 // m_log.DebugFormat( 652 // m_log.DebugFormat(
@@ -659,7 +657,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
659 { 657 {
660 int tickStart = Util.EnvironmentTickCount(); 658 int tickStart = Util.EnvironmentTickCount();
661 659
662 uuidGatherer.FetchAsset(kvp.Key); 660 uuidGatherer.FetchAsset(kvp.Key);
663 661
664 int ticksElapsed = Util.EnvironmentTickCountSubtract(tickStart); 662 int ticksElapsed = Util.EnvironmentTickCountSubtract(tickStart);
665 663
@@ -672,15 +670,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
672 RemoveIncomingSceneObjectJobs(so.OwnerID.ToString()); 670 RemoveIncomingSceneObjectJobs(so.OwnerID.ToString());
673 671
674 return; 672 return;
675 } 673 }
676 } 674 }
677 675
678 base.HandleIncomingSceneObject(so, newPosition); 676 base.HandleIncomingSceneObject(so, newPosition);
679 677
680 // m_log.DebugFormat( 678 // m_log.DebugFormat(
681 // "[HG ENTITY TRANSFER MODULE]: Completed incoming attachment {0} for HG user {1} with asset server {2}", 679 // "[HG ENTITY TRANSFER MODULE]: Completed incoming attachment {0} for HG user {1} with asset server {2}",
682 // so.Name, so.OwnerID, url); 680 // so.Name, so.OwnerID, url);
683 }, 681 },
684 so.OwnerID.ToString()); 682 so.OwnerID.ToString());
685 } 683 }
686 } 684 }
@@ -700,7 +698,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
700 string url = aCircuit.ServiceURLs["HomeURI"].ToString(); 698 string url = aCircuit.ServiceURLs["HomeURI"].ToString();
701 IUserAgentService security = new UserAgentServiceConnector(url); 699 IUserAgentService security = new UserAgentServiceConnector(url);
702 return security.VerifyClient(aCircuit.SessionID, token); 700 return security.VerifyClient(aCircuit.SessionID, token);
703 } 701 }
704 else 702 else
705 { 703 {
706 m_log.DebugFormat( 704 m_log.DebugFormat(
@@ -748,7 +746,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
748 GridRegion region = new GridRegion(); 746 GridRegion region = new GridRegion();
749 747
750 Uri uri = null; 748 Uri uri = null;
751 if (!aCircuit.ServiceURLs.ContainsKey("HomeURI") || 749 if (!aCircuit.ServiceURLs.ContainsKey("HomeURI") ||
752 (aCircuit.ServiceURLs.ContainsKey("HomeURI") && !Uri.TryCreate(aCircuit.ServiceURLs["HomeURI"].ToString(), UriKind.Absolute, out uri))) 750 (aCircuit.ServiceURLs.ContainsKey("HomeURI") && !Uri.TryCreate(aCircuit.ServiceURLs["HomeURI"].ToString(), UriKind.Absolute, out uri)))
753 return null; 751 return null;
754 752
@@ -760,4 +758,4 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
760 return region; 758 return region;
761 } 759 }
762 } 760 }
763} \ No newline at end of file 761}
diff --git a/OpenSim/Region/CoreModules/Framework/InterfaceCommander/Commander.cs b/OpenSim/Region/CoreModules/Framework/InterfaceCommander/Commander.cs
index b5a4005..63dbb19 100644
--- a/OpenSim/Region/CoreModules/Framework/InterfaceCommander/Commander.cs
+++ b/OpenSim/Region/CoreModules/Framework/InterfaceCommander/Commander.cs
@@ -41,34 +41,34 @@ namespace OpenSim.Region.CoreModules.Framework.InterfaceCommander
41 public class Commander : ICommander 41 public class Commander : ICommander
42 { 42 {
43 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 43 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
44 44
45 /// <value> 45 /// <value>
46 /// Used in runtime class generation 46 /// Used in runtime class generation
47 /// </summary> 47 /// </summary>
48 private string m_generatedApiClassName; 48 private string m_generatedApiClassName;
49 49
50 public string Name 50 public string Name
51 { 51 {
52 get { return m_name; } 52 get { return m_name; }
53 } 53 }
54 private string m_name; 54 private string m_name;
55 55
56 public string Help 56 public string Help
57 { 57 {
58 get 58 get
59 { 59 {
60 StringBuilder sb = new StringBuilder(); 60 StringBuilder sb = new StringBuilder();
61 61
62 sb.AppendLine("=== " + m_name + " ==="); 62 sb.AppendLine("=== " + m_name + " ===");
63 63
64 foreach (ICommand com in m_commands.Values) 64 foreach (ICommand com in m_commands.Values)
65 { 65 {
66 sb.AppendLine("* " + Name + " " + com.Name + " - " + com.Help); 66 sb.AppendLine("* " + Name + " " + com.Name + " - " + com.Help);
67 } 67 }
68 68
69 return sb.ToString(); 69 return sb.ToString();
70 } 70 }
71 } 71 }
72 72
73 /// <summary> 73 /// <summary>
74 /// Constructor 74 /// Constructor
@@ -78,7 +78,7 @@ namespace OpenSim.Region.CoreModules.Framework.InterfaceCommander
78 { 78 {
79 m_name = name; 79 m_name = name;
80 m_generatedApiClassName = m_name[0].ToString().ToUpper(); 80 m_generatedApiClassName = m_name[0].ToString().ToUpper();
81 81
82 if (m_name.Length > 1) 82 if (m_name.Length > 1)
83 m_generatedApiClassName += m_name.Substring(1); 83 m_generatedApiClassName += m_name.Substring(1);
84 } 84 }
@@ -87,7 +87,7 @@ namespace OpenSim.Region.CoreModules.Framework.InterfaceCommander
87 { 87 {
88 get { return m_commands; } 88 get { return m_commands; }
89 } 89 }
90 private Dictionary<string, ICommand> m_commands = new Dictionary<string, ICommand>(); 90 private Dictionary<string, ICommand> m_commands = new Dictionary<string, ICommand>();
91 91
92 #region ICommander Members 92 #region ICommander Members
93 93
@@ -162,7 +162,7 @@ namespace OpenSim.Region.CoreModules.Framework.InterfaceCommander
162 { 162 {
163 if (function != "help") 163 if (function != "help")
164 Console.WriteLine("ERROR: Invalid command - No such command exists"); 164 Console.WriteLine("ERROR: Invalid command - No such command exists");
165 165
166 Console.Write(Help); 166 Console.Write(Help);
167 } 167 }
168 } 168 }
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
index f54298c..51ae217 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
@@ -178,7 +178,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
178 { 178 {
179 UUID uuid = UUID.Zero; 179 UUID uuid = UUID.Zero;
180 UUID.TryParse(meta.CreatorID, out uuid); 180 UUID.TryParse(meta.CreatorID, out uuid);
181 UserAccount creator = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, uuid); 181 UserAccount creator = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, uuid);
182 if (creator != null) 182 if (creator != null)
183 meta.CreatorID = m_HomeURI + ";" + creator.FirstName + " " + creator.LastName; 183 meta.CreatorID = m_HomeURI + ";" + creator.FirstName + " " + creator.LastName;
184 } 184 }
@@ -300,8 +300,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
300 { 300 {
301 m_log.Error( 301 m_log.Error(
302 string.Format( 302 string.Format(
303 "[HG ASSET MAPPER]: Failed to post asset {0} (type {1}, length {2}) referenced from {3} to {4} with exception ", 303 "[HG ASSET MAPPER]: Failed to post asset {0} (type {1}, length {2}) referenced from {3} to {4} with exception ",
304 asset.ID, asset.Type, asset.Data.Length, assetID, userAssetURL), 304 asset.ID, asset.Type, asset.Data.Length, assetID, userAssetURL),
305 e); 305 e);
306 306
307 // For debugging purposes for now we will continue to throw the exception up the stack as was already happening. However, after 307 // For debugging purposes for now we will continue to throw the exception up the stack as was already happening. However, after
@@ -315,7 +315,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
315 else 315 else
316 { 316 {
317 m_log.DebugFormat( 317 m_log.DebugFormat(
318 "[HG ASSET MAPPER]: Didn't post asset {0} referenced from {1} because it already exists in asset server {2}", 318 "[HG ASSET MAPPER]: Didn't post asset {0} referenced from {1} because it already exists in asset server {2}",
319 uuid, assetID, userAssetURL); 319 uuid, assetID, userAssetURL);
320 } 320 }
321 } 321 }
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
index 582b267..ba3a7c9 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
@@ -91,9 +91,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
91 if (name == Name) 91 if (name == Name)
92 { 92 {
93 m_Enabled = true; 93 m_Enabled = true;
94 94
95 InitialiseCommon(source); 95 InitialiseCommon(source);
96 96
97 m_log.InfoFormat("[HG INVENTORY ACCESS MODULE]: {0} enabled.", Name); 97 m_log.InfoFormat("[HG INVENTORY ACCESS MODULE]: {0} enabled.", Name);
98 98
99 IConfig thisModuleConfig = source.Configs["HGInventoryAccessModule"]; 99 IConfig thisModuleConfig = source.Configs["HGInventoryAccessModule"];
@@ -117,7 +117,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
117 m_log.Warn("[HG INVENTORY ACCESS MODULE]: HGInventoryAccessModule configs not found. ProfileServerURI not set!"); 117 m_log.Warn("[HG INVENTORY ACCESS MODULE]: HGInventoryAccessModule configs not found. ProfileServerURI not set!");
118 118
119 m_bypassPermissions = !Util.GetConfigVarFromSections<bool>(source, "serverside_object_permissions", 119 m_bypassPermissions = !Util.GetConfigVarFromSections<bool>(source, "serverside_object_permissions",
120 new string[] { "Startup", "Permissions" }, true); 120 new string[] { "Startup", "Permissions" }, true);
121 121
122 } 122 }
123 } 123 }
@@ -209,7 +209,14 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
209 } 209 }
210 } 210 }
211 211
212 public void PostInventoryAsset(UUID avatarID, AssetType type, UUID assetID, string name, int userlevel) 212 private void PostInventoryAsset(InventoryItemBase item, int userlevel)
213 {
214 InventoryFolderBase f = m_Scene.InventoryService.GetFolderForType(item.Owner, FolderType.Trash);
215 if (f == null || (f != null && item.Folder != f.ID))
216 PostInventoryAsset(item.Owner, (AssetType)item.AssetType, item.AssetID, item.Name, userlevel);
217 }
218
219 private void PostInventoryAsset(UUID avatarID, AssetType type, UUID assetID, string name, int userlevel)
213 { 220 {
214 if (type == AssetType.Link) 221 if (type == AssetType.Link)
215 return; 222 return;
@@ -241,26 +248,34 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
241 } 248 }
242 249
243 250
244 /// 251 ///
245 /// CapsUpdateInventoryItemAsset 252 /// CapsUpdateInventoryItemAsset
246 /// 253 ///
247 public override UUID CapsUpdateInventoryItemAsset(IClientAPI remoteClient, UUID itemID, byte[] data) 254 public override UUID CapsUpdateInventoryItemAsset(IClientAPI remoteClient, UUID itemID, byte[] data)
248 { 255 {
249 UUID newAssetID = base.CapsUpdateInventoryItemAsset(remoteClient, itemID, data); 256 UUID newAssetID = base.CapsUpdateInventoryItemAsset(remoteClient, itemID, data);
250 257
251 PostInventoryAsset(remoteClient.AgentId, AssetType.Unknown, newAssetID, "", 0); 258 // We need to construct this here to satisfy the calling convention.
259 // Better this in two places than five formal params in all others.
260 InventoryItemBase item = new InventoryItemBase();
261 item.Owner = remoteClient.AgentId;
262 item.AssetType = (int)AssetType.Unknown;
263 item.AssetID = newAssetID;
264 item.Name = String.Empty;
265
266 PostInventoryAsset(item, 0);
252 267
253 return newAssetID; 268 return newAssetID;
254 } 269 }
255 270
256 /// 271 ///
257 /// UpdateInventoryItemAsset 272 /// UpdateInventoryItemAsset
258 /// 273 ///
259 public override bool UpdateInventoryItemAsset(UUID ownerID, InventoryItemBase item, AssetBase asset) 274 public override bool UpdateInventoryItemAsset(UUID ownerID, InventoryItemBase item, AssetBase asset)
260 { 275 {
261 if (base.UpdateInventoryItemAsset(ownerID, item, asset)) 276 if (base.UpdateInventoryItemAsset(ownerID, item, asset))
262 { 277 {
263 PostInventoryAsset(ownerID, (AssetType)asset.Type, asset.FullID, asset.Name, 0); 278 PostInventoryAsset(item, 0);
264 return true; 279 return true;
265 } 280 }
266 281
@@ -273,25 +288,45 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
273 protected override void ExportAsset(UUID agentID, UUID assetID) 288 protected override void ExportAsset(UUID agentID, UUID assetID)
274 { 289 {
275 if (!assetID.Equals(UUID.Zero)) 290 if (!assetID.Equals(UUID.Zero))
276 PostInventoryAsset(agentID, AssetType.Unknown, assetID, "", 0); 291 {
292 InventoryItemBase item = new InventoryItemBase();
293 item.Owner = agentID;
294 item.AssetType = (int)AssetType.Unknown;
295 item.AssetID = assetID;
296 item.Name = String.Empty;
297
298 PostInventoryAsset(item, 0);
299 }
277 else 300 else
301 {
278 m_log.Debug("[HGScene]: Scene.Inventory did not create asset"); 302 m_log.Debug("[HGScene]: Scene.Inventory did not create asset");
303 }
279 } 304 }
280 305
281 /// 306 ///
282 /// RezObject 307 /// RezObject
283 /// 308 ///
284 public override SceneObjectGroup RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart, 309 // compatibility do not use
285 UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, 310 public override SceneObjectGroup RezObject(
286 bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) 311 IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart,
312 UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
313 bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
314 {
315 return RezObject(remoteClient, itemID, UUID.Zero, RayEnd, RayStart,
316 RayTargetID, BypassRayCast, RayEndIsIntersection,
317 RezSelected, RemoveItem, fromTaskID, attachment);
318 }
319
320 public override SceneObjectGroup RezObject(IClientAPI remoteClient, UUID itemID,
321 UUID groupID, Vector3 RayEnd, Vector3 RayStart,
322 UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
323 bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
287 { 324 {
288 m_log.DebugFormat("[HGScene]: RezObject itemID={0} fromTaskID={1}", itemID, fromTaskID); 325 //m_log.DebugFormat("[HGScene]: RezObject itemID={0} fromTaskID={1}", itemID, fromTaskID);
289 326
290 //if (fromTaskID.Equals(UUID.Zero)) 327 //if (fromTaskID.Equals(UUID.Zero))
291 //{ 328 //{
292 InventoryItemBase item = new InventoryItemBase(itemID); 329 InventoryItemBase item = m_Scene.InventoryService.GetItem(remoteClient.AgentId, itemID);
293 item.Owner = remoteClient.AgentId;
294 item = m_Scene.InventoryService.GetItem(item);
295 //if (item == null) 330 //if (item == null)
296 //{ // Fetch the item 331 //{ // Fetch the item
297 // item = new InventoryItemBase(); 332 // item = new InventoryItemBase();
@@ -308,7 +343,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
308 //} 343 //}
309 344
310 // OK, we're done fetching. Pass it up to the default RezObject 345 // OK, we're done fetching. Pass it up to the default RezObject
311 SceneObjectGroup sog = base.RezObject(remoteClient, itemID, RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection, 346 SceneObjectGroup sog = base.RezObject(remoteClient, itemID, groupID, RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection,
312 RezSelected, RemoveItem, fromTaskID, attachment); 347 RezSelected, RemoveItem, fromTaskID, attachment);
313 348
314 return sog; 349 return sog;
@@ -351,7 +386,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
351 if (!m_CheckSeparateAssets) 386 if (!m_CheckSeparateAssets)
352 { 387 {
353 if (!UserManagementModule.IsLocalGridUser(userID)) 388 if (!UserManagementModule.IsLocalGridUser(userID))
354 { // foreign 389 { // foreign
355 ScenePresence sp = null; 390 ScenePresence sp = null;
356 if (m_Scene.TryGetScenePresence(userID, out sp)) 391 if (m_Scene.TryGetScenePresence(userID, out sp))
357 { 392 {
@@ -489,7 +524,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
489 foreach (InventoryItemBase it in content.Items) 524 foreach (InventoryItemBase it in content.Items)
490 it.Name = it.Name + " (Unavailable)"; ; 525 it.Name = it.Name + " (Unavailable)"; ;
491 526
492 // Send the new names 527 // Send the new names
493 inv.SendBulkUpdateInventory(keep.ToArray(), content.Items.ToArray()); 528 inv.SendBulkUpdateInventory(keep.ToArray(), content.Items.ToArray());
494 529
495 } 530 }
@@ -506,16 +541,17 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
506 541
507 #region Permissions 542 #region Permissions
508 543
509 private bool CanTakeObject(UUID objectID, UUID stealer, Scene scene) 544 private bool CanTakeObject(SceneObjectGroup sog, ScenePresence sp)
510 { 545 {
511 if (m_bypassPermissions) return true; 546 if (m_bypassPermissions) return true;
512 547
513 if (!m_OutboundPermission && !UserManagementModule.IsLocalGridUser(stealer)) 548 if(sp == null || sog == null)
549 return false;
550
551 if (!m_OutboundPermission && !UserManagementModule.IsLocalGridUser(sp.UUID))
514 { 552 {
515 SceneObjectGroup sog = null; 553 if (sog.OwnerID == sp.UUID)
516 if (m_Scene.TryGetSceneObjectGroup(objectID, out sog) && sog.OwnerID == stealer)
517 return true; 554 return true;
518
519 return false; 555 return false;
520 } 556 }
521 557
@@ -535,4 +571,4 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
535 571
536 #endregion 572 #endregion
537 } 573 }
538} \ No newline at end of file 574}
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index 5a9efb8..788ed1c 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -68,7 +68,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
68 return m_UserManagement; 68 return m_UserManagement;
69 } 69 }
70 } 70 }
71 71
72 public bool CoalesceMultipleObjectsToInventory { get; set; } 72 public bool CoalesceMultipleObjectsToInventory { get; set; }
73 73
74 #region INonSharedRegionModule 74 #region INonSharedRegionModule
@@ -92,14 +92,14 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
92 if (name == Name) 92 if (name == Name)
93 { 93 {
94 m_Enabled = true; 94 m_Enabled = true;
95 95
96 InitialiseCommon(source); 96 InitialiseCommon(source);
97 97
98 m_log.InfoFormat("[INVENTORY ACCESS MODULE]: {0} enabled.", Name); 98 m_log.InfoFormat("[INVENTORY ACCESS MODULE]: {0} enabled.", Name);
99 } 99 }
100 } 100 }
101 } 101 }
102 102
103 /// <summary> 103 /// <summary>
104 /// Common module config for both this and descendant classes. 104 /// Common module config for both this and descendant classes.
105 /// </summary> 105 /// </summary>
@@ -107,9 +107,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
107 protected virtual void InitialiseCommon(IConfigSource source) 107 protected virtual void InitialiseCommon(IConfigSource source)
108 { 108 {
109 IConfig inventoryConfig = source.Configs["Inventory"]; 109 IConfig inventoryConfig = source.Configs["Inventory"];
110 110
111 if (inventoryConfig != null) 111 if (inventoryConfig != null)
112 CoalesceMultipleObjectsToInventory 112 CoalesceMultipleObjectsToInventory
113 = inventoryConfig.GetBoolean("CoalesceMultipleObjectsToInventory", true); 113 = inventoryConfig.GetBoolean("CoalesceMultipleObjectsToInventory", true);
114 else 114 else
115 CoalesceMultipleObjectsToInventory = true; 115 CoalesceMultipleObjectsToInventory = true;
@@ -175,53 +175,73 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
175 /// <param name="nextOwnerMask"></param> 175 /// <param name="nextOwnerMask"></param>
176 public void CreateNewInventoryItem(IClientAPI remoteClient, UUID transactionID, UUID folderID, 176 public void CreateNewInventoryItem(IClientAPI remoteClient, UUID transactionID, UUID folderID,
177 uint callbackID, string description, string name, sbyte invType, 177 uint callbackID, string description, string name, sbyte invType,
178 sbyte assetType, 178 sbyte assetType, byte wearableType,
179 byte wearableType, uint nextOwnerMask, int creationDate) 179 uint nextOwnerMask, int creationDate)
180 { 180 {
181 m_log.DebugFormat("[INVENTORY ACCESS MODULE]: Received request to create inventory item {0} in folder {1}", name, folderID); 181 m_log.DebugFormat("[INVENTORY ACCESS MODULE]: Received request to create inventory item {0} in folder {1}, transactionID {2}", name,
182 folderID, transactionID);
182 183
183 if (!m_Scene.Permissions.CanCreateUserInventory(invType, remoteClient.AgentId)) 184 if (!m_Scene.Permissions.CanCreateUserInventory(invType, remoteClient.AgentId))
184 return; 185 return;
185 186
186 if (transactionID == UUID.Zero) 187 InventoryFolderBase folder = m_Scene.InventoryService.GetFolder(remoteClient.AgentId, folderID);
188
189 if (folder == null && Enum.IsDefined(typeof(FolderType), (sbyte)invType))
187 { 190 {
188 ScenePresence presence; 191 folder = m_Scene.InventoryService.GetFolderForType(remoteClient.AgentId, (FolderType)invType);
189 if (m_Scene.TryGetScenePresence(remoteClient.AgentId, out presence)) 192 if (folder != null)
190 { 193 m_log.DebugFormat("[INVENTORY ACCESS MODULE]: Requested folder not found but found folder for type {0}", invType);
191 byte[] data = null; 194 }
192 195
193 if (invType == (sbyte)InventoryType.Landmark && presence != null) 196 if (folder == null || folder.Owner != remoteClient.AgentId)
194 { 197 return;
195 string suffix = string.Empty, prefix = string.Empty;
196 string strdata = GenerateLandmark(presence, out prefix, out suffix);
197 data = Encoding.ASCII.GetBytes(strdata);
198 name = prefix + name;
199 description += suffix;
200 }
201 198
202 AssetBase asset = m_Scene.CreateAsset(name, description, assetType, data, remoteClient.AgentId); 199 if (transactionID != UUID.Zero)
203 m_Scene.AssetService.Store(asset);
204 m_Scene.CreateNewInventoryItem(
205 remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID,
206 name, description, 0, callbackID, asset.FullID, asset.Type, invType, nextOwnerMask, creationDate);
207 }
208 else
209 {
210 m_log.ErrorFormat(
211 "[INVENTORY ACCESS MODULE]: ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem",
212 remoteClient.AgentId);
213 }
214 }
215 else
216 { 200 {
217 IAgentAssetTransactions agentTransactions = m_Scene.AgentTransactionsModule; 201 IAgentAssetTransactions agentTransactions = m_Scene.AgentTransactionsModule;
218 if (agentTransactions != null) 202 if (agentTransactions != null)
219 { 203 {
220 agentTransactions.HandleItemCreationFromTransaction( 204 if (agentTransactions.HandleItemCreationFromTransaction(
221 remoteClient, transactionID, folderID, callbackID, description, 205 remoteClient, transactionID, folderID, callbackID, description,
222 name, invType, assetType, wearableType, nextOwnerMask); 206 name, invType, assetType, wearableType, nextOwnerMask))
207 return;
223 } 208 }
224 } 209 }
210
211 ScenePresence presence;
212 if (m_Scene.TryGetScenePresence(remoteClient.AgentId, out presence))
213 {
214 byte[] data = null;
215 uint everyonemask = 0;
216 uint groupmask = 0;
217
218 if (invType == (sbyte)InventoryType.Landmark && presence != null)
219 {
220 string suffix = string.Empty, prefix = string.Empty;
221 string strdata = GenerateLandmark(presence, out prefix, out suffix);
222 data = Encoding.ASCII.GetBytes(strdata);
223 name = prefix + name;
224 description += suffix;
225 groupmask = (uint)PermissionMask.AllAndExport;
226 everyonemask = (uint)(PermissionMask.AllAndExport & ~PermissionMask.Modify);
227 }
228
229 AssetBase asset = m_Scene.CreateAsset(name, description, assetType, data, remoteClient.AgentId);
230 m_Scene.AssetService.Store(asset);
231 m_Scene.CreateNewInventoryItem(
232 remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID,
233 name, description, 0, callbackID, asset.FullID, asset.Type, invType,
234 (uint)PermissionMask.AllAndExport, // Base
235 (uint)PermissionMask.AllAndExport, // Current
236 everyonemask,
237 nextOwnerMask, groupmask, creationDate, false); // Data from viewer
238 }
239 else
240 {
241 m_log.ErrorFormat(
242 "[INVENTORY ACCESS MODULE]: ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem",
243 remoteClient.AgentId);
244 }
225 } 245 }
226 246
227 protected virtual string GenerateLandmark(ScenePresence presence, out string prefix, out string suffix) 247 protected virtual string GenerateLandmark(ScenePresence presence, out string prefix, out string suffix)
@@ -244,53 +264,65 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
244 /// <returns></returns> 264 /// <returns></returns>
245 public virtual UUID CapsUpdateInventoryItemAsset(IClientAPI remoteClient, UUID itemID, byte[] data) 265 public virtual UUID CapsUpdateInventoryItemAsset(IClientAPI remoteClient, UUID itemID, byte[] data)
246 { 266 {
247 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); 267 InventoryItemBase item = m_Scene.InventoryService.GetItem(remoteClient.AgentId, itemID);
248 item = m_Scene.InventoryService.GetItem(item); 268
269 if (item == null)
270 {
271 m_log.ErrorFormat(
272 "[INVENTORY ACCESS MODULE]: Could not find item {0} for caps inventory update", itemID);
273 return UUID.Zero;
274 }
249 275
250 if (item.Owner != remoteClient.AgentId) 276 if (item.Owner != remoteClient.AgentId)
251 return UUID.Zero; 277 return UUID.Zero;
252 278
253 if (item != null) 279 if ((InventoryType)item.InvType == InventoryType.Notecard)
254 { 280 {
255 if ((InventoryType)item.InvType == InventoryType.Notecard) 281 if (!m_Scene.Permissions.CanEditNotecard(itemID, UUID.Zero, remoteClient.AgentId))
256 { 282 {
257 if (!m_Scene.Permissions.CanEditNotecard(itemID, UUID.Zero, remoteClient.AgentId)) 283 remoteClient.SendAgentAlertMessage("Insufficient permissions to edit notecard", false);
258 { 284 return UUID.Zero;
259 remoteClient.SendAgentAlertMessage("Insufficient permissions to edit notecard", false);
260 return UUID.Zero;
261 }
262
263 remoteClient.SendAlertMessage("Notecard saved");
264 } 285 }
265 else if ((InventoryType)item.InvType == InventoryType.LSL)
266 {
267 if (!m_Scene.Permissions.CanEditScript(itemID, UUID.Zero, remoteClient.AgentId))
268 {
269 remoteClient.SendAgentAlertMessage("Insufficient permissions to edit script", false);
270 return UUID.Zero;
271 }
272 286
273 remoteClient.SendAlertMessage("Script saved"); 287 remoteClient.SendAlertMessage("Notecard saved");
288 }
289 else if ((InventoryType)item.InvType == InventoryType.LSL)
290 {
291 if (!m_Scene.Permissions.CanEditScript(itemID, UUID.Zero, remoteClient.AgentId))
292 {
293 remoteClient.SendAgentAlertMessage("Insufficient permissions to edit script", false);
294 return UUID.Zero;
274 } 295 }
275 296
276 AssetBase asset = 297 remoteClient.SendAlertMessage("Script saved");
277 CreateAsset(item.Name, item.Description, (sbyte)item.AssetType, data, remoteClient.AgentId.ToString());
278 item.AssetID = asset.FullID;
279 m_Scene.AssetService.Store(asset);
280
281 m_Scene.InventoryService.UpdateItem(item);
282
283 // remoteClient.SendInventoryItemCreateUpdate(item);
284 return (asset.FullID);
285 } 298 }
286 else 299 else if ((CustomInventoryType)item.InvType == CustomInventoryType.AnimationSet)
287 { 300 {
288 m_log.ErrorFormat( 301 AnimationSet animSet = new AnimationSet(data);
289 "[INVENTORY ACCESS MODULE]: Could not find item {0} for caps inventory update", 302 uint res = animSet.Validate(x => {
290 itemID); 303 const int required = (int)(PermissionMask.Transfer | PermissionMask.Copy);
304 int perms = m_Scene.InventoryService.GetAssetPermissions(remoteClient.AgentId, x);
305 // enforce previus perm rule
306 if ((perms & required) != required)
307 return 0;
308 return (uint) perms;
309 });
310 if(res == 0)
311 {
312 remoteClient.SendAgentAlertMessage("Not enought permissions on asset(s) referenced by animation set '{0}', update failed", false);
313 return UUID.Zero;
314 }
291 } 315 }
292 316
293 return UUID.Zero; 317 AssetBase asset =
318 CreateAsset(item.Name, item.Description, (sbyte)item.AssetType, data, remoteClient.AgentId.ToString());
319 item.AssetID = asset.FullID;
320 m_Scene.AssetService.Store(asset);
321
322 m_Scene.InventoryService.UpdateItem(item);
323
324 // remoteClient.SendInventoryItemCreateUpdate(item);
325 return (asset.FullID);
294 } 326 }
295 327
296 public virtual bool UpdateInventoryItemAsset(UUID ownerID, InventoryItemBase item, AssetBase asset) 328 public virtual bool UpdateInventoryItemAsset(UUID ownerID, InventoryItemBase item, AssetBase asset)
@@ -298,7 +330,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
298 if (item != null && item.Owner == ownerID && asset != null) 330 if (item != null && item.Owner == ownerID && asset != null)
299 { 331 {
300// m_log.DebugFormat( 332// m_log.DebugFormat(
301// "[INVENTORY ACCESS MODULE]: Updating item {0} {1} with new asset {2}", 333// "[INVENTORY ACCESS MODULE]: Updating item {0} {1} with new asset {2}",
302// item.Name, item.ID, asset.ID); 334// item.Name, item.ID, asset.ID);
303 335
304 item.AssetID = asset.FullID; 336 item.AssetID = asset.FullID;
@@ -327,7 +359,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
327 List<InventoryItemBase> copiedItems = new List<InventoryItemBase>(); 359 List<InventoryItemBase> copiedItems = new List<InventoryItemBase>();
328 360
329 Dictionary<UUID, List<SceneObjectGroup>> bundlesToCopy = new Dictionary<UUID, List<SceneObjectGroup>>(); 361 Dictionary<UUID, List<SceneObjectGroup>> bundlesToCopy = new Dictionary<UUID, List<SceneObjectGroup>>();
330 362
331 if (CoalesceMultipleObjectsToInventory) 363 if (CoalesceMultipleObjectsToInventory)
332 { 364 {
333 // The following code groups the SOG's by owner. No objects 365 // The following code groups the SOG's by owner. No objects
@@ -337,7 +369,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
337 { 369 {
338 if (!bundlesToCopy.ContainsKey(g.OwnerID)) 370 if (!bundlesToCopy.ContainsKey(g.OwnerID))
339 bundlesToCopy[g.OwnerID] = new List<SceneObjectGroup>(); 371 bundlesToCopy[g.OwnerID] = new List<SceneObjectGroup>();
340 372
341 bundlesToCopy[g.OwnerID].Add(g); 373 bundlesToCopy[g.OwnerID].Add(g);
342 } 374 }
343 } 375 }
@@ -348,7 +380,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
348 { 380 {
349 List<SceneObjectGroup> bundle = new List<SceneObjectGroup>(); 381 List<SceneObjectGroup> bundle = new List<SceneObjectGroup>();
350 bundle.Add(g); 382 bundle.Add(g);
351 bundlesToCopy[g.UUID] = bundle; 383 bundlesToCopy[g.UUID] = bundle;
352 } 384 }
353 } 385 }
354 386
@@ -360,10 +392,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
360 // with distinct destinations as well. 392 // with distinct destinations as well.
361 foreach (List<SceneObjectGroup> bundle in bundlesToCopy.Values) 393 foreach (List<SceneObjectGroup> bundle in bundlesToCopy.Values)
362 copiedItems.Add(CopyBundleToInventory(action, folderID, bundle, remoteClient, asAttachment)); 394 copiedItems.Add(CopyBundleToInventory(action, folderID, bundle, remoteClient, asAttachment));
363 395
364 return copiedItems; 396 return copiedItems;
365 } 397 }
366 398
367 /// <summary> 399 /// <summary>
368 /// Copy a bundle of objects to inventory. If there is only one object, then this will create an object 400 /// Copy a bundle of objects to inventory. If there is only one object, then this will create an object
369 /// item. If there are multiple objects then these will be saved as a single coalesced item. 401 /// item. If there are multiple objects then these will be saved as a single coalesced item.
@@ -379,33 +411,42 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
379 DeRezAction action, UUID folderID, List<SceneObjectGroup> objlist, IClientAPI remoteClient, 411 DeRezAction action, UUID folderID, List<SceneObjectGroup> objlist, IClientAPI remoteClient,
380 bool asAttachment) 412 bool asAttachment)
381 { 413 {
382 CoalescedSceneObjects coa = new CoalescedSceneObjects(UUID.Zero); 414 CoalescedSceneObjects coa = new CoalescedSceneObjects(UUID.Zero);
383// Dictionary<UUID, Vector3> originalPositions = new Dictionary<UUID, Vector3>(); 415 Dictionary<UUID, Vector3> originalPositions = new Dictionary<UUID, Vector3>();
384 416 Dictionary<UUID, Quaternion> originalRotations = new Dictionary<UUID, Quaternion>();
385 Dictionary<SceneObjectGroup, KeyframeMotion> group2Keyframe = new Dictionary<SceneObjectGroup, KeyframeMotion>(); 417 // this possible is not needed if keyframes are saved
418// Dictionary<UUID, KeyframeMotion> originalKeyframes = new Dictionary<UUID, KeyframeMotion>();
386 419
387 foreach (SceneObjectGroup objectGroup in objlist) 420 foreach (SceneObjectGroup objectGroup in objlist)
388 { 421 {
389 if (objectGroup.RootPart.KeyframeMotion != null) 422 if (objectGroup.RootPart.KeyframeMotion != null)
390 { 423 {
391 objectGroup.RootPart.KeyframeMotion.Pause(); 424 objectGroup.RootPart.KeyframeMotion.Suspend();
392 group2Keyframe.Add(objectGroup, objectGroup.RootPart.KeyframeMotion);
393 objectGroup.RootPart.KeyframeMotion = null;
394 } 425 }
426 objectGroup.RootPart.SetForce(Vector3.Zero);
427 objectGroup.RootPart.SetAngularImpulse(Vector3.Zero, false);
395 428
396// Vector3 inventoryStoredPosition = new Vector3 429// originalKeyframes[objectGroup.UUID] = objectGroup.RootPart.KeyframeMotion;
397// (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize) 430// objectGroup.RootPart.KeyframeMotion = null;
398// ? 250 431
399// : objectGroup.AbsolutePosition.X) 432 Vector3 inventoryStoredPosition = objectGroup.AbsolutePosition;
400// , 433 originalPositions[objectGroup.UUID] = inventoryStoredPosition;
401// (objectGroup.AbsolutePosition.Y > (int)Constants.RegionSize) 434 Quaternion inventoryStoredRotation = objectGroup.GroupRotation;
402// ? 250 435 originalRotations[objectGroup.UUID] = inventoryStoredRotation;
403// : objectGroup.AbsolutePosition.Y, 436
404// objectGroup.AbsolutePosition.Z); 437 // Restore attachment data after trip through the sim
405// 438 if (objectGroup.AttachmentPoint > 0)
406// originalPositions[objectGroup.UUID] = objectGroup.AbsolutePosition; 439 {
407// 440 inventoryStoredPosition = objectGroup.RootPart.AttachedPos;
408// objectGroup.AbsolutePosition = inventoryStoredPosition; 441 inventoryStoredRotation = objectGroup.RootPart.AttachRotation;
442 if (objectGroup.RootPart.Shape.PCode != (byte) PCode.Tree &&
443 objectGroup.RootPart.Shape.PCode != (byte) PCode.NewTree)
444 objectGroup.RootPart.Shape.LastAttachPoint = (byte)objectGroup.AttachmentPoint;
445
446 }
447
448 objectGroup.AbsolutePosition = inventoryStoredPosition;
449 objectGroup.RootPart.RotationOffset = inventoryStoredRotation;
409 450
410 // Make sure all bits but the ones we want are clear 451 // Make sure all bits but the ones we want are clear
411 // on take. 452 // on take.
@@ -418,7 +459,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
418 (uint)PermissionMask.Export); 459 (uint)PermissionMask.Export);
419 objectGroup.RootPart.NextOwnerMask |= 460 objectGroup.RootPart.NextOwnerMask |=
420 (uint)PermissionMask.Move; 461 (uint)PermissionMask.Move;
421 462
422 coa.Add(objectGroup); 463 coa.Add(objectGroup);
423 } 464 }
424 465
@@ -432,10 +473,16 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
432 itemXml = CoalescedSceneObjectsSerializer.ToXml(coa, !asAttachment); 473 itemXml = CoalescedSceneObjectsSerializer.ToXml(coa, !asAttachment);
433 else 474 else
434 itemXml = SceneObjectSerializer.ToOriginalXmlFormat(objlist[0], !asAttachment); 475 itemXml = SceneObjectSerializer.ToOriginalXmlFormat(objlist[0], !asAttachment);
435 476
436// // Restore the position of each group now that it has been stored to inventory. 477 // Restore the position of each group now that it has been stored to inventory.
437// foreach (SceneObjectGroup objectGroup in objlist) 478 foreach (SceneObjectGroup objectGroup in objlist)
438// objectGroup.AbsolutePosition = originalPositions[objectGroup.UUID]; 479 {
480 objectGroup.AbsolutePosition = originalPositions[objectGroup.UUID];
481 objectGroup.RootPart.RotationOffset = originalRotations[objectGroup.UUID];
482// objectGroup.RootPart.KeyframeMotion = originalKeyframes[objectGroup.UUID];
483 if (objectGroup.RootPart.KeyframeMotion != null)
484 objectGroup.RootPart.KeyframeMotion.Resume();
485 }
439 486
440 InventoryItemBase item = CreateItemForObject(action, remoteClient, objlist[0], folderID); 487 InventoryItemBase item = CreateItemForObject(action, remoteClient, objlist[0], folderID);
441 488
@@ -448,11 +495,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
448 495
449 item.CreatorId = objlist[0].RootPart.CreatorID.ToString(); 496 item.CreatorId = objlist[0].RootPart.CreatorID.ToString();
450 item.CreatorData = objlist[0].RootPart.CreatorData; 497 item.CreatorData = objlist[0].RootPart.CreatorData;
451 498
452 if (objlist.Count > 1) 499 if (objlist.Count > 1)
453 { 500 {
454 item.Flags = (uint)InventoryItemFlags.ObjectHasMultipleItems; 501 item.Flags = (uint)InventoryItemFlags.ObjectHasMultipleItems;
455 502
456 // If the objects have different creators then don't specify a creator at all 503 // If the objects have different creators then don't specify a creator at all
457 foreach (SceneObjectGroup objectGroup in objlist) 504 foreach (SceneObjectGroup objectGroup in objlist)
458 { 505 {
@@ -468,8 +515,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
468 else 515 else
469 { 516 {
470 item.SaleType = objlist[0].RootPart.ObjectSaleType; 517 item.SaleType = objlist[0].RootPart.ObjectSaleType;
471 item.SalePrice = objlist[0].RootPart.SalePrice; 518 item.SalePrice = objlist[0].RootPart.SalePrice;
472 } 519 }
473 520
474 AssetBase asset = CreateAsset( 521 AssetBase asset = CreateAsset(
475 objlist[0].GetPartName(objlist[0].RootPart.LocalId), 522 objlist[0].GetPartName(objlist[0].RootPart.LocalId),
@@ -478,7 +525,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
478 Utils.StringToBytes(itemXml), 525 Utils.StringToBytes(itemXml),
479 objlist[0].OwnerID.ToString()); 526 objlist[0].OwnerID.ToString());
480 m_Scene.AssetService.Store(asset); 527 m_Scene.AssetService.Store(asset);
481 528
482 item.AssetID = asset.FullID; 529 item.AssetID = asset.FullID;
483 530
484 if (DeRezAction.SaveToExistingUserInventoryItem == action) 531 if (DeRezAction.SaveToExistingUserInventoryItem == action)
@@ -487,13 +534,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
487 } 534 }
488 else 535 else
489 { 536 {
537 AddPermissions(item, objlist[0], objlist, remoteClient);
538
490 item.CreationDate = Util.UnixTimeSinceEpoch(); 539 item.CreationDate = Util.UnixTimeSinceEpoch();
491 item.Description = asset.Description; 540 item.Description = asset.Description;
492 item.Name = asset.Name; 541 item.Name = asset.Name;
493 item.AssetType = asset.Type; 542 item.AssetType = asset.Type;
494 543
495 AddPermissions(item, objlist[0], objlist, remoteClient);
496
497 m_Scene.AddInventoryItem(item); 544 m_Scene.AddInventoryItem(item);
498 545
499 if (remoteClient != null && item.Owner == remoteClient.AgentId) 546 if (remoteClient != null && item.Owner == remoteClient.AgentId)
@@ -510,17 +557,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
510 } 557 }
511 } 558 }
512 559
513 // Restore KeyframeMotion
514 foreach (SceneObjectGroup objectGroup in group2Keyframe.Keys)
515 {
516 objectGroup.RootPart.KeyframeMotion = group2Keyframe[objectGroup];
517 objectGroup.RootPart.KeyframeMotion.Start();
518 }
519
520 // This is a hook to do some per-asset post-processing for subclasses that need that 560 // This is a hook to do some per-asset post-processing for subclasses that need that
521 if (remoteClient != null) 561 if (remoteClient != null && action != DeRezAction.Delete)
522 ExportAsset(remoteClient.AgentId, asset.FullID); 562 ExportAsset(remoteClient.AgentId, asset.FullID);
523 563
524 return item; 564 return item;
525 } 565 }
526 566
@@ -538,56 +578,41 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
538 /// <param name="remoteClient"></param> 578 /// <param name="remoteClient"></param>
539 /// <returns></returns> 579 /// <returns></returns>
540 protected InventoryItemBase AddPermissions( 580 protected InventoryItemBase AddPermissions(
541 InventoryItemBase item, SceneObjectGroup so, List<SceneObjectGroup> objsForEffectivePermissions, 581 InventoryItemBase item, SceneObjectGroup so, List<SceneObjectGroup> objsForEffectivePermissions,
542 IClientAPI remoteClient) 582 IClientAPI remoteClient)
543 { 583 {
544 uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move | PermissionMask.Export) | 7; 584 uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move | PermissionMask.Export | PermissionMask.FoldedMask);
545 uint allObjectsNextOwnerPerms = 0x7fffffff; 585
546 uint allObjectsEveryOnePerms = 0x7fffffff;
547 uint allObjectsGroupPerms = 0x7fffffff;
548
549 foreach (SceneObjectGroup grp in objsForEffectivePermissions) 586 foreach (SceneObjectGroup grp in objsForEffectivePermissions)
550 { 587 {
551 effectivePerms &= grp.GetEffectivePermissions(); 588 effectivePerms &= grp.CurrentAndFoldedNextPermissions();
552 allObjectsNextOwnerPerms &= grp.RootPart.NextOwnerMask;
553 allObjectsEveryOnePerms &= grp.RootPart.EveryoneMask;
554 allObjectsGroupPerms &= grp.RootPart.GroupMask;
555 } 589 }
556 effectivePerms |= (uint)PermissionMask.Move; 590
557
558 //PermissionsUtil.LogPermissions(item.Name, "Before AddPermissions", item.BasePermissions, item.CurrentPermissions, item.NextPermissions);
559
560 if (remoteClient != null && (remoteClient.AgentId != so.RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions()) 591 if (remoteClient != null && (remoteClient.AgentId != so.RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions())
561 { 592 {
562 // Changing ownership, so apply the "Next Owner" permissions to all of the 593 // apply parts inventory items next owner
563 // inventory item's permissions. 594 PermissionsUtil.ApplyNoModFoldedPermissions(effectivePerms, ref effectivePerms);
564 595 // change to next owner
565 uint perms = effectivePerms; 596 uint basePerms = effectivePerms & so.RootPart.NextOwnerMask;
566 PermissionsUtil.ApplyFoldedPermissions(effectivePerms, ref perms); 597 // fix and update folded
567 598 basePerms = PermissionsUtil.FixAndFoldPermissions(basePerms);
568 item.BasePermissions = perms & allObjectsNextOwnerPerms; 599
569 item.CurrentPermissions = item.BasePermissions; 600 item.BasePermissions = basePerms;
570 item.NextPermissions = perms & allObjectsNextOwnerPerms; 601 item.CurrentPermissions = basePerms;
571 item.EveryOnePermissions = allObjectsEveryOnePerms & allObjectsNextOwnerPerms; 602 item.NextPermissions = basePerms & so.RootPart.NextOwnerMask;
572 item.GroupPermissions = allObjectsGroupPerms & allObjectsNextOwnerPerms; 603 item.EveryOnePermissions = basePerms & so.RootPart.EveryoneMask;
573 604 item.GroupPermissions = basePerms & so.RootPart.GroupMask;
605
574 // apply next owner perms on rez 606 // apply next owner perms on rez
575 item.CurrentPermissions |= SceneObjectGroup.SLAM; 607 item.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm;
576 } 608 }
577 else 609 else
578 { 610 {
579 // Not changing ownership.
580 // In this case we apply the permissions in the object's items ONLY to the inventory
581 // item's "Next Owner" permissions, but NOT to its "Current", "Base", etc. permissions.
582 // E.g., if the object contains a No-Transfer item then the item's "Next Owner"
583 // permissions are also No-Transfer.
584 PermissionsUtil.ApplyFoldedPermissions(effectivePerms, ref allObjectsNextOwnerPerms);
585
586 item.BasePermissions = effectivePerms; 611 item.BasePermissions = effectivePerms;
587 item.CurrentPermissions = effectivePerms; 612 item.CurrentPermissions = effectivePerms;
588 item.NextPermissions = allObjectsNextOwnerPerms & effectivePerms; 613 item.NextPermissions = so.RootPart.NextOwnerMask & effectivePerms;
589 item.EveryOnePermissions = allObjectsEveryOnePerms & effectivePerms; 614 item.EveryOnePermissions = so.RootPart.EveryoneMask & effectivePerms;
590 item.GroupPermissions = allObjectsGroupPerms & effectivePerms; 615 item.GroupPermissions = so.RootPart.GroupMask & effectivePerms;
591 616
592 item.CurrentPermissions &= 617 item.CurrentPermissions &=
593 ((uint)PermissionMask.Copy | 618 ((uint)PermissionMask.Copy |
@@ -595,14 +620,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
595 (uint)PermissionMask.Modify | 620 (uint)PermissionMask.Modify |
596 (uint)PermissionMask.Move | 621 (uint)PermissionMask.Move |
597 (uint)PermissionMask.Export | 622 (uint)PermissionMask.Export |
598 7); // Preserve folded permissions 623 (uint)PermissionMask.FoldedMask); // Preserve folded permissions ??
599 } 624 }
600 625
601 //PermissionsUtil.LogPermissions(item.Name, "After AddPermissions", item.BasePermissions, item.CurrentPermissions, item.NextPermissions);
602
603 return item; 626 return item;
604 } 627 }
605 628
606 /// <summary> 629 /// <summary>
607 /// Create an item using details for the given scene object. 630 /// Create an item using details for the given scene object.
608 /// </summary> 631 /// </summary>
@@ -615,7 +638,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
615 DeRezAction action, IClientAPI remoteClient, SceneObjectGroup so, UUID folderID) 638 DeRezAction action, IClientAPI remoteClient, SceneObjectGroup so, UUID folderID)
616 { 639 {
617// m_log.DebugFormat( 640// m_log.DebugFormat(
618// "[BASIC INVENTORY ACCESS MODULE]: Creating item for object {0} {1} for folder {2}, action {3}", 641// "[BASIC INVENTORY ACCESS MODULE]: Creating item for object {0} {1} for folder {2}, action {3}",
619// so.Name, so.UUID, folderID, action); 642// so.Name, so.UUID, folderID, action);
620// 643//
621 // Get the user info of the item destination 644 // Get the user info of the item destination
@@ -663,14 +686,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
663 // Delete is treated like return in this case 686 // Delete is treated like return in this case
664 // Deleting your own items makes them go to trash 687 // Deleting your own items makes them go to trash
665 // 688 //
666 689
667 InventoryFolderBase folder = null; 690 InventoryFolderBase folder = null;
668 InventoryItemBase item = null; 691 InventoryItemBase item = null;
669 692
670 if (DeRezAction.SaveToExistingUserInventoryItem == action) 693 if (DeRezAction.SaveToExistingUserInventoryItem == action)
671 { 694 {
672 item = new InventoryItemBase(so.RootPart.FromUserInventoryItemID, userID); 695 item = m_Scene.InventoryService.GetItem(userID, so.RootPart.FromUserInventoryItemID);
673 item = m_Scene.InventoryService.GetItem(item);
674 696
675 //item = userInfo.RootFolder.FindItem( 697 //item = userInfo.RootFolder.FindItem(
676 // objectGroup.RootPart.FromUserInventoryItemID); 698 // objectGroup.RootPart.FromUserInventoryItemID);
@@ -680,7 +702,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
680 m_log.DebugFormat( 702 m_log.DebugFormat(
681 "[INVENTORY ACCESS MODULE]: Object {0} {1} scheduled for save to inventory has already been deleted.", 703 "[INVENTORY ACCESS MODULE]: Object {0} {1} scheduled for save to inventory has already been deleted.",
682 so.Name, so.UUID); 704 so.Name, so.UUID);
683 705
684 return null; 706 return null;
685 } 707 }
686 } 708 }
@@ -742,8 +764,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
742 { 764 {
743 if (so.FromFolderID != UUID.Zero && so.RootPart.OwnerID == remoteClient.AgentId) 765 if (so.FromFolderID != UUID.Zero && so.RootPart.OwnerID == remoteClient.AgentId)
744 { 766 {
745 InventoryFolderBase f = new InventoryFolderBase(so.FromFolderID, userID); 767 folder = m_Scene.InventoryService.GetFolder(userID, so.FromFolderID);
746 folder = m_Scene.InventoryService.GetFolder(f);
747 768
748 if(folder.Type == 14 || folder.Type == 16) 769 if(folder.Type == 14 || folder.Type == 16)
749 { 770 {
@@ -763,49 +784,65 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
763 } 784 }
764 } 785 }
765 786
766 item = new InventoryItemBase(); 787 item = new InventoryItemBase();
767 item.ID = UUID.Random(); 788 item.ID = UUID.Random();
768 item.InvType = (int)InventoryType.Object; 789 item.InvType = (int)InventoryType.Object;
769 item.Folder = folder.ID; 790 item.Folder = folder.ID;
770 item.Owner = userID; 791 item.Owner = userID;
771 } 792 }
772 793
773 return item; 794 return item;
774 } 795 }
775 796 // compatibility do not use
776 public virtual SceneObjectGroup RezObject( 797 public virtual SceneObjectGroup RezObject(
777 IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart, 798 IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart,
778 UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, 799 UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
779 bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) 800 bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
780 { 801 {
781// m_log.DebugFormat("[INVENTORY ACCESS MODULE]: RezObject for {0}, item {1}", remoteClient.Name, itemID); 802 return RezObject(remoteClient, itemID, UUID.Zero, RayEnd, RayStart,
803 RayTargetID, BypassRayCast, RayEndIsIntersection,
804 RezSelected, RemoveItem, fromTaskID, attachment);
805 }
782 806
783 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); 807 public virtual SceneObjectGroup RezObject(
784 item = m_Scene.InventoryService.GetItem(item); 808 IClientAPI remoteClient, UUID itemID, UUID rezGroupID, Vector3 RayEnd, Vector3 RayStart,
809 UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
810 bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
811 {
812// m_log.DebugFormat("[INVENTORY ACCESS MODULE]: RezObject for {0}, item {1}", remoteClient.Name, itemID);
813 InventoryItemBase item = m_Scene.InventoryService.GetItem(remoteClient.AgentId, itemID);
785 814
786 if (item == null) 815 if (item == null)
787 { 816 {
788 m_log.WarnFormat(
789 "[INVENTORY ACCESS MODULE]: Could not find item {0} for {1} in RezObject()",
790 itemID, remoteClient.Name);
791
792 return null; 817 return null;
793 } 818 }
794 819
795 item.Owner = remoteClient.AgentId; 820 item.Owner = remoteClient.AgentId;
796 821
797 return RezObject( 822 return RezObject(
798 remoteClient, item, item.AssetID, 823 remoteClient, item, rezGroupID, item.AssetID,
799 RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection, 824 RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection,
800 RezSelected, RemoveItem, fromTaskID, attachment); 825 RezSelected, RemoveItem, fromTaskID, attachment);
801 } 826 }
802 827 // compatility
803 public virtual SceneObjectGroup RezObject( 828 public virtual SceneObjectGroup RezObject(
804 IClientAPI remoteClient, InventoryItemBase item, UUID assetID, Vector3 RayEnd, Vector3 RayStart, 829 IClientAPI remoteClient, InventoryItemBase item, UUID assetID, Vector3 RayEnd, Vector3 RayStart,
805 UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, 830 UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
806 bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) 831 bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
807 { 832 {
808 AssetBase rezAsset = m_Scene.AssetService.Get(assetID.ToString()); 833 return RezObject(remoteClient, item, UUID.Zero, assetID,
834 RayEnd, RayStart, RayTargetID,
835 BypassRayCast, RayEndIsIntersection,
836 RezSelected, RemoveItem, fromTaskID, attachment);
837 }
838
839 public virtual SceneObjectGroup RezObject(
840 IClientAPI remoteClient, InventoryItemBase item, UUID groupID, UUID assetID,
841 Vector3 RayEnd, Vector3 RayStart, UUID RayTargetID,
842 byte BypassRayCast, bool RayEndIsIntersection,
843 bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
844 {
845 AssetBase rezAsset = m_Scene.AssetService.Get(assetID.ToString());
809 846
810 if (rezAsset == null) 847 if (rezAsset == null)
811 { 848 {
@@ -827,6 +864,15 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
827 return null; 864 return null;
828 } 865 }
829 866
867 if(rezAsset.Data == null || rezAsset.Data.Length == 0)
868 {
869 m_log.WarnFormat(
870 "[INVENTORY ACCESS MODULE]: missing data in asset {0} to RezObject()",
871 assetID, remoteClient.Name);
872 remoteClient.SendAgentAlertMessage(string.Format("Unable to rez: missing data in asset {0} ", assetID), false);
873 return null;
874 }
875
830 SceneObjectGroup group = null; 876 SceneObjectGroup group = null;
831 877
832 List<SceneObjectGroup> objlist; 878 List<SceneObjectGroup> objlist;
@@ -836,7 +882,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
836 byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0); 882 byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0);
837 Vector3 pos; 883 Vector3 pos;
838 884
839 bool single 885 bool single
840 = m_Scene.GetObjectsToRez( 886 = m_Scene.GetObjectsToRez(
841 rezAsset.Data, attachment, out objlist, out veclist, out bbox, out offsetHeight); 887 rezAsset.Data, attachment, out objlist, out veclist, out bbox, out offsetHeight);
842 888
@@ -856,12 +902,35 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
856 pos -= bbox / 2; 902 pos -= bbox / 2;
857 } 903 }
858 904
905 int primcount = 0;
906 foreach (SceneObjectGroup g in objlist)
907 primcount += g.PrimCount;
908
909 if (!m_Scene.Permissions.CanRezObject(
910 primcount, remoteClient.AgentId, pos)
911 && !attachment)
912 {
913 // The client operates in no fail mode. It will
914 // have already removed the item from the folder
915 // if it's no copy.
916 // Put it back if it's not an attachment
917 //
918 if (item != null)
919 {
920 if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!attachment))
921 remoteClient.SendBulkUpdateInventory(item);
922 }
923
924 return null;
925 }
926
859 if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, pos, veclist, attachment)) 927 if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, pos, veclist, attachment))
860 return null; 928 return null;
861 929
862 for (int i = 0; i < objlist.Count; i++) 930 for (int i = 0; i < objlist.Count; i++)
863 { 931 {
864 group = objlist[i]; 932 group = objlist[i];
933 SceneObjectPart rootPart = group.RootPart;
865 934
866// m_log.DebugFormat( 935// m_log.DebugFormat(
867// "[INVENTORY ACCESS MODULE]: Preparing to rez {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}", 936// "[INVENTORY ACCESS MODULE]: Preparing to rez {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}",
@@ -891,9 +960,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
891 // Make the rezzer the owner, as this is not necessarily set correctly in the serialized asset. 960 // Make the rezzer the owner, as this is not necessarily set correctly in the serialized asset.
892 part.LastOwnerID = part.OwnerID; 961 part.LastOwnerID = part.OwnerID;
893 part.OwnerID = remoteClient.AgentId; 962 part.OwnerID = remoteClient.AgentId;
963 part.RezzerID = remoteClient.AgentId;
894 } 964 }
895 } 965 }
896 966
967 group.ResetIDs();
968
897 if (!attachment) 969 if (!attachment)
898 { 970 {
899 // If it's rezzed in world, select it. Much easier to 971 // If it's rezzed in world, select it. Much easier to
@@ -903,48 +975,38 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
903 { 975 {
904 part.CreateSelected = true; 976 part.CreateSelected = true;
905 } 977 }
906 }
907 978
908 group.ResetIDs(); 979 if (rootPart.Shape.PCode == (byte)PCode.Prim)
909 980 group.ClearPartAttachmentData();
910 if (attachment) 981 }
982 else
911 { 983 {
912 group.RootPart.Flags |= PrimFlags.Phantom;
913 group.IsAttachment = true; 984 group.IsAttachment = true;
914 } 985 }
915 986
987 group.SetGroup(groupID, remoteClient);
988
916 // If we're rezzing an attachment then don't ask 989 // If we're rezzing an attachment then don't ask
917 // AddNewSceneObject() to update the client since 990 // AddNewSceneObject() to update the client since
918 // we'll be doing that later on. Scheduling more than 991 // we'll be doing that later on. Scheduling more than
919 // one full update during the attachment 992 // one full update during the attachment
920 // process causes some clients to fail to display the 993 // process causes some clients to fail to display the
921 // attachment properly. 994 // attachment properly.
922 m_Scene.AddNewSceneObject(group, !attachment, false);
923 995
924 // if attachment we set it's asset id so object updates
925 // can reflect that, if not, we set it's position in world.
926 if (!attachment) 996 if (!attachment)
927 { 997 {
928 group.ScheduleGroupForFullUpdate();
929
930 group.AbsolutePosition = pos + veclist[i]; 998 group.AbsolutePosition = pos + veclist[i];
931 } 999 m_Scene.AddNewSceneObject(group, true, false);
932
933 group.SetGroup(remoteClient.ActiveGroupId, remoteClient);
934
935 if (!attachment)
936 {
937 SceneObjectPart rootPart = group.RootPart;
938
939 if (rootPart.Shape.PCode == (byte)PCode.Prim)
940 group.ClearPartAttachmentData();
941 1000
942 // Fire on_rez 1001 // Fire on_rez
943 group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1); 1002 group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1);
944 rootPart.ParentGroup.ResumeScripts(); 1003 rootPart.ParentGroup.ResumeScripts();
945 1004
946 rootPart.ScheduleFullUpdate(); 1005 group.ScheduleGroupForFullUpdate();
947 } 1006 }
1007 else
1008 m_Scene.AddNewSceneObject(group, true, false);
1009
948 1010
949// m_log.DebugFormat( 1011// m_log.DebugFormat(
950// "[INVENTORY ACCESS MODULE]: Rezzed {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}", 1012// "[INVENTORY ACCESS MODULE]: Rezzed {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}",
@@ -953,6 +1015,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
953// remoteClient.Name); 1015// remoteClient.Name);
954 } 1016 }
955 1017
1018// group.SetGroup(remoteClient.ActiveGroupId, remoteClient);
1019
956 if (item != null) 1020 if (item != null)
957 DoPostRezWhenFromItem(item, attachment); 1021 DoPostRezWhenFromItem(item, attachment);
958 1022
@@ -973,7 +1037,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
973 /// <param name="isAttachment"></param> 1037 /// <param name="isAttachment"></param>
974 /// <returns>true if we can processed with rezzing, false if we need to abort</returns> 1038 /// <returns>true if we can processed with rezzing, false if we need to abort</returns>
975 private bool DoPreRezWhenFromItem( 1039 private bool DoPreRezWhenFromItem(
976 IClientAPI remoteClient, InventoryItemBase item, List<SceneObjectGroup> objlist, 1040 IClientAPI remoteClient, InventoryItemBase item, List<SceneObjectGroup> objlist,
977 Vector3 pos, List<Vector3> veclist, bool isAttachment) 1041 Vector3 pos, List<Vector3> veclist, bool isAttachment)
978 { 1042 {
979 UUID fromUserInventoryItemId = UUID.Zero; 1043 UUID fromUserInventoryItemId = UUID.Zero;
@@ -1033,10 +1097,16 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
1033 // object itself before we rez. 1097 // object itself before we rez.
1034 // 1098 //
1035 // Only do these for the first object if we are rezzing a coalescence. 1099 // Only do these for the first object if we are rezzing a coalescence.
1036 if (i == 0) 1100 // nahh dont mess with coalescence objects,
1101 // the name in inventory can be change for inventory purpuses only
1102 if (objlist.Count == 1)
1037 { 1103 {
1038 rootPart.Name = item.Name; 1104 rootPart.Name = item.Name;
1039 rootPart.Description = item.Description; 1105 rootPart.Description = item.Description;
1106 }
1107
1108 if ((item.Flags & (uint)InventoryItemFlags.ObjectSlamSale) != 0)
1109 {
1040 rootPart.ObjectSaleType = item.SaleType; 1110 rootPart.ObjectSaleType = item.SaleType;
1041 rootPart.SalePrice = item.SalePrice; 1111 rootPart.SalePrice = item.SalePrice;
1042 } 1112 }
@@ -1047,20 +1117,78 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
1047// "[INVENTORY ACCESS MODULE]: rootPart.OwnedID {0}, item.Owner {1}, item.CurrentPermissions {2:X}", 1117// "[INVENTORY ACCESS MODULE]: rootPart.OwnedID {0}, item.Owner {1}, item.CurrentPermissions {2:X}",
1048// rootPart.OwnerID, item.Owner, item.CurrentPermissions); 1118// rootPart.OwnerID, item.Owner, item.CurrentPermissions);
1049 1119
1050 if ((rootPart.OwnerID != item.Owner) || (item.CurrentPermissions & SceneObjectGroup.SLAM) != 0) 1120 if ((rootPart.OwnerID != item.Owner) ||
1121 (item.CurrentPermissions & (uint)PermissionMask.Slam) != 0 ||
1122 (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0)
1051 { 1123 {
1052 //Need to kill the for sale here 1124 //Need to kill the for sale here
1053 rootPart.ObjectSaleType = 0; 1125 rootPart.ObjectSaleType = 0;
1054 rootPart.SalePrice = 10; 1126 rootPart.SalePrice = 10;
1055 }
1056 1127
1057 foreach (SceneObjectPart part in so.Parts) 1128 if (m_Scene.Permissions.PropagatePermissions())
1129 {
1130 foreach (SceneObjectPart part in so.Parts)
1131 {
1132 part.GroupMask = 0; // DO NOT propagate here
1133 if( part.OwnerID != part.GroupID)
1134 part.LastOwnerID = part.OwnerID;
1135 part.OwnerID = item.Owner;
1136 part.RezzerID = item.Owner;
1137 part.Inventory.ChangeInventoryOwner(item.Owner);
1138
1139 // Reconstruct the original item's base permissions. They
1140 // can be found in the lower (folded) bits.
1141 if ((item.BasePermissions & (uint)PermissionMask.FoldedMask) != 0)
1142 {
1143 // We have permissions stored there so use them
1144 part.NextOwnerMask = ((item.BasePermissions & (uint)PermissionMask.FoldedMask) << (int)PermissionMask.FoldingShift);
1145 part.NextOwnerMask |= (uint)PermissionMask.Move;
1146 }
1147 else
1148 {
1149 // This is a legacy object and we can't avoid the issues that
1150 // caused perms loss or escalation before, treat it the legacy
1151 // way.
1152 part.NextOwnerMask = item.NextPermissions;
1153 }
1154 }
1155
1156 so.ApplyNextOwnerPermissions();
1157
1158 // In case the user has changed flags on a received item
1159 // we have to apply those changes after the slam. Else we
1160 // get a net loss of permissions.
1161 // On legacy objects, this opts for a loss of permissions rather
1162 // than the previous handling that allowed escalation.
1163 foreach (SceneObjectPart part in so.Parts)
1164 {
1165 if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
1166 {
1167 part.GroupMask = item.GroupPermissions & part.BaseMask;
1168 part.EveryoneMask = item.EveryOnePermissions & part.BaseMask;
1169 part.NextOwnerMask = item.NextPermissions & part.BaseMask;
1170 }
1171 }
1172
1173 }
1174 }
1175 else
1058 { 1176 {
1059 part.FromUserInventoryItemID = fromUserInventoryItemId; 1177 foreach (SceneObjectPart part in so.Parts)
1060 part.ApplyPermissionsOnRez(item, true, m_Scene); 1178 {
1179 part.FromUserInventoryItemID = fromUserInventoryItemId;
1180
1181 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0)
1182 part.EveryoneMask = item.EveryOnePermissions;
1183 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0)
1184 part.NextOwnerMask = item.NextPermissions;
1185 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0)
1186 part.GroupMask = item.GroupPermissions;
1187 }
1061 } 1188 }
1062 1189
1063 rootPart.TrimPermissions(); 1190 rootPart.TrimPermissions();
1191 so.InvalidateDeepEffectivePerms();
1064 1192
1065 if (isAttachment) 1193 if (isAttachment)
1066 so.FromItemID = item.ID; 1194 so.FromItemID = item.ID;
@@ -1184,9 +1312,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
1184 protected virtual InventoryItemBase GetItem(UUID agentID, UUID itemID) 1312 protected virtual InventoryItemBase GetItem(UUID agentID, UUID itemID)
1185 { 1313 {
1186 IInventoryService invService = m_Scene.RequestModuleInterface<IInventoryService>(); 1314 IInventoryService invService = m_Scene.RequestModuleInterface<IInventoryService>();
1187 InventoryItemBase item = new InventoryItemBase(itemID, agentID); 1315 InventoryItemBase item = invService.GetItem(agentID, itemID);
1188 item = invService.GetItem(item); 1316
1189
1190 if (item != null && item.CreatorData != null && item.CreatorData != string.Empty) 1317 if (item != null && item.CreatorData != null && item.CreatorData != string.Empty)
1191 UserManagementModule.AddUser(item.CreatorIdAsUuid, item.CreatorData); 1318 UserManagementModule.AddUser(item.CreatorIdAsUuid, item.CreatorData);
1192 1319
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/HGAssetMapperTests.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/HGAssetMapperTests.cs
index 007ff63..01c5d3b 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/HGAssetMapperTests.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/HGAssetMapperTests.cs
@@ -77,7 +77,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
77 scene.StartScripts(); 77 scene.StartScripts();
78 78
79 HGAssetMapper hgam = new HGAssetMapper(scene, homeUrl); 79 HGAssetMapper hgam = new HGAssetMapper(scene, homeUrl);
80 UserAccount ua 80 UserAccount ua
81 = UserAccountHelpers.CreateUserWithInventory(scene, userFirstName, userLastName, userId, "password"); 81 = UserAccountHelpers.CreateUserWithInventory(scene, userFirstName, userLastName, userId, "password");
82 82
83 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, soPartsCount, ua.PrincipalID, "part", soIdTail); 83 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, soPartsCount, ua.PrincipalID, "part", soIdTail);
@@ -93,6 +93,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
93 Assert.AreEqual(foreignUrl, ncAssetGet.CreatorID); 93 Assert.AreEqual(foreignUrl, ncAssetGet.CreatorID);
94 string xmlData = Utils.BytesToString(ncAssetGet.Data); 94 string xmlData = Utils.BytesToString(ncAssetGet.Data);
95 XmlDocument ncAssetGetXmlDoc = new XmlDocument(); 95 XmlDocument ncAssetGetXmlDoc = new XmlDocument();
96 ncAssetGetXmlDoc.XmlResolver=null;
96 ncAssetGetXmlDoc.LoadXml(xmlData); 97 ncAssetGetXmlDoc.LoadXml(xmlData);
97 98
98// Console.WriteLine(ncAssetGetXmlDoc.OuterXml); 99// Console.WriteLine(ncAssetGetXmlDoc.OuterXml);
@@ -116,7 +117,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
116 XmlNode uuidAttribute = savedScriptStateNodes[0].Attributes.GetNamedItem("UUID"); 117 XmlNode uuidAttribute = savedScriptStateNodes[0].Attributes.GetNamedItem("UUID");
117 Assert.NotNull(uuidAttribute); 118 Assert.NotNull(uuidAttribute);
118 // XXX: To check the actual UUID attribute we would have to do some work to retreive the UUID of the task 119 // XXX: To check the actual UUID attribute we would have to do some work to retreive the UUID of the task
119 // item created earlier. 120 // item created earlier.
120 } 121 }
121 122
122 private void RezScript(Scene scene, UUID soId, string script, string itemName, UUID userId) 123 private void RezScript(Scene scene, UUID soId, string script, string itemName, UUID userId)
@@ -131,9 +132,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
131 // immediately for tests rather than chunter through it's threaded mechanisms. 132 // immediately for tests rather than chunter through it's threaded mechanisms.
132 AutoResetEvent chatEvent = new AutoResetEvent(false); 133 AutoResetEvent chatEvent = new AutoResetEvent(false);
133 134
134 scene.EventManager.OnChatFromWorld += (s, c) => 135 scene.EventManager.OnChatFromWorld += (s, c) =>
135 { 136 {
136// Console.WriteLine("Got chat [{0}]", c.Message); 137// Console.WriteLine("Got chat [{0}]", c.Message);
137 chatEvent.Set(); 138 chatEvent.Set();
138 }; 139 };
139 140
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs
index 1d91165..de29ae9 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs
@@ -48,12 +48,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
48{ 48{
49 [TestFixture] 49 [TestFixture]
50 public class InventoryAccessModuleTests : OpenSimTestCase 50 public class InventoryAccessModuleTests : OpenSimTestCase
51 { 51 {
52 protected TestScene m_scene; 52 protected TestScene m_scene;
53 protected BasicInventoryAccessModule m_iam; 53 protected BasicInventoryAccessModule m_iam;
54 protected UUID m_userId = UUID.Parse("00000000-0000-0000-0000-000000000020"); 54 protected UUID m_userId = UUID.Parse("00000000-0000-0000-0000-000000000020");
55 protected TestClient m_tc; 55 protected TestClient m_tc;
56 56
57 [SetUp] 57 [SetUp]
58 public override void SetUp() 58 public override void SetUp()
59 { 59 {
@@ -68,31 +68,32 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
68 SceneHelpers sceneHelpers = new SceneHelpers(); 68 SceneHelpers sceneHelpers = new SceneHelpers();
69 m_scene = sceneHelpers.SetupScene(); 69 m_scene = sceneHelpers.SetupScene();
70 SceneHelpers.SetupSceneModules(m_scene, config, m_iam); 70 SceneHelpers.SetupSceneModules(m_scene, config, m_iam);
71 71
72 // Create user 72 // Create user
73 string userFirstName = "Jock"; 73 string userFirstName = "Jock";
74 string userLastName = "Stirrup"; 74 string userLastName = "Stirrup";
75 string userPassword = "troll"; 75 string userPassword = "troll";
76 UserAccountHelpers.CreateUserWithInventory(m_scene, userFirstName, userLastName, m_userId, userPassword); 76 UserAccountHelpers.CreateUserWithInventory(m_scene, userFirstName, userLastName, m_userId, userPassword);
77 77
78 AgentCircuitData acd = new AgentCircuitData(); 78 AgentCircuitData acd = new AgentCircuitData();
79 acd.AgentID = m_userId; 79 acd.AgentID = m_userId;
80 m_tc = new TestClient(acd, m_scene); 80 m_tc = new TestClient(acd, m_scene);
81 } 81 }
82 82
83 [Test] 83 [Test]
84 public void TestRezCoalescedObject() 84 public void TestRezCoalescedObject()
85 { 85 {
86/*
86 TestHelpers.InMethod(); 87 TestHelpers.InMethod();
87// log4net.Config.XmlConfigurator.Configure(); 88// log4net.Config.XmlConfigurator.Configure();
88 89
89 // Create asset 90 // Create asset
90 SceneObjectGroup object1 = SceneHelpers.CreateSceneObject(1, m_userId, "Object1", 0x20); 91 SceneObjectGroup object1 = SceneHelpers.CreateSceneObject(1, m_userId, "Object1", 0x20);
91 object1.AbsolutePosition = new Vector3(15, 30, 45); 92 object1.AbsolutePosition = new Vector3(15, 30, 45);
92 93
93 SceneObjectGroup object2 = SceneHelpers.CreateSceneObject(1, m_userId, "Object2", 0x40); 94 SceneObjectGroup object2 = SceneHelpers.CreateSceneObject(1, m_userId, "Object2", 0x40);
94 object2.AbsolutePosition = new Vector3(25, 50, 75); 95 object2.AbsolutePosition = new Vector3(25, 50, 75);
95 96
96 CoalescedSceneObjects coa = new CoalescedSceneObjects(m_userId, object1, object2); 97 CoalescedSceneObjects coa = new CoalescedSceneObjects(m_userId, object1, object2);
97 98
98 UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060"); 99 UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060");
@@ -106,45 +107,46 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
106 item1.Name = item1Name; 107 item1.Name = item1Name;
107 item1.AssetID = asset1.FullID; 108 item1.AssetID = asset1.FullID;
108 item1.ID = item1Id; 109 item1.ID = item1Id;
109 InventoryFolderBase objsFolder 110 InventoryFolderBase objsFolder
110 = InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, m_userId, "Objects")[0]; 111 = InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, m_userId, "Objects")[0];
111 item1.Folder = objsFolder.ID; 112 item1.Folder = objsFolder.ID;
112 item1.Flags |= (uint)InventoryItemFlags.ObjectHasMultipleItems; 113 item1.Flags |= (uint)InventoryItemFlags.ObjectHasMultipleItems;
113 m_scene.AddInventoryItem(item1); 114 m_scene.AddInventoryItem(item1);
114 115
115 SceneObjectGroup so 116 SceneObjectGroup so
116 = m_iam.RezObject( 117 = m_iam.RezObject(
117 m_tc, item1Id, new Vector3(100, 100, 100), Vector3.Zero, UUID.Zero, 1, false, false, false, UUID.Zero, false); 118 m_tc, item1Id, new Vector3(100, 100, 100), Vector3.Zero, UUID.Zero, 1, false, false, false, UUID.Zero, false);
118 119
119 Assert.That(so, Is.Not.Null); 120 Assert.That(so, Is.Not.Null);
120 121
121 Assert.That(m_scene.SceneGraph.GetTotalObjectsCount(), Is.EqualTo(2)); 122 Assert.That(m_scene.SceneGraph.GetTotalObjectsCount(), Is.EqualTo(2));
122 123
123 SceneObjectPart retrievedObj1Part = m_scene.GetSceneObjectPart(object1.Name); 124 SceneObjectPart retrievedObj1Part = m_scene.GetSceneObjectPart(object1.Name);
124 Assert.That(retrievedObj1Part, Is.Null); 125 Assert.That(retrievedObj1Part, Is.Null);
125 126
126 retrievedObj1Part = m_scene.GetSceneObjectPart(item1.Name); 127 retrievedObj1Part = m_scene.GetSceneObjectPart(item1.Name);
127 Assert.That(retrievedObj1Part, Is.Not.Null); 128 Assert.That(retrievedObj1Part, Is.Not.Null);
128 Assert.That(retrievedObj1Part.Name, Is.EqualTo(item1.Name)); 129 Assert.That(retrievedObj1Part.Name, Is.EqualTo(item1.Name));
129 130
130 // Bottom of coalescence is placed on ground, hence we end up with 100.5 rather than 85 since the bottom 131 // Bottom of coalescence is placed on ground, hence we end up with 100.5 rather than 85 since the bottom
131 // object is unit square. 132 // object is unit square.
132 Assert.That(retrievedObj1Part.AbsolutePosition, Is.EqualTo(new Vector3(95, 90, 100.5f))); 133 Assert.That(retrievedObj1Part.AbsolutePosition, Is.EqualTo(new Vector3(95, 90, 100.5f)));
133 134
134 SceneObjectPart retrievedObj2Part = m_scene.GetSceneObjectPart(object2.Name); 135 SceneObjectPart retrievedObj2Part = m_scene.GetSceneObjectPart(object2.Name);
135 Assert.That(retrievedObj2Part, Is.Not.Null); 136 Assert.That(retrievedObj2Part, Is.Not.Null);
136 Assert.That(retrievedObj2Part.Name, Is.EqualTo(object2.Name)); 137 Assert.That(retrievedObj2Part.Name, Is.EqualTo(object2.Name));
137 Assert.That(retrievedObj2Part.AbsolutePosition, Is.EqualTo(new Vector3(105, 110, 130.5f))); 138 Assert.That(retrievedObj2Part.AbsolutePosition, Is.EqualTo(new Vector3(105, 110, 130.5f)));
138 } 139*/
139 140 }
141
140 [Test] 142 [Test]
141 public void TestRezObject() 143 public void TestRezObject()
142 { 144 {
143 TestHelpers.InMethod(); 145 TestHelpers.InMethod();
144// log4net.Config.XmlConfigurator.Configure(); 146// log4net.Config.XmlConfigurator.Configure();
145 147
146 // Create asset 148 // Create asset
147 SceneObjectGroup object1 = SceneHelpers.CreateSceneObject(1, m_userId, "My Little Dog Object", 0x40); 149 SceneObjectGroup object1 = SceneHelpers.CreateSceneObject(1, m_userId, "My Little Dog Object", 0x40);
148 150
149 UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060"); 151 UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060");
150 AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1); 152 AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1);
@@ -157,17 +159,17 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
157 item1.Name = item1Name; 159 item1.Name = item1Name;
158 item1.AssetID = asset1.FullID; 160 item1.AssetID = asset1.FullID;
159 item1.ID = item1Id; 161 item1.ID = item1Id;
160 InventoryFolderBase objsFolder 162 InventoryFolderBase objsFolder
161 = InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, m_userId, "Objects")[0]; 163 = InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, m_userId, "Objects")[0];
162 item1.Folder = objsFolder.ID; 164 item1.Folder = objsFolder.ID;
163 m_scene.AddInventoryItem(item1); 165 m_scene.AddInventoryItem(item1);
164 166
165 SceneObjectGroup so 167 SceneObjectGroup so
166 = m_iam.RezObject( 168 = m_iam.RezObject(
167 m_tc, item1Id, Vector3.Zero, Vector3.Zero, UUID.Zero, 1, false, false, false, UUID.Zero, false); 169 m_tc, item1Id, UUID.Zero, Vector3.Zero, Vector3.Zero, UUID.Zero, 1, false, false, false, UUID.Zero, false);
168 170
169 Assert.That(so, Is.Not.Null); 171 Assert.That(so, Is.Not.Null);
170 172
171 SceneObjectPart retrievedPart = m_scene.GetSceneObjectPart(so.UUID); 173 SceneObjectPart retrievedPart = m_scene.GetSceneObjectPart(so.UUID);
172 Assert.That(retrievedPart, Is.Not.Null); 174 Assert.That(retrievedPart, Is.Not.Null);
173 } 175 }
diff --git a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs
index 862f0b7..5d77201 100644
--- a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs
@@ -126,7 +126,7 @@ namespace OpenSim.Region.CoreModules.Framework.Library
126 return; 126 return;
127 127
128 // This will never run more than once, even if the region is restarted 128 // This will never run more than once, even if the region is restarted
129 if (!m_HasRunOnce) 129 if (!m_HasRunOnce)
130 { 130 {
131 LoadLibrariesFromArchives(); 131 LoadLibrariesFromArchives();
132 //DumpLibrary(); 132 //DumpLibrary();
@@ -178,7 +178,7 @@ namespace OpenSim.Region.CoreModules.Framework.Library
178 InventoryArchiveReadRequest archread = new InventoryArchiveReadRequest(m_MockScene.InventoryService, m_MockScene.AssetService, m_MockScene.UserAccountService, uinfo, simpleName, iarFileName, false); 178 InventoryArchiveReadRequest archread = new InventoryArchiveReadRequest(m_MockScene.InventoryService, m_MockScene.AssetService, m_MockScene.UserAccountService, uinfo, simpleName, iarFileName, false);
179 try 179 try
180 { 180 {
181 HashSet<InventoryNodeBase> nodes = archread.Execute(); 181 Dictionary<UUID, InventoryNodeBase> nodes = archread.Execute();
182 if (nodes != null && nodes.Count == 0) 182 if (nodes != null && nodes.Count == 0)
183 { 183 {
184 // didn't find the subfolder with the given name; place it on the top 184 // didn't find the subfolder with the given name; place it on the top
@@ -188,7 +188,7 @@ namespace OpenSim.Region.CoreModules.Framework.Library
188 archread.Execute(); 188 archread.Execute();
189 } 189 }
190 190
191 foreach (InventoryNodeBase node in nodes) 191 foreach (InventoryNodeBase node in nodes.Values)
192 FixPerms(node); 192 FixPerms(node);
193 } 193 }
194 catch (Exception e) 194 catch (Exception e)
diff --git a/OpenSim/Region/CoreModules/Framework/Library/LocalInventoryService.cs b/OpenSim/Region/CoreModules/Framework/Library/LocalInventoryService.cs
index e1e1838..c1a9457 100644
--- a/OpenSim/Region/CoreModules/Framework/Library/LocalInventoryService.cs
+++ b/OpenSim/Region/CoreModules/Framework/Library/LocalInventoryService.cs
@@ -103,13 +103,8 @@ namespace OpenSim.Region.CoreModules.Framework.Library
103 { 103 {
104 InventoryItemBase[] itemColl = new InventoryItemBase[itemIDs.Length]; 104 InventoryItemBase[] itemColl = new InventoryItemBase[itemIDs.Length];
105 int i = 0; 105 int i = 0;
106 InventoryItemBase item = new InventoryItemBase();
107 item.Owner = principalID;
108 foreach (UUID fid in itemIDs) 106 foreach (UUID fid in itemIDs)
109 { 107 itemColl[i++] = GetItem(principalID, fid);
110 item.ID = fid;
111 itemColl[i++] = GetItem(item);
112 }
113 108
114 return itemColl; 109 return itemColl;
115 } 110 }
@@ -239,14 +234,14 @@ namespace OpenSim.Region.CoreModules.Framework.Library
239 /// </summary> 234 /// </summary>
240 /// <param name="item"></param> 235 /// <param name="item"></param>
241 /// <returns></returns> 236 /// <returns></returns>
242 public InventoryItemBase GetItem(InventoryItemBase item) { return null; } 237 public InventoryItemBase GetItem(UUID principalID, UUID itemID) { return null; }
243 238
244 /// <summary> 239 /// <summary>
245 /// Get a folder, given by its UUID 240 /// Get a folder, given by its UUID
246 /// </summary> 241 /// </summary>
247 /// <param name="folder"></param> 242 /// <param name="folder"></param>
248 /// <returns></returns> 243 /// <returns></returns>
249 public InventoryFolderBase GetFolder(InventoryFolderBase folder) { return null; } 244 public InventoryFolderBase GetFolder(UUID principalID, UUID folderID) { return null; }
250 245
251 /// <summary> 246 /// <summary>
252 /// Does the given user have an inventory structure? 247 /// Does the given user have an inventory structure?
@@ -264,11 +259,11 @@ namespace OpenSim.Region.CoreModules.Framework.Library
264 259
265 /// <summary> 260 /// <summary>
266 /// Get the union of permissions of all inventory items 261 /// Get the union of permissions of all inventory items
267 /// that hold the given assetID. 262 /// that hold the given assetID.
268 /// </summary> 263 /// </summary>
269 /// <param name="userID"></param> 264 /// <param name="userID"></param>
270 /// <param name="assetID"></param> 265 /// <param name="assetID"></param>
271 /// <returns>The permissions or 0 if no such asset is found in 266 /// <returns>The permissions or 0 if no such asset is found in
272 /// the user's inventory</returns> 267 /// the user's inventory</returns>
273 public int GetAssetPermissions(UUID userID, UUID assetID) { return 0; } 268 public int GetAssetPermissions(UUID userID, UUID assetID) { return 0; }
274 } 269 }
diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs
index 64feec1..fb3d31c 100644
--- a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs
@@ -44,7 +44,7 @@ using Mono.Addins;
44namespace OpenSim.Region.CoreModules.Framework.Monitoring 44namespace OpenSim.Region.CoreModules.Framework.Monitoring
45{ 45{
46 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "MonitorModule")] 46 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "MonitorModule")]
47 public class MonitorModule : INonSharedRegionModule 47 public class MonitorModule : INonSharedRegionModule
48 { 48 {
49 /// <summary> 49 /// <summary>
50 /// Is this module enabled? 50 /// Is this module enabled?
@@ -78,7 +78,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
78 78
79 if (cnfg != null) 79 if (cnfg != null)
80 Enabled = cnfg.GetBoolean("Enabled", true); 80 Enabled = cnfg.GetBoolean("Enabled", true);
81 81
82 if (!Enabled) 82 if (!Enabled)
83 return; 83 return;
84 84
@@ -205,7 +205,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
205 m_scene, 205 m_scene,
206 "ScriptEventsPerSecondMonitor", 206 "ScriptEventsPerSecondMonitor",
207 "Script Events", 207 "Script Events",
208 m => m.Scene.StatsReporter.LastReportedSimStats[20], 208 m => m.Scene.StatsReporter.LastReportedSimStats[23],
209 m => string.Format("{0} per second", m.GetValue()))); 209 m => string.Format("{0} per second", m.GetValue())));
210 210
211 m_staticMonitors.Add( 211 m_staticMonitors.Add(
@@ -301,7 +301,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
301 m_scene, 301 m_scene,
302 "SpareFrameTimeMonitor", 302 "SpareFrameTimeMonitor",
303 "Spare Frame Time", 303 "Spare Frame Time",
304 m => m.Scene.StatsReporter.LastReportedSimStats[21], 304 m => m.Scene.StatsReporter.LastReportedSimStats[38],
305 m => string.Format("{0} ms", m.GetValue()))); 305 m => string.Format("{0} ms", m.GetValue())));
306 306
307 m_alerts.Add(new DeadlockAlert(m_staticMonitors.Find(x => x is LastFrameTimeMonitor) as LastFrameTimeMonitor)); 307 m_alerts.Add(new DeadlockAlert(m_staticMonitors.Find(x => x is LastFrameTimeMonitor) as LastFrameTimeMonitor));
@@ -433,7 +433,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
433 MakeStat("ScriptLines", "lines/sec", (s) => { s.Value = m_scene.StatsReporter.LastReportedSimStats[20]; }); 433 MakeStat("ScriptLines", "lines/sec", (s) => { s.Value = m_scene.StatsReporter.LastReportedSimStats[20]; });
434 MakeStat("SimSpareMS", "ms/sec", (s) => { s.Value = m_scene.StatsReporter.LastReportedSimStats[21]; }); 434 MakeStat("SimSpareMS", "ms/sec", (s) => { s.Value = m_scene.StatsReporter.LastReportedSimStats[21]; });
435 } 435 }
436 436
437 private void UnRegisterStatsManagerRegionStatistics() 437 private void UnRegisterStatsManagerRegionStatistics()
438 { 438 {
439 foreach (Stat stat in registeredStats) 439 foreach (Stat stat in registeredStats)
@@ -443,6 +443,6 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
443 } 443 }
444 registeredStats.Clear(); 444 registeredStats.Clear();
445 } 445 }
446 446
447 } 447 }
448} \ No newline at end of file 448} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Framework/Search/BasicSearchModule.cs b/OpenSim/Region/CoreModules/Framework/Search/BasicSearchModule.cs
index 3849996..c04d856 100644
--- a/OpenSim/Region/CoreModules/Framework/Search/BasicSearchModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Search/BasicSearchModule.cs
@@ -135,7 +135,7 @@ namespace OpenSim.Region.CoreModules.Framework.Search
135 135
136 #endregion ISharedRegionModule 136 #endregion ISharedRegionModule
137 137
138 138
139 #region Event Handlers 139 #region Event Handlers
140 140
141 void EventManager_OnMakeRootAgent(ScenePresence sp) 141 void EventManager_OnMakeRootAgent(ScenePresence sp)
diff --git a/OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs b/OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs
index 3abacbd..2c74c0e 100644
--- a/OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs
@@ -48,31 +48,16 @@ namespace OpenSim.Region.CoreModules.Framework
48 MethodBase.GetCurrentMethod().DeclaringType); 48 MethodBase.GetCurrentMethod().DeclaringType);
49 49
50 private readonly List<Scene> m_scenes = new List<Scene>(); 50 private readonly List<Scene> m_scenes = new List<Scene>();
51 private System.Timers.Timer m_timer = new System.Timers.Timer(); 51 private JobEngine m_processorJobEngine;
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 52
57 #region ISharedRegionModule 53 #region ISharedRegionModule
58 54
59 public void Initialise(IConfigSource config) 55 public void Initialise(IConfigSource config)
60 { 56 {
61 m_Interval = Util.GetConfigVarFromSections<int>(config, "Interval", new string[] { "ServiceThrottle" }, 5000); 57 m_processorJobEngine = new JobEngine(
62 58 "ServiceThrottle","ServiceThrottle");
63 m_timer = new System.Timers.Timer(); 59 m_processorJobEngine.RequestProcessTimeoutOnStop = 31000; // many webrequests have 30s expire
64 m_timer.AutoReset = false; 60 m_processorJobEngine.Start();
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 //WorkManager.StartThread(
71 // ProcessQueue,
72 // "GridServiceRequestThread",
73 // ThreadPriority.BelowNormal,
74 // true,
75 // false);
76 } 61 }
77 62
78 public void AddRegion(Scene scene) 63 public void AddRegion(Scene scene)
@@ -82,7 +67,6 @@ namespace OpenSim.Region.CoreModules.Framework
82 m_scenes.Add(scene); 67 m_scenes.Add(scene);
83 scene.RegisterModuleInterface<IServiceThrottleModule>(this); 68 scene.RegisterModuleInterface<IServiceThrottleModule>(this);
84 scene.EventManager.OnNewClient += OnNewClient; 69 scene.EventManager.OnNewClient += OnNewClient;
85 scene.EventManager.OnMakeRootAgent += OnMakeRootAgent;
86 } 70 }
87 } 71 }
88 72
@@ -105,6 +89,7 @@ namespace OpenSim.Region.CoreModules.Framework
105 89
106 public void Close() 90 public void Close()
107 { 91 {
92 m_processorJobEngine.Stop();
108 } 93 }
109 94
110 public string Name 95 public string Name
@@ -126,38 +111,32 @@ namespace OpenSim.Region.CoreModules.Framework
126 client.OnRegionHandleRequest += OnRegionHandleRequest; 111 client.OnRegionHandleRequest += OnRegionHandleRequest;
127 } 112 }
128 113
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) 114 public void OnRegionHandleRequest(IClientAPI client, UUID regionID)
143 { 115 {
144 //m_log.DebugFormat("[SERVICE THROTTLE]: RegionHandleRequest {0}", regionID); 116 //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 117 Action action = delegate
153 { 118 {
154 GridRegion r = m_scenes[0].GridService.GetRegionByUUID(UUID.Zero, regionID); 119 if(!client.IsActive)
120 return;
121
122 if(m_scenes.Count == 0)
123 return;
124
125 Scene baseScene = m_scenes[0];
126
127 if(baseScene == null || baseScene.ShuttingDown)
128 return;
129
130 GridRegion r = baseScene.GridService.GetRegionByUUID(UUID.Zero, regionID);
131
132 if(!client.IsActive)
133 return;
155 134
156 if (r != null && r.RegionHandle != 0) 135 if (r != null && r.RegionHandle != 0)
157 client.SendRegionHandle(regionID, r.RegionHandle); 136 client.SendRegionHandle(regionID, r.RegionHandle);
158 }; 137 };
159 138
160 Enqueue("region", regionID.ToString(), action); 139 m_processorJobEngine.QueueJob("regionHandle", action, regionID.ToString());
161 } 140 }
162 141
163 #endregion Events 142 #endregion Events
@@ -166,91 +145,10 @@ namespace OpenSim.Region.CoreModules.Framework
166 145
167 public void Enqueue(string category, string itemid, Action continuation) 146 public void Enqueue(string category, string itemid, Action continuation)
168 { 147 {
169 lock (m_RequestQueue) 148 m_processorJobEngine.QueueJob(category, continuation, itemid);
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 } 149 }
191 150
192 #endregion IServiceThrottleModule 151 #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 } 152 }
255 153
256} 154}
diff --git a/OpenSim/Region/CoreModules/Framework/Statistics/Logging/BinaryLoggingModule.cs b/OpenSim/Region/CoreModules/Framework/Statistics/Logging/BinaryLoggingModule.cs
index f3436d1..3e6c8b5 100644
--- a/OpenSim/Region/CoreModules/Framework/Statistics/Logging/BinaryLoggingModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Statistics/Logging/BinaryLoggingModule.cs
@@ -45,14 +45,14 @@ namespace OpenSim.Region.CoreModules.Framework.Statistics.Logging
45 public class BinaryLoggingModule : INonSharedRegionModule 45 public class BinaryLoggingModule : 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 protected bool m_collectStats; 49 protected bool m_collectStats;
50 protected Scene m_scene = null; 50 protected Scene m_scene = null;
51 51
52 public string Name { get { return "Binary Statistics Logging Module"; } } 52 public string Name { get { return "Binary Statistics Logging Module"; } }
53 public Type ReplaceableInterface { get { return null; } } 53 public Type ReplaceableInterface { get { return null; } }
54 54
55 public void Initialise(IConfigSource source) 55 public void Initialise(IConfigSource source)
56 { 56 {
57 try 57 try
58 { 58 {
@@ -81,23 +81,23 @@ namespace OpenSim.Region.CoreModules.Framework.Statistics.Logging
81 // if it doesn't work, we don't collect anything 81 // if it doesn't work, we don't collect anything
82 } 82 }
83 } 83 }
84 84
85 public void AddRegion(Scene scene) 85 public void AddRegion(Scene scene)
86 { 86 {
87 m_scene = scene; 87 m_scene = scene;
88 } 88 }
89 89
90 public void RemoveRegion(Scene scene) 90 public void RemoveRegion(Scene scene)
91 { 91 {
92 } 92 }
93 93
94 public void RegionLoaded(Scene scene) 94 public void RegionLoaded(Scene scene)
95 { 95 {
96 if (m_collectStats) 96 if (m_collectStats)
97 m_scene.StatsReporter.OnSendStatsResult += LogSimStats; 97 m_scene.StatsReporter.OnSendStatsResult += LogSimStats;
98 } 98 }
99 99
100 public void Close() 100 public void Close()
101 { 101 {
102 } 102 }
103 103
@@ -107,12 +107,12 @@ namespace OpenSim.Region.CoreModules.Framework.Statistics.Logging
107 public string Path; 107 public string Path;
108 public System.IO.BinaryWriter Log; 108 public System.IO.BinaryWriter Log;
109 } 109 }
110 110
111 static StatLogger m_statLog = null; 111 static StatLogger m_statLog = null;
112 static TimeSpan m_statLogPeriod = TimeSpan.FromSeconds(300); 112 static TimeSpan m_statLogPeriod = TimeSpan.FromSeconds(300);
113 static string m_statsDir = String.Empty; 113 static string m_statsDir = String.Empty;
114 static Object m_statLockObject = new Object(); 114 static Object m_statLockObject = new Object();
115 115
116 private void LogSimStats(SimStats stats) 116 private void LogSimStats(SimStats stats)
117 { 117 {
118 SimStatsPacket pack = new SimStatsPacket(); 118 SimStatsPacket pack = new SimStatsPacket();
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs
index 7b89c2c..3e0a610 100644
--- a/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs
@@ -52,7 +52,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
52 52
53 #region ISharedRegionModule 53 #region ISharedRegionModule
54 54
55 public new void Initialise(IConfigSource config) 55 public override void Initialise(IConfigSource config)
56 { 56 {
57 string umanmod = config.Configs["Modules"].GetString("UserManagementModule", null); 57 string umanmod = config.Configs["Modules"].GetString("UserManagementModule", null);
58 if (umanmod == Name) 58 if (umanmod == Name)
@@ -111,7 +111,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
111 } 111 }
112 112
113 // This is it! Let's ask the other world 113 // This is it! Let's ask the other world
114 if (words[0].Contains(".")) 114 if (words[0].Contains("."))
115 { 115 {
116 string[] names = words[0].Split(new char[] { '.' }); 116 string[] names = words[0].Split(new char[] { '.' });
117 if (names.Length >= 2) 117 if (names.Length >= 2)
@@ -130,7 +130,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
130 } 130 }
131 131
132 UserAgentServiceConnector uasConn = new UserAgentServiceConnector(uriStr); 132 UserAgentServiceConnector uasConn = new UserAgentServiceConnector(uriStr);
133 133
134 UUID userID = UUID.Zero; 134 UUID userID = UUID.Zero;
135 try 135 try
136 { 136 {
@@ -140,7 +140,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
140 { 140 {
141 m_log.Debug("[USER MANAGEMENT MODULE]: GetUUID call failed ", e); 141 m_log.Debug("[USER MANAGEMENT MODULE]: GetUUID call failed ", e);
142 } 142 }
143 143
144 if (!userID.Equals(UUID.Zero)) 144 if (!userID.Equals(UUID.Zero))
145 { 145 {
146 UserData ud = new UserData(); 146 UserData ud = new UserData();
@@ -163,8 +163,8 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
163 //{ 163 //{
164 // foreach (UserData d in m_UserCache.Values) 164 // foreach (UserData d in m_UserCache.Values)
165 // { 165 // {
166 // if (d.LastName.StartsWith("@") && 166 // if (d.LastName.StartsWith("@") &&
167 // (d.FirstName.ToLower().StartsWith(query.ToLower()) || 167 // (d.FirstName.ToLower().StartsWith(query.ToLower()) ||
168 // d.LastName.ToLower().StartsWith(query.ToLower()))) 168 // d.LastName.ToLower().StartsWith(query.ToLower())))
169 // users.Add(d); 169 // users.Add(d);
170 // } 170 // }
@@ -172,4 +172,4 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
172 } 172 }
173 173
174 } 174 }
175} \ No newline at end of file 175}
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/Tests/HGUserManagementModuleTests.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/Tests/HGUserManagementModuleTests.cs
index 4e3b7e5..9d91aa3 100644
--- a/OpenSim/Region/CoreModules/Framework/UserManagement/Tests/HGUserManagementModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/Tests/HGUserManagementModuleTests.cs
@@ -37,7 +37,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement.Tests
37{ 37{
38 [TestFixture] 38 [TestFixture]
39 public class HGUserManagementModuleTests : OpenSimTestCase 39 public class HGUserManagementModuleTests : OpenSimTestCase
40 { 40 {
41 /// <summary> 41 /// <summary>
42 /// Test that a new HG agent (i.e. one without a user account) has their name cached in the UMM upon creation. 42 /// Test that a new HG agent (i.e. one without a user account) has their name cached in the UMM upon creation.
43 /// </summary> 43 /// </summary>
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
index 7ecbd26..2695464 100644
--- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
@@ -66,7 +66,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
66 66
67 #region ISharedRegionModule 67 #region ISharedRegionModule
68 68
69 public void Initialise(IConfigSource config) 69 public virtual void Initialise(IConfigSource config)
70 { 70 {
71 string umanmod = config.Configs["Modules"].GetString("UserManagementModule", Name); 71 string umanmod = config.Configs["Modules"].GetString("UserManagementModule", Name);
72 if (umanmod == Name) 72 if (umanmod == Name)
@@ -88,7 +88,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
88 m_DisplayChangingHomeURI = userManagementConfig.GetBoolean("DisplayChangingHomeURI", false); 88 m_DisplayChangingHomeURI = userManagementConfig.GetBoolean("DisplayChangingHomeURI", false);
89 } 89 }
90 90
91 public bool IsSharedModule 91 public virtual bool IsSharedModule
92 { 92 {
93 get { return true; } 93 get { return true; }
94 } 94 }
@@ -98,12 +98,12 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
98 get { return "BasicUserManagementModule"; } 98 get { return "BasicUserManagementModule"; }
99 } 99 }
100 100
101 public Type ReplaceableInterface 101 public virtual Type ReplaceableInterface
102 { 102 {
103 get { return null; } 103 get { return null; }
104 } 104 }
105 105
106 public void AddRegion(Scene scene) 106 public virtual void AddRegion(Scene scene)
107 { 107 {
108 if (m_Enabled) 108 if (m_Enabled)
109 { 109 {
@@ -119,7 +119,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
119 } 119 }
120 } 120 }
121 121
122 public void RemoveRegion(Scene scene) 122 public virtual void RemoveRegion(Scene scene)
123 { 123 {
124 if (m_Enabled) 124 if (m_Enabled)
125 { 125 {
@@ -131,17 +131,17 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
131 } 131 }
132 } 132 }
133 133
134 public void RegionLoaded(Scene s) 134 public virtual void RegionLoaded(Scene s)
135 { 135 {
136 if (m_Enabled && m_ServiceThrottle == null) 136 if (m_Enabled && m_ServiceThrottle == null)
137 m_ServiceThrottle = s.RequestModuleInterface<IServiceThrottleModule>(); 137 m_ServiceThrottle = s.RequestModuleInterface<IServiceThrottleModule>();
138 } 138 }
139 139
140 public void PostInitialise() 140 public virtual void PostInitialise()
141 { 141 {
142 } 142 }
143 143
144 public void Close() 144 public virtual void Close()
145 { 145 {
146 lock (m_Scenes) 146 lock (m_Scenes)
147 { 147 {
@@ -157,31 +157,34 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
157 157
158 #region Event Handlers 158 #region Event Handlers
159 159
160 void EventManager_OnPrimsLoaded(Scene s) 160 protected virtual void EventManager_OnPrimsLoaded(Scene s)
161 { 161 {
162 // let's sniff all the user names referenced by objects in the scene 162 // let's sniff all the user names referenced by objects in the scene
163 m_log.DebugFormat("[USER MANAGEMENT MODULE]: Caching creators' data from {0} ({1} objects)...", s.RegionInfo.RegionName, s.GetEntities().Length); 163 m_log.DebugFormat("[USER MANAGEMENT MODULE]: Caching creators' data from {0} ({1} objects)...", s.RegionInfo.RegionName, s.GetEntities().Length);
164 s.ForEachSOG(delegate(SceneObjectGroup sog) { CacheCreators(sog); }); 164 s.ForEachSOG(delegate(SceneObjectGroup sog) { CacheCreators(sog); });
165 } 165 }
166 166
167 void EventManager_OnNewClient(IClientAPI client) 167 protected virtual void EventManager_OnNewClient(IClientAPI client)
168 { 168 {
169 client.OnConnectionClosed += new Action<IClientAPI>(HandleConnectionClosed); 169 client.OnConnectionClosed += new Action<IClientAPI>(HandleConnectionClosed);
170 client.OnNameFromUUIDRequest += new UUIDNameRequest(HandleUUIDNameRequest); 170 client.OnNameFromUUIDRequest += new UUIDNameRequest(HandleUUIDNameRequest);
171 client.OnAvatarPickerRequest += new AvatarPickerRequest(HandleAvatarPickerRequest); 171 client.OnAvatarPickerRequest += new AvatarPickerRequest(HandleAvatarPickerRequest);
172 } 172 }
173 173
174 void HandleConnectionClosed(IClientAPI client) 174 protected virtual void HandleConnectionClosed(IClientAPI client)
175 { 175 {
176 client.OnNameFromUUIDRequest -= new UUIDNameRequest(HandleUUIDNameRequest); 176 client.OnNameFromUUIDRequest -= new UUIDNameRequest(HandleUUIDNameRequest);
177 client.OnAvatarPickerRequest -= new AvatarPickerRequest(HandleAvatarPickerRequest); 177 client.OnAvatarPickerRequest -= new AvatarPickerRequest(HandleAvatarPickerRequest);
178 client.OnConnectionClosed -= new Action<IClientAPI>(HandleConnectionClosed);
178 } 179 }
179 180
180 void HandleUUIDNameRequest(UUID uuid, IClientAPI client) 181 protected virtual void HandleUUIDNameRequest(UUID uuid, IClientAPI client)
181 { 182 {
182// m_log.DebugFormat( 183// m_log.DebugFormat(
183// "[USER MANAGEMENT MODULE]: Handling request for name binding of UUID {0} from {1}", 184// "[USER MANAGEMENT MODULE]: Handling request for name binding of UUID {0} from {1}",
184// uuid, remote_client.Name); 185// uuid, remote_client.Name);
186 if(m_Scenes.Count <= 0)
187 return;
185 188
186 if (m_Scenes[0].LibraryService != null && (m_Scenes[0].LibraryService.LibraryRootFolder.Owner == uuid)) 189 if (m_Scenes[0].LibraryService != null && (m_Scenes[0].LibraryService.LibraryRootFolder.Owner == uuid))
187 { 190 {
@@ -204,7 +207,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
204 } 207 }
205 208
206 // Not found in cache, queue continuation 209 // Not found in cache, queue continuation
207 m_ServiceThrottle.Enqueue("name", uuid.ToString(), delegate 210 m_ServiceThrottle.Enqueue("uuidname", uuid.ToString(), delegate
208 { 211 {
209 //m_log.DebugFormat("[YYY]: Name request {0}", uuid); 212 //m_log.DebugFormat("[YYY]: Name request {0}", uuid);
210 213
@@ -214,9 +217,12 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
214 // So to avoid clients 217 // So to avoid clients
215 // (particularly Hypergrid clients) permanently binding "Unknown User" to a given UUID, we will 218 // (particularly Hypergrid clients) permanently binding "Unknown User" to a given UUID, we will
216 // instead drop the request entirely. 219 // instead drop the request entirely.
220 if(!client.IsActive)
221 return;
217 if (GetUser(uuid, out user)) 222 if (GetUser(uuid, out user))
218 { 223 {
219 client.SendNameReply(uuid, user.FirstName, user.LastName); 224 if(client.IsActive)
225 client.SendNameReply(uuid, user.FirstName, user.LastName);
220 } 226 }
221// else 227// else
222// m_log.DebugFormat( 228// m_log.DebugFormat(
@@ -226,7 +232,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
226 } 232 }
227 } 233 }
228 234
229 public void HandleAvatarPickerRequest(IClientAPI client, UUID avatarID, UUID RequestID, string query) 235 public virtual void HandleAvatarPickerRequest(IClientAPI client, UUID avatarID, UUID RequestID, string query)
230 { 236 {
231 //EventManager.TriggerAvatarPickerRequest(); 237 //EventManager.TriggerAvatarPickerRequest();
232 238
@@ -286,8 +292,11 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
286 292
287 #region IPeople 293 #region IPeople
288 294
289 public List<UserData> GetUserData(string query, int page_size, int page_number) 295 public virtual List<UserData> GetUserData(string query, int page_size, int page_number)
290 { 296 {
297 if(m_Scenes.Count <= 0)
298 return new List<UserData>();;
299
291 // search the user accounts service 300 // search the user accounts service
292 List<UserAccount> accs = m_Scenes[0].UserAccountService.GetUserAccounts(m_Scenes[0].RegionInfo.ScopeID, query); 301 List<UserAccount> accs = m_Scenes[0].UserAccountService.GetUserAccounts(m_Scenes[0].RegionInfo.ScopeID, query);
293 302
@@ -323,7 +332,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
323 332
324 #endregion IPeople 333 #endregion IPeople
325 334
326 private void CacheCreators(SceneObjectGroup sog) 335 protected virtual void CacheCreators(SceneObjectGroup sog)
327 { 336 {
328 //m_log.DebugFormat("[USER MANAGEMENT MODULE]: processing {0} {1}; {2}", sog.RootPart.Name, sog.RootPart.CreatorData, sog.RootPart.CreatorIdentification); 337 //m_log.DebugFormat("[USER MANAGEMENT MODULE]: processing {0} {1}; {2}", sog.RootPart.Name, sog.RootPart.CreatorData, sog.RootPart.CreatorIdentification);
329 AddUser(sog.RootPart.CreatorID, sog.RootPart.CreatorData); 338 AddUser(sog.RootPart.CreatorID, sog.RootPart.CreatorData);
@@ -336,9 +345,108 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
336 } 345 }
337 } 346 }
338 347
348 /// <summary>
349 ///
350 /// </summary>
351 /// <param name="uuid"></param>
352 /// <param name="names">Caller please provide a properly instantiated array for names, string[2]</param>
353 /// <returns></returns>
354 protected virtual bool TryGetUserNames(UUID uuid, string[] names)
355 {
356 if (names == null)
357 names = new string[2];
358
359 if (TryGetUserNamesFromCache(uuid, names))
360 return true;
361
362 if (TryGetUserNamesFromServices(uuid, names))
363 return true;
364
365 return false;
366 }
367
368 protected virtual bool TryGetUserNamesFromCache(UUID uuid, string[] names)
369 {
370 lock (m_UserCache)
371 {
372 if (m_UserCache.ContainsKey(uuid))
373 {
374 names[0] = m_UserCache[uuid].FirstName;
375 names[1] = m_UserCache[uuid].LastName;
376
377 return true;
378 }
379 }
380
381 return false;
382 }
383
384 /// <summary>
385 /// Try to get the names bound to the given uuid, from the services.
386 /// </summary>
387 /// <returns>True if the name was found, false if not.</returns>
388 /// <param name='uuid'></param>
389 /// <param name='names'>The array of names if found. If not found, then names[0] = "Unknown" and names[1] = "User"</param>
390 protected virtual bool TryGetUserNamesFromServices(UUID uuid, string[] names)
391 {
392 if(m_Scenes.Count <= 0)
393 return false;
394
395 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(UUID.Zero, uuid);
396
397 if (account != null)
398 {
399 names[0] = account.FirstName;
400 names[1] = account.LastName;
401
402 UserData user = new UserData();
403 user.FirstName = account.FirstName;
404 user.LastName = account.LastName;
405
406 lock (m_UserCache)
407 m_UserCache[uuid] = user;
408
409 return true;
410 }
411 else
412 {
413 // Let's try the GridUser service
414 GridUserInfo uInfo = m_Scenes[0].GridUserService.GetGridUserInfo(uuid.ToString());
415 if (uInfo != null)
416 {
417 string url, first, last, tmp;
418 UUID u;
419 if (Util.ParseUniversalUserIdentifier(uInfo.UserID, out u, out url, out first, out last, out tmp))
420 {
421 AddUser(uuid, first, last, url);
422
423 if (m_UserCache.ContainsKey(uuid))
424 {
425 names[0] = m_UserCache[uuid].FirstName;
426 names[1] = m_UserCache[uuid].LastName;
427
428 return true;
429 }
430 }
431 else
432 m_log.DebugFormat("[USER MANAGEMENT MODULE]: Unable to parse UUI {0}", uInfo.UserID);
433 }
434// else
435// {
436// m_log.DebugFormat("[USER MANAGEMENT MODULE]: No grid user found for {0}", uuid);
437// }
438
439 names[0] = "Unknown";
440 names[1] = "UserUMMTGUN9";
441
442 return false;
443 }
444 }
445
446
339 #region IUserManagement 447 #region IUserManagement
340 448
341 public UUID GetUserIdByName(string name) 449 public virtual UUID GetUserIdByName(string name)
342 { 450 {
343 string[] parts = name.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries); 451 string[] parts = name.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
344 if (parts.Length < 2) 452 if (parts.Length < 2)
@@ -347,8 +455,11 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
347 return GetUserIdByName(parts[0], parts[1]); 455 return GetUserIdByName(parts[0], parts[1]);
348 } 456 }
349 457
350 public UUID GetUserIdByName(string firstName, string lastName) 458 public virtual UUID GetUserIdByName(string firstName, string lastName)
351 { 459 {
460 if(m_Scenes.Count <= 0)
461 return UUID.Zero;
462
352 // TODO: Optimize for reverse lookup if this gets used by non-console commands. 463 // TODO: Optimize for reverse lookup if this gets used by non-console commands.
353 lock (m_UserCache) 464 lock (m_UserCache)
354 { 465 {
@@ -367,14 +478,159 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
367 return UUID.Zero; 478 return UUID.Zero;
368 } 479 }
369 480
370 public string GetUserName(UUID uuid) 481 public virtual string GetUserName(UUID uuid)
371 { 482 {
372 UserData user; 483 UserData user;
373 GetUser(uuid, out user); 484 GetUser(uuid, out user);
374 return user.FirstName + " " + user.LastName; 485 return user.FirstName + " " + user.LastName;
375 } 486 }
376 487
377 public string GetUserHomeURL(UUID userID) 488 public virtual Dictionary<UUID,string> GetUsersNames(string[] ids)
489 {
490 Dictionary<UUID,string> ret = new Dictionary<UUID,string>();
491 if(m_Scenes.Count <= 0)
492 return ret;
493
494 List<string> missing = new List<string>();
495 Dictionary<UUID,string> untried = new Dictionary<UUID, string>();
496
497 // look in cache
498 UserData userdata = new UserData();
499
500 UUID uuid = UUID.Zero;
501 foreach(string id in ids)
502 {
503 if(UUID.TryParse(id, out uuid))
504 {
505 lock (m_UserCache)
506 {
507 if (m_UserCache.TryGetValue(uuid, out userdata) &&
508 userdata.FirstName != "Unknown" && userdata.FirstName != string.Empty)
509 {
510 string name = userdata.FirstName + " " + userdata.LastName;
511
512 if(userdata.HasGridUserTried)
513 ret[uuid] = name;
514 else
515 {
516 untried[uuid] = name;
517 missing.Add(id);
518 }
519 }
520 else
521 missing.Add(id);
522 }
523 }
524 }
525
526 if(missing.Count == 0)
527 return ret;
528
529 // try user account service
530 List<UserAccount> accounts = m_Scenes[0].UserAccountService.GetUserAccounts(
531 m_Scenes[0].RegionInfo.ScopeID, missing);
532
533 if(accounts.Count != 0)
534 {
535 foreach(UserAccount uac in accounts)
536 {
537 if(uac != null)
538 {
539 string name = uac.FirstName + " " + uac.LastName;
540 ret[uac.PrincipalID] = name;
541 missing.Remove(uac.PrincipalID.ToString()); // slowww
542 untried.Remove(uac.PrincipalID);
543
544 userdata = new UserData();
545 userdata.Id = uac.PrincipalID;
546 userdata.FirstName = uac.FirstName;
547 userdata.LastName = uac.LastName;
548 userdata.HomeURL = string.Empty;
549 userdata.IsUnknownUser = false;
550 userdata.HasGridUserTried = true;
551 lock (m_UserCache)
552 m_UserCache[uac.PrincipalID] = userdata;
553 }
554 }
555 }
556
557 if (missing.Count == 0 || m_Scenes[0].GridUserService == null)
558 return ret;
559
560 // try grid user service
561
562 GridUserInfo[] pinfos = m_Scenes[0].GridUserService.GetGridUserInfo(missing.ToArray());
563 if(pinfos.Length > 0)
564 {
565 foreach(GridUserInfo uInfo in pinfos)
566 {
567 if (uInfo != null)
568 {
569 string url, first, last, tmp;
570
571 if(uInfo.UserID.Length <= 36)
572 continue;
573
574 if (Util.ParseUniversalUserIdentifier(uInfo.UserID, out uuid, out url, out first, out last, out tmp))
575 {
576 if (url != string.Empty)
577 {
578 try
579 {
580 userdata = new UserData();
581 userdata.FirstName = first.Replace(" ", ".") + "." + last.Replace(" ", ".");
582 userdata.LastName = "@" + new Uri(url).Authority;
583 userdata.Id = uuid;
584 userdata.HomeURL = url;
585 userdata.IsUnknownUser = false;
586 userdata.HasGridUserTried = true;
587 lock (m_UserCache)
588 m_UserCache[uuid] = userdata;
589
590 string name = userdata.FirstName + " " + userdata.LastName;
591 ret[uuid] = name;
592 missing.Remove(uuid.ToString());
593 untried.Remove(uuid);
594 }
595 catch
596 {
597 }
598 }
599 }
600 }
601 }
602 }
603
604 // add the untried in cache that still failed
605 if(untried.Count > 0)
606 {
607 foreach(KeyValuePair<UUID, string> kvp in untried)
608 {
609 ret[kvp.Key] = kvp.Value;
610 missing.Remove((kvp.Key).ToString());
611 }
612 }
613
614 // add the UMMthings ( not sure we should)
615 if(missing.Count > 0)
616 {
617 foreach(string id in missing)
618 {
619 if(UUID.TryParse(id, out uuid) && uuid != UUID.Zero)
620 {
621 if (m_Scenes[0].LibraryService != null &&
622 (m_Scenes[0].LibraryService.LibraryRootFolder.Owner == uuid))
623 ret[uuid] = "Mr OpenSim";
624 else
625 ret[uuid] = "Unknown UserUMMAU43";
626 }
627 }
628 }
629
630 return ret;
631 }
632
633 public virtual string GetUserHomeURL(UUID userID)
378 { 634 {
379 UserData user; 635 UserData user;
380 if(GetUser(userID, out user)) 636 if(GetUser(userID, out user))
@@ -384,7 +640,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
384 return string.Empty; 640 return string.Empty;
385 } 641 }
386 642
387 public string GetUserServerURL(UUID userID, string serverType) 643 public virtual string GetUserServerURL(UUID userID, string serverType)
388 { 644 {
389 UserData userdata; 645 UserData userdata;
390 if(!GetUser(userID, out userdata)) 646 if(!GetUser(userID, out userdata))
@@ -424,14 +680,14 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
424 return string.Empty; 680 return string.Empty;
425 } 681 }
426 682
427 public string GetUserUUI(UUID userID) 683 public virtual string GetUserUUI(UUID userID)
428 { 684 {
429 string uui; 685 string uui;
430 GetUserUUI(userID, out uui); 686 GetUserUUI(userID, out uui);
431 return uui; 687 return uui;
432 } 688 }
433 689
434 public bool GetUserUUI(UUID userID, out string uui) 690 public virtual bool GetUserUUI(UUID userID, out string uui)
435 { 691 {
436 UserData ud; 692 UserData ud;
437 bool result = GetUser(userID, out ud); 693 bool result = GetUser(userID, out ud);
@@ -449,6 +705,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
449 last = parts[1]; 705 last = parts[1];
450 } 706 }
451 uui = userID + ";" + homeURL + ";" + first + " " + last; 707 uui = userID + ";" + homeURL + ";" + first + " " + last;
708 return result;
452 } 709 }
453 } 710 }
454 711
@@ -457,8 +714,14 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
457 } 714 }
458 715
459 #region Cache Management 716 #region Cache Management
460 public bool GetUser(UUID uuid, out UserData userdata) 717 public virtual bool GetUser(UUID uuid, out UserData userdata)
461 { 718 {
719 if(m_Scenes.Count <= 0)
720 {
721 userdata = new UserData();
722 return false;
723 }
724
462 lock (m_UserCache) 725 lock (m_UserCache)
463 { 726 {
464 if (m_UserCache.TryGetValue(uuid, out userdata)) 727 if (m_UserCache.TryGetValue(uuid, out userdata))
@@ -471,7 +734,6 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
471 else 734 else
472 { 735 {
473 userdata = new UserData(); 736 userdata = new UserData();
474 userdata.HasGridUserTried = false;
475 userdata.Id = uuid; 737 userdata.Id = uuid;
476 userdata.FirstName = "Unknown"; 738 userdata.FirstName = "Unknown";
477 userdata.LastName = "UserUMMAU42"; 739 userdata.LastName = "UserUMMAU42";
@@ -544,7 +806,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
544 return !userdata.IsUnknownUser; 806 return !userdata.IsUnknownUser;
545 } 807 }
546 808
547 public void AddUser(UUID uuid, string first, string last) 809 public virtual void AddUser(UUID uuid, string first, string last, bool isNPC = false)
548 { 810 {
549 lock(m_UserCache) 811 lock(m_UserCache)
550 { 812 {
@@ -555,13 +817,13 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
555 user.FirstName = first; 817 user.FirstName = first;
556 user.LastName = last; 818 user.LastName = last;
557 user.IsUnknownUser = false; 819 user.IsUnknownUser = false;
558 user.HasGridUserTried = false; 820 user.HasGridUserTried = isNPC;
559 m_UserCache.Add(uuid, user); 821 m_UserCache.Add(uuid, user);
560 } 822 }
561 } 823 }
562 } 824 }
563 825
564 public void AddUser(UUID uuid, string first, string last, string homeURL) 826 public virtual void AddUser(UUID uuid, string first, string last, string homeURL)
565 { 827 {
566 //m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, first {1}, last {2}, url {3}", uuid, first, last, homeURL); 828 //m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, first {1}, last {2}, url {3}", uuid, first, last, homeURL);
567 829
@@ -611,7 +873,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
611 } 873 }
612 } 874 }
613 875
614 public void AddUser(UUID id, string creatorData) 876 public virtual void AddUser(UUID id, string creatorData)
615 { 877 {
616 // m_log.InfoFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, creatorData {1}", id, creatorData); 878 // m_log.InfoFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, creatorData {1}", id, creatorData);
617 879
@@ -694,24 +956,29 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
694 } 956 }
695 #endregion 957 #endregion
696 958
697 public bool IsLocalGridUser(UUID uuid) 959 public virtual bool IsLocalGridUser(UUID uuid)
698 { 960 {
699 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, uuid); 961 lock (m_Scenes)
700 if (account == null || (account != null && !account.LocalToGrid)) 962 {
701 return false; 963 if (m_Scenes.Count == 0)
964 return true;
965 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, uuid);
966 if (account == null || (account != null && !account.LocalToGrid))
967 return false;
968 }
702 969
703 return true; 970 return true;
704 } 971 }
705 972
706 #endregion IUserManagement 973 #endregion IUserManagement
707 974
708 protected void Init() 975 protected virtual void Init()
709 { 976 {
710 AddUser(UUID.Zero, "Unknown", "User"); 977 AddUser(UUID.Zero, "Unknown", "User");
711 RegisterConsoleCmds(); 978 RegisterConsoleCmds();
712 } 979 }
713 980
714 protected void RegisterConsoleCmds() 981 protected virtual void RegisterConsoleCmds()
715 { 982 {
716 MainConsole.Instance.Commands.AddCommand("Users", true, 983 MainConsole.Instance.Commands.AddCommand("Users", true,
717 "show name", 984 "show name",
@@ -735,7 +1002,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
735 HandleResetUserCache); 1002 HandleResetUserCache);
736 } 1003 }
737 1004
738 private void HandleResetUserCache(string module, string[] cmd) 1005 protected virtual void HandleResetUserCache(string module, string[] cmd)
739 { 1006 {
740 lock(m_UserCache) 1007 lock(m_UserCache)
741 { 1008 {
@@ -743,7 +1010,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
743 } 1010 }
744 } 1011 }
745 1012
746 private void HandleShowUser(string module, string[] cmd) 1013 protected virtual void HandleShowUser(string module, string[] cmd)
747 { 1014 {
748 if (cmd.Length < 3) 1015 if (cmd.Length < 3)
749 { 1016 {
@@ -772,7 +1039,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
772 MainConsole.Instance.Output(cdt.ToString()); 1039 MainConsole.Instance.Output(cdt.ToString());
773 } 1040 }
774 1041
775 private void HandleShowUsers(string module, string[] cmd) 1042 protected virtual void HandleShowUsers(string module, string[] cmd)
776 { 1043 {
777 ConsoleDisplayTable cdt = new ConsoleDisplayTable(); 1044 ConsoleDisplayTable cdt = new ConsoleDisplayTable();
778 cdt.AddColumn("UUID", 36); 1045 cdt.AddColumn("UUID", 36);