diff options
author | onefang | 2019-05-19 21:24:15 +1000 |
---|---|---|
committer | onefang | 2019-05-19 21:24:15 +1000 |
commit | 5e4d6cab00cb29cd088ab7b62ab13aff103b64cb (patch) | |
tree | a9fbc62df9eb2d1d9ba2698d8552eae71eca20d8 /OpenSim/Region/CoreModules/Framework | |
parent | Add a build script. (diff) | |
download | opensim-SC-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.zip opensim-SC-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.tar.gz opensim-SC-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.tar.bz2 opensim-SC-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.tar.xz |
Dump OpenSim 0.9.0.1 into it's own branch.
Diffstat (limited to 'OpenSim/Region/CoreModules/Framework')
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; | |||
44 | namespace OpenSim.Region.CoreModules.Framework.Monitoring | 44 | namespace 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); |