aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Framework
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/Framework')
-rw-r--r--OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs41
-rw-r--r--OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs119
-rw-r--r--OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs139
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs542
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs141
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs6
-rw-r--r--OpenSim/Region/CoreModules/Framework/InterfaceCommander/Command.cs4
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs38
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs12
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs7
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs10
-rw-r--r--OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs1
-rw-r--r--OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs46
-rw-r--r--OpenSim/Region/CoreModules/Framework/Statistics/Logging/BinaryLoggingModule.cs2
-rwxr-xr-xOpenSim/Region/CoreModules/Framework/Statistics/Logging/LogWriter.cs15
-rw-r--r--OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs10
16 files changed, 949 insertions, 184 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
index 7f30e5a..2eb9bfb 100644
--- a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
@@ -55,7 +55,7 @@ namespace OpenSim.Region.CoreModules.Framework
55 /// <summary> 55 /// <summary>
56 /// Each agent has its own capabilities handler. 56 /// Each agent has its own capabilities handler.
57 /// </summary> 57 /// </summary>
58 protected Dictionary<UUID, Caps> m_capsObjects = new Dictionary<UUID, Caps>(); 58 protected Dictionary<uint, Caps> m_capsObjects = new Dictionary<uint, Caps>();
59 59
60 protected Dictionary<UUID, string> capsPaths = new Dictionary<UUID, string>(); 60 protected Dictionary<UUID, string> capsPaths = new Dictionary<UUID, string>();
61 protected Dictionary<UUID, Dictionary<ulong, string>> childrenSeeds 61 protected Dictionary<UUID, Dictionary<ulong, string>> childrenSeeds
@@ -100,7 +100,7 @@ namespace OpenSim.Region.CoreModules.Framework
100 get { return null; } 100 get { return null; }
101 } 101 }
102 102
103 public void CreateCaps(UUID agentId) 103 public void CreateCaps(UUID agentId, uint circuitCode)
104 { 104 {
105 int flags = m_scene.GetUserFlags(agentId); 105 int flags = m_scene.GetUserFlags(agentId);
106 if (m_scene.RegionInfo.EstateSettings.IsBanned(agentId, flags)) 106 if (m_scene.RegionInfo.EstateSettings.IsBanned(agentId, flags))
@@ -108,9 +108,9 @@ namespace OpenSim.Region.CoreModules.Framework
108 108
109 String capsObjectPath = GetCapsPath(agentId); 109 String capsObjectPath = GetCapsPath(agentId);
110 110
111 if (m_capsObjects.ContainsKey(agentId)) 111 if (m_capsObjects.ContainsKey(circuitCode))
112 { 112 {
113 Caps oldCaps = m_capsObjects[agentId]; 113 Caps oldCaps = m_capsObjects[circuitCode];
114 114
115 m_log.DebugFormat( 115 m_log.DebugFormat(
116 "[CAPS]: Recreating caps for agent {0}. Old caps path {1}, new caps path {2}. ", 116 "[CAPS]: Recreating caps for agent {0}. Old caps path {1}, new caps path {2}. ",
@@ -125,12 +125,12 @@ namespace OpenSim.Region.CoreModules.Framework
125 (MainServer.Instance == null) ? 0: MainServer.Instance.Port, 125 (MainServer.Instance == null) ? 0: MainServer.Instance.Port,
126 capsObjectPath, agentId, m_scene.RegionInfo.RegionName); 126 capsObjectPath, agentId, m_scene.RegionInfo.RegionName);
127 127
128 m_capsObjects[agentId] = caps; 128 m_capsObjects[circuitCode] = caps;
129 129
130 m_scene.EventManager.TriggerOnRegisterCaps(agentId, caps); 130 m_scene.EventManager.TriggerOnRegisterCaps(agentId, caps);
131 } 131 }
132 132
133 public void RemoveCaps(UUID agentId) 133 public void RemoveCaps(UUID agentId, uint circuitCode)
134 { 134 {
135 if (childrenSeeds.ContainsKey(agentId)) 135 if (childrenSeeds.ContainsKey(agentId))
136 { 136 {
@@ -139,11 +139,11 @@ namespace OpenSim.Region.CoreModules.Framework
139 139
140 lock (m_capsObjects) 140 lock (m_capsObjects)
141 { 141 {
142 if (m_capsObjects.ContainsKey(agentId)) 142 if (m_capsObjects.ContainsKey(circuitCode))
143 { 143 {
144 m_capsObjects[agentId].DeregisterHandlers(); 144 m_capsObjects[circuitCode].DeregisterHandlers();
145 m_scene.EventManager.TriggerOnDeregisterCaps(agentId, m_capsObjects[agentId]); 145 m_scene.EventManager.TriggerOnDeregisterCaps(agentId, m_capsObjects[circuitCode]);
146 m_capsObjects.Remove(agentId); 146 m_capsObjects.Remove(circuitCode);
147 } 147 }
148 else 148 else
149 { 149 {
@@ -154,19 +154,30 @@ namespace OpenSim.Region.CoreModules.Framework
154 } 154 }
155 } 155 }
156 156
157 public Caps GetCapsForUser(UUID agentId) 157 public Caps GetCapsForUser(uint circuitCode)
158 { 158 {
159 lock (m_capsObjects) 159 lock (m_capsObjects)
160 { 160 {
161 if (m_capsObjects.ContainsKey(agentId)) 161 if (m_capsObjects.ContainsKey(circuitCode))
162 { 162 {
163 return m_capsObjects[agentId]; 163 return m_capsObjects[circuitCode];
164 } 164 }
165 } 165 }
166 166
167 return null; 167 return null;
168 } 168 }
169 169
170 public void ActivateCaps(uint circuitCode)
171 {
172 lock (m_capsObjects)
173 {
174 if (m_capsObjects.ContainsKey(circuitCode))
175 {
176 m_capsObjects[circuitCode].Activate();
177 }
178 }
179 }
180
170 public void SetAgentCapsSeeds(AgentCircuitData agent) 181 public void SetAgentCapsSeeds(AgentCircuitData agent)
171 { 182 {
172 capsPaths[agent.AgentID] = agent.CapsPath; 183 capsPaths[agent.AgentID] = agent.CapsPath;
@@ -237,9 +248,9 @@ namespace OpenSim.Region.CoreModules.Framework
237 StringBuilder caps = new StringBuilder(); 248 StringBuilder caps = new StringBuilder();
238 caps.AppendFormat("Region {0}:\n", m_scene.RegionInfo.RegionName); 249 caps.AppendFormat("Region {0}:\n", m_scene.RegionInfo.RegionName);
239 250
240 foreach (KeyValuePair<UUID, Caps> kvp in m_capsObjects) 251 foreach (KeyValuePair<uint, Caps> kvp in m_capsObjects)
241 { 252 {
242 caps.AppendFormat("** User {0}:\n", kvp.Key); 253 caps.AppendFormat("** Circuit {0}:\n", kvp.Key);
243 254
244 for (IDictionaryEnumerator kvp2 = kvp.Value.CapsHandlers.GetCapsDetails(false).GetEnumerator(); kvp2.MoveNext(); ) 255 for (IDictionaryEnumerator kvp2 = kvp.Value.CapsHandlers.GetCapsDetails(false).GetEnumerator(); kvp2.MoveNext(); )
245 { 256 {
diff --git a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs
new file mode 100644
index 0000000..1f1568f
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs
@@ -0,0 +1,119 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using log4net;
32using Mono.Addins;
33using Nini.Config;
34using OpenMetaverse;
35using OpenMetaverse.Packets;
36using OpenMetaverse.StructuredData;
37using OpenSim.Framework;
38using OpenSim.Region.Framework;
39using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes;
41
42namespace OpenSim.Region.CoreModules.Framework.DynamicAttributes.DAExampleModule
43{
44 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DAExampleModule")]
45 public class DAExampleModule : INonSharedRegionModule
46 {
47// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48
49 private static readonly bool ENABLED = false; // enable for testing
50
51 public const string DANamespace = "DAExample Module";
52
53 protected Scene m_scene;
54 protected IDialogModule m_dialogMod;
55
56 public string Name { get { return "DAExample Module"; } }
57 public Type ReplaceableInterface { get { return null; } }
58
59 public void Initialise(IConfigSource source) {}
60
61 public void AddRegion(Scene scene)
62 {
63 if (ENABLED)
64 {
65 m_scene = scene;
66 m_scene.EventManager.OnSceneGroupMove += OnSceneGroupMove;
67 m_dialogMod = m_scene.RequestModuleInterface<IDialogModule>();
68 }
69 }
70
71 public void RemoveRegion(Scene scene)
72 {
73 if (ENABLED)
74 {
75 m_scene.EventManager.OnSceneGroupMove -= OnSceneGroupMove;
76 }
77 }
78
79 public void RegionLoaded(Scene scene) {}
80
81 public void Close()
82 {
83 RemoveRegion(m_scene);
84 }
85
86 protected bool OnSceneGroupMove(UUID groupId, Vector3 delta)
87 {
88 OSDMap attrs = null;
89 SceneObjectPart sop = m_scene.GetSceneObjectPart(groupId);
90
91 if (sop == null)
92 return true;
93
94 if (!sop.DynAttrs.TryGetValue(DANamespace, out attrs))
95 attrs = new OSDMap();
96
97 OSDInteger newValue;
98
99 // We have to lock on the entire dynamic attributes map to avoid race conditions with serialization code.
100 lock (sop.DynAttrs)
101 {
102 if (!attrs.ContainsKey("moves"))
103 newValue = new OSDInteger(1);
104 else
105 newValue = new OSDInteger(attrs["moves"].AsInteger() + 1);
106
107 attrs["moves"] = newValue;
108
109 sop.DynAttrs[DANamespace] = attrs;
110 }
111
112 sop.ParentGroup.HasGroupChanged = true;
113
114 m_dialogMod.SendGeneralAlert(string.Format("{0} {1} moved {2} times", sop.Name, sop.UUID, newValue));
115
116 return true;
117 }
118 }
119} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs
new file mode 100644
index 0000000..650aa35
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs
@@ -0,0 +1,139 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using log4net;
32using Mono.Addins;
33using Nini.Config;
34using OpenMetaverse;
35using OpenMetaverse.Packets;
36using OpenMetaverse.StructuredData;
37using OpenSim.Framework;
38using OpenSim.Region.Framework;
39using OpenSim.Region.CoreModules.Framework.DynamicAttributes.DAExampleModule;
40using OpenSim.Region.Framework.Interfaces;
41using OpenSim.Region.Framework.Scenes;
42
43namespace OpenSim.Region.Framework.DynamicAttributes.DOExampleModule
44{
45 /// <summary>
46 /// Example module for experimenting with and demonstrating dynamic object ideas.
47 /// </summary>
48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DOExampleModule")]
49 public class DOExampleModule : INonSharedRegionModule
50 {
51 public class MyObject
52 {
53 public int Moves { get; set; }
54
55 public MyObject(int moves)
56 {
57 Moves = moves;
58 }
59 }
60
61 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
62
63 private static readonly bool ENABLED = false; // enable for testing
64
65 private Scene m_scene;
66 private IDialogModule m_dialogMod;
67
68 public string Name { get { return "DOExample Module"; } }
69 public Type ReplaceableInterface { get { return null; } }
70
71 public void Initialise(IConfigSource source) {}
72
73 public void AddRegion(Scene scene)
74 {
75 if (ENABLED)
76 {
77 m_scene = scene;
78 m_scene.EventManager.OnObjectAddedToScene += OnObjectAddedToScene;
79 m_scene.EventManager.OnSceneGroupMove += OnSceneGroupMove;
80 m_dialogMod = m_scene.RequestModuleInterface<IDialogModule>();
81 }
82 }
83
84 public void RemoveRegion(Scene scene)
85 {
86 if (ENABLED)
87 {
88 m_scene.EventManager.OnSceneGroupMove -= OnSceneGroupMove;
89 }
90 }
91
92 public void RegionLoaded(Scene scene) {}
93
94 public void Close()
95 {
96 RemoveRegion(m_scene);
97 }
98
99 private void OnObjectAddedToScene(SceneObjectGroup so)
100 {
101 SceneObjectPart rootPart = so.RootPart;
102
103 OSDMap attrs;
104
105 int movesSoFar = 0;
106
107// Console.WriteLine("Here for {0}", so.Name);
108
109 if (rootPart.DynAttrs.TryGetValue(DAExampleModule.DANamespace, out attrs))
110 {
111 movesSoFar = attrs["moves"].AsInteger();
112
113 m_log.DebugFormat(
114 "[DO EXAMPLE MODULE]: Found saved moves {0} for {1} in {2}", movesSoFar, so.Name, m_scene.Name);
115 }
116
117 rootPart.DynObjs.Add(Name, new MyObject(movesSoFar));
118 }
119
120 private bool OnSceneGroupMove(UUID groupId, Vector3 delta)
121 {
122 SceneObjectGroup so = m_scene.GetSceneObjectGroup(groupId);
123
124 if (so == null)
125 return true;
126
127 object rawObj = so.RootPart.DynObjs.Get(Name);
128
129 if (rawObj != null)
130 {
131 MyObject myObj = (MyObject)rawObj;
132
133 m_dialogMod.SendGeneralAlert(string.Format("{0} {1} moved {2} times", so.Name, so.UUID, ++myObj.Moves));
134 }
135
136 return true;
137 }
138 }
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 cb09047..b70aeb7 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -33,6 +33,7 @@ using System.Threading;
33using OpenSim.Framework; 33using OpenSim.Framework;
34using OpenSim.Framework.Capabilities; 34using OpenSim.Framework.Capabilities;
35using OpenSim.Framework.Client; 35using OpenSim.Framework.Client;
36using OpenSim.Framework.Monitoring;
36using OpenSim.Region.Framework.Interfaces; 37using OpenSim.Region.Framework.Interfaces;
37using OpenSim.Region.Framework.Scenes; 38using OpenSim.Region.Framework.Scenes;
38using OpenSim.Region.Physics.Manager; 39using OpenSim.Region.Physics.Manager;
@@ -66,6 +67,42 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
66 /// </summary> 67 /// </summary>
67 public bool WaitForAgentArrivedAtDestination { get; set; } 68 public bool WaitForAgentArrivedAtDestination { get; set; }
68 69
70 /// <summary>
71 /// If true then we ask the viewer to disable teleport cancellation and ignore teleport requests.
72 /// </summary>
73 /// <remarks>
74 /// This is useful in situations where teleport is very likely to always succeed and we want to avoid a
75 /// situation where avatars can be come 'stuck' due to a failed teleport cancellation. Unfortunately, the
76 /// nature of the teleport protocol makes it extremely difficult (maybe impossible) to make teleport
77 /// cancellation consistently suceed.
78 /// </remarks>
79 public bool DisableInterRegionTeleportCancellation { get; set; }
80
81 /// <summary>
82 /// Number of times inter-region teleport was attempted.
83 /// </summary>
84 private Stat m_interRegionTeleportAttempts;
85
86 /// <summary>
87 /// Number of times inter-region teleport was aborted (due to simultaneous client logout).
88 /// </summary>
89 private Stat m_interRegionTeleportAborts;
90
91 /// <summary>
92 /// Number of times inter-region teleport was successfully cancelled by the client.
93 /// </summary>
94 private Stat m_interRegionTeleportCancels;
95
96 /// <summary>
97 /// Number of times inter-region teleport failed due to server/client/network problems (e.g. viewer failed to
98 /// connect with destination region).
99 /// </summary>
100 /// <remarks>
101 /// This is not necessarily a problem for this simulator - in open-grid/hg conditions, viewer connectivity to
102 /// destination simulator is unknown.
103 /// </remarks>
104 private Stat m_interRegionTeleportFailures;
105
69 protected bool m_Enabled = false; 106 protected bool m_Enabled = false;
70 107
71 public Scene Scene { get; private set; } 108 public Scene Scene { get; private set; }
@@ -80,6 +117,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
80 new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>(); 117 new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>();
81 118
82 private IEventQueue m_eqModule; 119 private IEventQueue m_eqModule;
120 private IRegionCombinerModule m_regionCombinerModule;
83 121
84 #region ISharedRegionModule 122 #region ISharedRegionModule
85 123
@@ -116,6 +154,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
116 IConfig transferConfig = source.Configs["EntityTransfer"]; 154 IConfig transferConfig = source.Configs["EntityTransfer"];
117 if (transferConfig != null) 155 if (transferConfig != null)
118 { 156 {
157 DisableInterRegionTeleportCancellation
158 = transferConfig.GetBoolean("DisableInterRegionTeleportCancellation", false);
159
119 WaitForAgentArrivedAtDestination 160 WaitForAgentArrivedAtDestination
120 = transferConfig.GetBoolean("wait_for_callback", WaitForAgentArrivedAtDestinationDefault); 161 = transferConfig.GetBoolean("wait_for_callback", WaitForAgentArrivedAtDestinationDefault);
121 162
@@ -142,6 +183,60 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
142 183
143 Scene = scene; 184 Scene = scene;
144 185
186 m_interRegionTeleportAttempts =
187 new Stat(
188 "InterRegionTeleportAttempts",
189 "Number of inter-region teleports attempted.",
190 "This does not count attempts which failed due to pre-conditions (e.g. target simulator refused access).\n"
191 + "You can get successfully teleports by subtracting aborts, cancels and teleport failures from this figure.",
192 "",
193 "entitytransfer",
194 Scene.Name,
195 StatType.Push,
196 null,
197 StatVerbosity.Debug);
198
199 m_interRegionTeleportAborts =
200 new Stat(
201 "InterRegionTeleportAborts",
202 "Number of inter-region teleports aborted due to client actions.",
203 "The chief action is simultaneous logout whilst teleporting.",
204 "",
205 "entitytransfer",
206 Scene.Name,
207 StatType.Push,
208 null,
209 StatVerbosity.Debug);
210
211 m_interRegionTeleportCancels =
212 new Stat(
213 "InterRegionTeleportCancels",
214 "Number of inter-region teleports cancelled by the client.",
215 null,
216 "",
217 "entitytransfer",
218 Scene.Name,
219 StatType.Push,
220 null,
221 StatVerbosity.Debug);
222
223 m_interRegionTeleportFailures =
224 new Stat(
225 "InterRegionTeleportFailures",
226 "Number of inter-region teleports that failed due to server/client/network issues.",
227 "This number may not be very helpful in open-grid/hg situations as the network connectivity/quality of destinations is uncontrollable.",
228 "",
229 "entitytransfer",
230 Scene.Name,
231 StatType.Push,
232 null,
233 StatVerbosity.Debug);
234
235 StatsManager.RegisterStat(m_interRegionTeleportAttempts);
236 StatsManager.RegisterStat(m_interRegionTeleportAborts);
237 StatsManager.RegisterStat(m_interRegionTeleportCancels);
238 StatsManager.RegisterStat(m_interRegionTeleportFailures);
239
145 scene.RegisterModuleInterface<IEntityTransferModule>(this); 240 scene.RegisterModuleInterface<IEntityTransferModule>(this);
146 scene.EventManager.OnNewClient += OnNewClient; 241 scene.EventManager.OnNewClient += OnNewClient;
147 } 242 }
@@ -150,12 +245,25 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
150 { 245 {
151 client.OnTeleportHomeRequest += TriggerTeleportHome; 246 client.OnTeleportHomeRequest += TriggerTeleportHome;
152 client.OnTeleportLandmarkRequest += RequestTeleportLandmark; 247 client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
153 client.OnTeleportCancel += TeleportCancel; 248
249 if (!DisableInterRegionTeleportCancellation)
250 client.OnTeleportCancel += OnClientCancelTeleport;
251
252 client.OnConnectionClosed += OnConnectionClosed;
154 } 253 }
155 254
156 public virtual void Close() {} 255 public virtual void Close() {}
157 256
158 public virtual void RemoveRegion(Scene scene) {} 257 public virtual void RemoveRegion(Scene scene)
258 {
259 if (m_Enabled)
260 {
261 StatsManager.DeregisterStat(m_interRegionTeleportAttempts);
262 StatsManager.DeregisterStat(m_interRegionTeleportAborts);
263 StatsManager.DeregisterStat(m_interRegionTeleportCancels);
264 StatsManager.DeregisterStat(m_interRegionTeleportFailures);
265 }
266 }
159 267
160 public virtual void RegionLoaded(Scene scene) 268 public virtual void RegionLoaded(Scene scene)
161 { 269 {
@@ -163,12 +271,33 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
163 return; 271 return;
164 272
165 m_eqModule = Scene.RequestModuleInterface<IEventQueue>(); 273 m_eqModule = Scene.RequestModuleInterface<IEventQueue>();
274 m_regionCombinerModule = Scene.RequestModuleInterface<IRegionCombinerModule>();
166 } 275 }
167 276
168 #endregion 277 #endregion
169 278
170 #region Agent Teleports 279 #region Agent Teleports
171 280
281 private void OnConnectionClosed(IClientAPI client)
282 {
283 if (client.IsLoggingOut)
284 {
285 m_entityTransferStateMachine.UpdateInTransit(client.AgentId, AgentTransferState.Aborting);
286
287 m_log.DebugFormat(
288 "[ENTITY TRANSFER MODULE]: Aborted teleport request from {0} in {1} due to simultaneous logout",
289 client.Name, Scene.Name);
290 }
291 }
292
293 private void OnClientCancelTeleport(IClientAPI client)
294 {
295 m_entityTransferStateMachine.UpdateInTransit(client.AgentId, AgentTransferState.Cancelling);
296
297 m_log.DebugFormat(
298 "[ENTITY TRANSFER MODULE]: Received teleport cancel request from {0} in {1}", client.Name, Scene.Name);
299 }
300
172 public void Teleport(ScenePresence sp, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags) 301 public void Teleport(ScenePresence sp, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags)
173 { 302 {
174 if (sp.Scene.Permissions.IsGridGod(sp.UUID)) 303 if (sp.Scene.Permissions.IsGridGod(sp.UUID))
@@ -180,13 +309,24 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
180 if (!sp.Scene.Permissions.CanTeleport(sp.UUID)) 309 if (!sp.Scene.Permissions.CanTeleport(sp.UUID))
181 return; 310 return;
182 311
183 // Reset animations; the viewer does that in teleports.
184 sp.Animator.ResetAnimations();
185
186 string destinationRegionName = "(not found)"; 312 string destinationRegionName = "(not found)";
187 313
314 // Record that this agent is in transit so that we can prevent simultaneous requests and do later detection
315 // of whether the destination region completes the teleport.
316 if (!m_entityTransferStateMachine.SetInTransit(sp.UUID))
317 {
318 m_log.DebugFormat(
319 "[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2}@{3} - agent is already in transit.",
320 sp.Name, sp.UUID, position, regionHandle);
321
322 return;
323 }
324
188 try 325 try
189 { 326 {
327 // Reset animations; the viewer does that in teleports.
328 sp.Animator.ResetAnimations();
329
190 if (regionHandle == sp.Scene.RegionInfo.RegionHandle) 330 if (regionHandle == sp.Scene.RegionInfo.RegionHandle)
191 { 331 {
192 destinationRegionName = sp.Scene.RegionInfo.RegionName; 332 destinationRegionName = sp.Scene.RegionInfo.RegionName;
@@ -195,12 +335,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
195 } 335 }
196 else // Another region possibly in another simulator 336 else // Another region possibly in another simulator
197 { 337 {
198 GridRegion finalDestination; 338 GridRegion finalDestination = null;
199 TeleportAgentToDifferentRegion( 339 try
200 sp, regionHandle, position, lookAt, teleportFlags, out finalDestination); 340 {
201 341 TeleportAgentToDifferentRegion(
202 if (finalDestination != null) 342 sp, regionHandle, position, lookAt, teleportFlags, out finalDestination);
203 destinationRegionName = finalDestination.RegionName; 343 }
344 finally
345 {
346 if (finalDestination != null)
347 destinationRegionName = finalDestination.RegionName;
348 }
204 } 349 }
205 } 350 }
206 catch (Exception e) 351 catch (Exception e)
@@ -210,11 +355,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
210 sp.Name, sp.AbsolutePosition, sp.Scene.RegionInfo.RegionName, position, destinationRegionName, 355 sp.Name, sp.AbsolutePosition, sp.Scene.RegionInfo.RegionName, position, destinationRegionName,
211 e.Message, e.StackTrace); 356 e.Message, e.StackTrace);
212 357
213 // Make sure that we clear the in-transit flag so that future teleport attempts don't always fail.
214 m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
215
216 sp.ControllingClient.SendTeleportFailed("Internal error"); 358 sp.ControllingClient.SendTeleportFailed("Internal error");
217 } 359 }
360 finally
361 {
362 m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
363 }
218 } 364 }
219 365
220 /// <summary> 366 /// <summary>
@@ -230,23 +376,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
230 "[ENTITY TRANSFER MODULE]: Teleport for {0} to {1} within {2}", 376 "[ENTITY TRANSFER MODULE]: Teleport for {0} to {1} within {2}",
231 sp.Name, position, sp.Scene.RegionInfo.RegionName); 377 sp.Name, position, sp.Scene.RegionInfo.RegionName);
232 378
233 if (!m_entityTransferStateMachine.SetInTransit(sp.UUID))
234 {
235 m_log.DebugFormat(
236 "[ENTITY TRANSFER MODULE]: Ignoring within region teleport request of {0} {1} to {2} - agent is already in transit.",
237 sp.Name, sp.UUID, position);
238
239 return;
240 }
241
242 // Teleport within the same region 379 // Teleport within the same region
243 if (IsOutsideRegion(sp.Scene, position) || position.Z < 0) 380 if (IsOutsideRegion(sp.Scene, position) || position.Z < 0)
244 { 381 {
245 Vector3 emergencyPos = new Vector3(128, 128, 128); 382 Vector3 emergencyPos = new Vector3(128, 128, 128);
246 383
247 m_log.WarnFormat( 384 m_log.WarnFormat(
248 "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", 385 "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2} in {3}. Substituting {4}",
249 position, sp.Name, sp.UUID, emergencyPos); 386 position, sp.Name, sp.UUID, Scene.Name, emergencyPos);
250 387
251 position = emergencyPos; 388 position = emergencyPos;
252 } 389 }
@@ -287,7 +424,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
287 } 424 }
288 425
289 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); 426 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp);
290 m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
291 } 427 }
292 428
293 /// <summary> 429 /// <summary>
@@ -341,7 +477,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
341 // 477 //
342 // This is it 478 // This is it
343 // 479 //
344 DoTeleport(sp, reg, finalDestination, position, lookAt, teleportFlags); 480 DoTeleportInternal(sp, reg, finalDestination, position, lookAt, teleportFlags);
345 // 481 //
346 // 482 //
347 // 483 //
@@ -396,27 +532,54 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
396 && Math.Abs(sourceRegion.RegionLocY - destRegion.RegionCoordY) <= MaxTransferDistance; 532 && Math.Abs(sourceRegion.RegionLocY - destRegion.RegionCoordY) <= MaxTransferDistance;
397 } 533 }
398 534
535 /// <summary>
536 /// Wraps DoTeleportInternal() and manages the transfer state.
537 /// </summary>
399 public void DoTeleport( 538 public void DoTeleport(
400 ScenePresence sp, GridRegion reg, GridRegion finalDestination, 539 ScenePresence sp, GridRegion reg, GridRegion finalDestination,
401 Vector3 position, Vector3 lookAt, uint teleportFlags) 540 Vector3 position, Vector3 lookAt, uint teleportFlags)
402 { 541 {
403 // Record that this agent is in transit so that we can prevent simultaneous requests and do later detection 542 // Record that this agent is in transit so that we can prevent simultaneous requests and do later detection
404 // of whether the destination region completes the teleport. 543 // of whether the destination region completes the teleport.
405 m_entityTransferStateMachine.SetInTransit(sp.UUID); 544 if (!m_entityTransferStateMachine.SetInTransit(sp.UUID))
406// if (!m_entityTransferStateMachine.SetInTransit(sp.UUID)) 545 {
407// { 546 m_log.DebugFormat(
408// m_log.DebugFormat( 547 "[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2} ({3}) {4}/{5} - agent is already in transit.",
409// "[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2} ({3}) {4}/{5} - agent is already in transit.", 548 sp.Name, sp.UUID, reg.ServerURI, finalDestination.ServerURI, finalDestination.RegionName, position);
410// sp.Name, sp.UUID, reg.ServerURI, finalDestination.ServerURI, finalDestination.RegionName, position);
411//
412// return;
413// }
414 549
415 if (reg == null || finalDestination == null) 550 return;
551 }
552
553 try
554 {
555 DoTeleportInternal(sp, reg, finalDestination, position, lookAt, teleportFlags);
556 }
557 catch (Exception e)
558 {
559 m_log.ErrorFormat(
560 "[ENTITY TRANSFER MODULE]: Exception on teleport of {0} from {1}@{2} to {3}@{4}: {5}{6}",
561 sp.Name, sp.AbsolutePosition, sp.Scene.RegionInfo.RegionName, position, finalDestination.RegionName,
562 e.Message, e.StackTrace);
563
564 sp.ControllingClient.SendTeleportFailed("Internal error");
565 }
566 finally
416 { 567 {
417 sp.ControllingClient.SendTeleportFailed("Unable to locate destination");
418 m_entityTransferStateMachine.ResetFromTransit(sp.UUID); 568 m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
569 }
570 }
419 571
572 /// <summary>
573 /// Teleports the agent to another region.
574 /// This method doesn't manage the transfer state; the caller must do that.
575 /// </summary>
576 private void DoTeleportInternal(
577 ScenePresence sp, GridRegion reg, GridRegion finalDestination,
578 Vector3 position, Vector3 lookAt, uint teleportFlags)
579 {
580 if (reg == null || finalDestination == null)
581 {
582 sp.ControllingClient.SendTeleportFailed("Unable to locate destination");
420 return; 583 return;
421 } 584 }
422 585
@@ -436,8 +599,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
436 sourceRegion.RegionName, sourceRegion.RegionLocX, sourceRegion.RegionLocY, 599 sourceRegion.RegionName, sourceRegion.RegionLocX, sourceRegion.RegionLocY,
437 MaxTransferDistance)); 600 MaxTransferDistance));
438 601
439 m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
440
441 return; 602 return;
442 } 603 }
443 604
@@ -455,7 +616,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
455 if (endPoint == null || endPoint.Address == null) 616 if (endPoint == null || endPoint.Address == null)
456 { 617 {
457 sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); 618 sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down");
458 m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
459 619
460 return; 620 return;
461 } 621 }
@@ -465,19 +625,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
465 "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.", 625 "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.",
466 sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName); 626 sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName);
467 627
468// if (!sp.ValidateAttachments())
469// {
470// sp.ControllingClient.SendTeleportFailed("Inconsistent attachment state");
471// return;
472// }
473
474 string reason; 628 string reason;
475 string version; 629 string version;
476 if (!Scene.SimulationService.QueryAccess( 630 if (!Scene.SimulationService.QueryAccess(
477 finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out version, out reason)) 631 finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out version, out reason))
478 { 632 {
479 sp.ControllingClient.SendTeleportFailed(reason); 633 sp.ControllingClient.SendTeleportFailed(reason);
480 m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
481 634
482 m_log.DebugFormat( 635 m_log.DebugFormat(
483 "[ENTITY TRANSFER MODULE]: {0} was stopped from teleporting from {1} to {2} because {3}", 636 "[ENTITY TRANSFER MODULE]: {0} was stopped from teleporting from {1} to {2} because {3}",
@@ -486,6 +639,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
486 return; 639 return;
487 } 640 }
488 641
642 // Before this point, teleport 'failure' is due to checkable pre-conditions such as whether the target
643 // simulator can be found and is explicitly prepared to allow access. Therefore, we will not count these
644 // as server attempts.
645 m_interRegionTeleportAttempts.Value++;
646
489 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version); 647 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version);
490 648
491 // Fixing a bug where teleporting while sitting results in the avatar ending up removed from 649 // Fixing a bug where teleporting while sitting results in the avatar ending up removed from
@@ -495,6 +653,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
495 else if (sp.Flying) 653 else if (sp.Flying)
496 teleportFlags |= (uint)TeleportFlags.IsFlying; 654 teleportFlags |= (uint)TeleportFlags.IsFlying;
497 655
656 if (DisableInterRegionTeleportCancellation)
657 teleportFlags |= (uint)TeleportFlags.DisableCancel;
658
498 // At least on LL 3.3.4, this is not strictly necessary - a teleport will succeed without sending this to 659 // At least on LL 3.3.4, this is not strictly necessary - a teleport will succeed without sending this to
499 // the viewer. However, it might mean that the viewer does not see the black teleport screen (untested). 660 // the viewer. However, it might mean that the viewer does not see the black teleport screen (untested).
500 sp.ControllingClient.SendTeleportStart(teleportFlags); 661 sp.ControllingClient.SendTeleportStart(teleportFlags);
@@ -531,11 +692,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
531 } 692 }
532 693
533 // Let's create an agent there if one doesn't exist yet. 694 // Let's create an agent there if one doesn't exist yet.
695 // NOTE: logout will always be false for a non-HG teleport.
534 bool logout = false; 696 bool logout = false;
535 if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout)) 697 if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout))
536 { 698 {
699 m_interRegionTeleportFailures.Value++;
700
537 sp.ControllingClient.SendTeleportFailed(String.Format("Teleport refused: {0}", reason)); 701 sp.ControllingClient.SendTeleportFailed(String.Format("Teleport refused: {0}", reason));
538 m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
539 702
540 m_log.DebugFormat( 703 m_log.DebugFormat(
541 "[ENTITY TRANSFER MODULE]: Teleport of {0} from {1} to {2} was refused because {3}", 704 "[ENTITY TRANSFER MODULE]: Teleport of {0} from {1} to {2} was refused because {3}",
@@ -544,6 +707,27 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
544 return; 707 return;
545 } 708 }
546 709
710 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Cancelling)
711 {
712 m_interRegionTeleportCancels.Value++;
713
714 m_log.DebugFormat(
715 "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after CreateAgent on client request",
716 sp.Name, finalDestination.RegionName, sp.Scene.Name);
717
718 return;
719 }
720 else if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
721 {
722 m_interRegionTeleportAborts.Value++;
723
724 m_log.DebugFormat(
725 "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after CreateAgent due to previous client close.",
726 sp.Name, finalDestination.RegionName, sp.Scene.Name);
727
728 return;
729 }
730
547 // Past this point we have to attempt clean up if the teleport fails, so update transfer state. 731 // Past this point we have to attempt clean up if the teleport fails, so update transfer state.
548 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); 732 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring);
549 733
@@ -553,6 +737,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
553 IClientIPEndpoint ipepClient; 737 IClientIPEndpoint ipepClient;
554 if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) 738 if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY))
555 { 739 {
740 m_log.DebugFormat(
741 "[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} needs new child agent for incoming agent {3} from {4}",
742 finalDestination.RegionName, newRegionX, newRegionY, sp.Name, Scene.Name);
743
556 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent..."); 744 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent...");
557 #region IP Translation for NAT 745 #region IP Translation for NAT
558 // Uses ipepClient above 746 // Uses ipepClient above
@@ -565,11 +753,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
565 753
566 if (m_eqModule != null) 754 if (m_eqModule != null)
567 { 755 {
756 // The EnableSimulator message makes the client establish a connection with the destination
757 // simulator by sending the initial UseCircuitCode UDP packet to the destination containing the
758 // correct circuit code.
568 m_eqModule.EnableSimulator(destinationHandle, endPoint, sp.UUID); 759 m_eqModule.EnableSimulator(destinationHandle, endPoint, sp.UUID);
569 760
570 // ES makes the client send a UseCircuitCode message to the destination, 761 // XXX: Is this wait necessary? We will always end up waiting on UpdateAgent for the destination
571 // which triggers a bunch of things there. 762 // simulator to confirm that it has established communication with the viewer.
572 // So let's wait
573 Thread.Sleep(200); 763 Thread.Sleep(200);
574 764
575 // At least on LL 3.3.4 for teleports between different regions on the same simulator this appears 765 // At least on LL 3.3.4 for teleports between different regions on the same simulator this appears
@@ -580,6 +770,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
580 } 770 }
581 else 771 else
582 { 772 {
773 // XXX: This is a little misleading since we're information the client of its avatar destination,
774 // which may or may not be a neighbour region of the source region. This path is probably little
775 // used anyway (with EQ being the one used). But it is currently being used for test code.
583 sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint); 776 sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint);
584 } 777 }
585 } 778 }
@@ -597,23 +790,66 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
597 790
598 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent..."); 791 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent...");
599 792
793 // We will check for an abort before UpdateAgent since UpdateAgent will require an active viewer to
794 // establish th econnection to the destination which makes it return true.
795 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
796 {
797 m_interRegionTeleportAborts.Value++;
798
799 m_log.DebugFormat(
800 "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} before UpdateAgent",
801 sp.Name, finalDestination.RegionName, sp.Scene.Name);
802
803 return;
804 }
805
806 // A common teleport failure occurs when we can send CreateAgent to the
807 // destination region but the viewer cannot establish the connection (e.g. due to network issues between
808 // the viewer and the destination). In this case, UpdateAgent timesout after 10 seconds, although then
809 // there's a further 10 second wait whilst we attempt to tell the destination to delete the agent in Fail().
600 if (!UpdateAgent(reg, finalDestination, agent, sp)) 810 if (!UpdateAgent(reg, finalDestination, agent, sp))
601 { 811 {
602 // Region doesn't take it 812 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
813 {
814 m_interRegionTeleportAborts.Value++;
815
816 m_log.DebugFormat(
817 "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after UpdateAgent due to previous client close.",
818 sp.Name, finalDestination.RegionName, sp.Scene.Name);
819
820 return;
821 }
822
603 m_log.WarnFormat( 823 m_log.WarnFormat(
604 "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Returning avatar to source region.", 824 "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Keeping avatar in source region.",
605 sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); 825 sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName);
606 826
607 Fail(sp, finalDestination, logout); 827 Fail(sp, finalDestination, logout, "Connection between viewer and destination region could not be established.");
608 return; 828 return;
609 } 829 }
610 830
611 sp.ControllingClient.SendTeleportProgress(teleportFlags | (uint)TeleportFlags.DisableCancel, "sending_dest"); 831 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Cancelling)
832 {
833 m_interRegionTeleportCancels.Value++;
834
835 m_log.DebugFormat(
836 "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after UpdateAgent on client request",
837 sp.Name, finalDestination.RegionName, sp.Scene.Name);
838
839 CleanupFailedInterRegionTeleport(sp, finalDestination);
840
841 return;
842 }
612 843
613 m_log.DebugFormat( 844 m_log.DebugFormat(
614 "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} from {1} to {2}", 845 "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} from {1} to {2}",
615 capsPath, sp.Scene.RegionInfo.RegionName, sp.Name); 846 capsPath, sp.Scene.RegionInfo.RegionName, sp.Name);
616 847
848 // We need to set this here to avoid an unlikely race condition when teleporting to a neighbour simulator,
849 // where that neighbour simulator could otherwise request a child agent create on the source which then
850 // closes our existing agent which is still signalled as root.
851 sp.IsChildAgent = true;
852
617 if (m_eqModule != null) 853 if (m_eqModule != null)
618 { 854 {
619 m_eqModule.TeleportFinishEvent(destinationHandle, 13, endPoint, 0, teleportFlags, capsPath, sp.UUID); 855 m_eqModule.TeleportFinishEvent(destinationHandle, 13, endPoint, 0, teleportFlags, capsPath, sp.UUID);
@@ -624,19 +860,28 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
624 teleportFlags, capsPath); 860 teleportFlags, capsPath);
625 } 861 }
626 862
627 // Let's set this to true tentatively. This does not trigger OnChildAgent
628 sp.IsChildAgent = true;
629
630 // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which 863 // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which
631 // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation 864 // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation
632 // that the client contacted the destination before we close things here. 865 // that the client contacted the destination before we close things here.
633 if (!m_entityTransferStateMachine.WaitForAgentArrivedAtDestination(sp.UUID)) 866 if (!m_entityTransferStateMachine.WaitForAgentArrivedAtDestination(sp.UUID))
634 { 867 {
868 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
869 {
870 m_interRegionTeleportAborts.Value++;
871
872 m_log.DebugFormat(
873 "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after WaitForAgentArrivedAtDestination due to previous client close.",
874 sp.Name, finalDestination.RegionName, sp.Scene.Name);
875
876 return;
877 }
878
635 m_log.WarnFormat( 879 m_log.WarnFormat(
636 "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.", 880 "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.",
637 sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); 881 sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName);
638 882
639 Fail(sp, finalDestination, logout); 883 Fail(sp, finalDestination, logout, "Destination region did not signal teleport completion.");
884
640 return; 885 return;
641 } 886 }
642 887
@@ -659,8 +904,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
659 // Now let's make it officially a child agent 904 // Now let's make it officially a child agent
660 sp.MakeChildAgent(); 905 sp.MakeChildAgent();
661 906
662// sp.Scene.CleanDroppedAttachments();
663
664 // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone 907 // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone
665 908
666 if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) 909 if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg))
@@ -680,27 +923,21 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
680 // now we have a child agent in this region. 923 // now we have a child agent in this region.
681 sp.Reset(); 924 sp.Reset();
682 } 925 }
683
684 // Commented pending deletion since this method no longer appears to do anything at all
685// // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE!
686// if (sp.Scene.NeedSceneCacheClear(sp.UUID))
687// {
688// m_log.DebugFormat(
689// "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed",
690// sp.UUID);
691// }
692
693 m_entityTransferStateMachine.ResetFromTransit(sp.UUID);
694 } 926 }
695 927
696 protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout) 928 /// <summary>
929 /// Clean up an inter-region teleport that did not complete, either because of simulator failure or cancellation.
930 /// </summary>
931 /// <remarks>
932 /// All operations here must be idempotent so that we can call this method at any point in the teleport process
933 /// up until we send the TeleportFinish event quene event to the viewer.
934 /// <remarks>
935 /// <param name='sp'> </param>
936 /// <param name='finalDestination'></param>
937 protected virtual void CleanupFailedInterRegionTeleport(ScenePresence sp, GridRegion finalDestination)
697 { 938 {
698 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); 939 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp);
699 940
700 // Client never contacted destination. Let's restore everything back
701 sp.ControllingClient.SendTeleportFailed("Problems connecting to destination.");
702
703 // Fail. Reset it back
704 sp.IsChildAgent = false; 941 sp.IsChildAgent = false;
705 ReInstantiateScripts(sp); 942 ReInstantiateScripts(sp);
706 943
@@ -708,10 +945,26 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
708 945
709 // Finally, kill the agent we just created at the destination. 946 // Finally, kill the agent we just created at the destination.
710 Scene.SimulationService.CloseAgent(finalDestination, sp.UUID); 947 Scene.SimulationService.CloseAgent(finalDestination, sp.UUID);
948 }
711 949
712 sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout); 950 /// <summary>
951 /// Signal that the inter-region teleport failed and perform cleanup.
952 /// </summary>
953 /// <param name='sp'></param>
954 /// <param name='finalDestination'></param>
955 /// <param name='logout'></param>
956 /// <param name='reason'>Human readable reason for teleport failure. Will be sent to client.</param>
957 protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout, string reason)
958 {
959 CleanupFailedInterRegionTeleport(sp, finalDestination);
960
961 m_interRegionTeleportFailures.Value++;
713 962
714 m_entityTransferStateMachine.ResetFromTransit(sp.UUID); 963 sp.ControllingClient.SendTeleportFailed(
964 string.Format(
965 "Problems connecting to destination {0}, reason: {1}", finalDestination.RegionName, reason));
966
967 sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout);
715 } 968 }
716 969
717 protected virtual bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout) 970 protected virtual bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout)
@@ -762,7 +1015,21 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
762 1015
763 protected virtual bool NeedsNewAgent(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY) 1016 protected virtual bool NeedsNewAgent(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY)
764 { 1017 {
765 return Util.IsOutsideView(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY); 1018 if (m_regionCombinerModule != null && m_regionCombinerModule.IsRootForMegaregion(Scene.RegionInfo.RegionID))
1019 {
1020 Vector2 swCorner, neCorner;
1021 GetMegaregionViewRange(out swCorner, out neCorner);
1022
1023 m_log.DebugFormat(
1024 "[ENTITY TRANSFER MODULE]: Megaregion view of {0} is from {1} to {2} with new agent check for {3},{4}",
1025 Scene.Name, swCorner, neCorner, newRegionX, newRegionY);
1026
1027 return !(newRegionX >= swCorner.X && newRegionX <= neCorner.X && newRegionY >= swCorner.Y && newRegionY <= neCorner.Y);
1028 }
1029 else
1030 {
1031 return Util.IsOutsideView(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY);
1032 }
766 } 1033 }
767 1034
768 protected virtual bool NeedsClosing(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, GridRegion reg) 1035 protected virtual bool NeedsClosing(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, GridRegion reg)
@@ -866,6 +1133,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
866 { 1133 {
867 version = String.Empty; 1134 version = String.Empty;
868 newpos = new Vector3(pos.X, pos.Y, pos.Z); 1135 newpos = new Vector3(pos.X, pos.Y, pos.Z);
1136
1137// m_log.DebugFormat(
1138// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name);
1139
869 uint neighbourx = scene.RegionInfo.RegionLocX; 1140 uint neighbourx = scene.RegionInfo.RegionLocX;
870 uint neighboury = scene.RegionInfo.RegionLocY; 1141 uint neighboury = scene.RegionInfo.RegionLocY;
871 const float boundaryDistance = 1.7f; 1142 const float boundaryDistance = 1.7f;
@@ -995,11 +1266,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
995 return neighbourRegion; 1266 return neighbourRegion;
996 } 1267 }
997 1268
998 private void TeleportCancel(IClientAPI remoteClient)
999 {
1000 m_entityTransferStateMachine.ResetFromTransit(remoteClient.AgentId);
1001 }
1002
1003 public bool Cross(ScenePresence agent, bool isFlying) 1269 public bool Cross(ScenePresence agent, bool isFlying)
1004 { 1270 {
1005 uint x; 1271 uint x;
@@ -1023,16 +1289,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1023 } 1289 }
1024 1290
1025 1291
1026 public delegate void InformClientToInitateTeleportToLocationDelegate(ScenePresence agent, uint regionX, uint regionY, 1292 public delegate void InformClientToInitiateTeleportToLocationDelegate(ScenePresence agent, uint regionX, uint regionY,
1027 Vector3 position, 1293 Vector3 position,
1028 Scene initiatingScene); 1294 Scene initiatingScene);
1029 1295
1030 private void InformClientToInitateTeleportToLocation(ScenePresence agent, uint regionX, uint regionY, Vector3 position, Scene initiatingScene) 1296 private void InformClientToInitiateTeleportToLocation(ScenePresence agent, uint regionX, uint regionY, Vector3 position, Scene initiatingScene)
1031 { 1297 {
1032 1298
1033 // This assumes that we know what our neighbours are. 1299 // This assumes that we know what our neighbours are.
1034 1300
1035 InformClientToInitateTeleportToLocationDelegate d = InformClientToInitiateTeleportToLocationAsync; 1301 InformClientToInitiateTeleportToLocationDelegate d = InformClientToInitiateTeleportToLocationAsync;
1036 d.BeginInvoke(agent, regionX, regionY, position, initiatingScene, 1302 d.BeginInvoke(agent, regionX, regionY, position, initiatingScene,
1037 InformClientToInitiateTeleportToLocationCompleted, 1303 InformClientToInitiateTeleportToLocationCompleted,
1038 d); 1304 d);
@@ -1042,7 +1308,19 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1042 Scene initiatingScene) 1308 Scene initiatingScene)
1043 { 1309 {
1044 Thread.Sleep(10000); 1310 Thread.Sleep(10000);
1045 1311
1312 m_log.DebugFormat(
1313 "[ENTITY TRANSFER MODULE]: Auto-reteleporting {0} to correct megaregion location {1},{2},{3} from {4}",
1314 agent.Name, regionX, regionY, position, initiatingScene.Name);
1315
1316 agent.Scene.RequestTeleportLocation(
1317 agent.ControllingClient,
1318 Utils.UIntsToLong(regionX * (uint)Constants.RegionSize, regionY * (uint)Constants.RegionSize),
1319 position,
1320 agent.Lookat,
1321 (uint)Constants.TeleportFlags.ViaLocation);
1322
1323 /*
1046 IMessageTransferModule im = initiatingScene.RequestModuleInterface<IMessageTransferModule>(); 1324 IMessageTransferModule im = initiatingScene.RequestModuleInterface<IMessageTransferModule>();
1047 if (im != null) 1325 if (im != null)
1048 { 1326 {
@@ -1077,12 +1355,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1077 }); 1355 });
1078 1356
1079 } 1357 }
1358 */
1080 } 1359 }
1081 1360
1082 private void InformClientToInitiateTeleportToLocationCompleted(IAsyncResult iar) 1361 private void InformClientToInitiateTeleportToLocationCompleted(IAsyncResult iar)
1083 { 1362 {
1084 InformClientToInitateTeleportToLocationDelegate icon = 1363 InformClientToInitiateTeleportToLocationDelegate icon =
1085 (InformClientToInitateTeleportToLocationDelegate)iar.AsyncState; 1364 (InformClientToInitiateTeleportToLocationDelegate)iar.AsyncState;
1086 icon.EndInvoke(iar); 1365 icon.EndInvoke(iar);
1087 } 1366 }
1088 1367
@@ -1107,10 +1386,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1107 bool isFlying, string version) 1386 bool isFlying, string version)
1108 { 1387 {
1109 if (!CrossAgentToNewRegionPrep(agent, neighbourRegion)) 1388 if (!CrossAgentToNewRegionPrep(agent, neighbourRegion))
1389 {
1390 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1110 return agent; 1391 return agent;
1392 }
1111 1393
1112 if (!CrossAgentIntoNewRegionMain(agent, pos, neighbourRegion, isFlying)) 1394 if (!CrossAgentIntoNewRegionMain(agent, pos, neighbourRegion, isFlying))
1395 {
1396 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1113 return agent; 1397 return agent;
1398 }
1114 1399
1115 CrossAgentToNewRegionPost(agent, pos, neighbourRegion, isFlying, version); 1400 CrossAgentToNewRegionPost(agent, pos, neighbourRegion, isFlying, version);
1116 return agent; 1401 return agent;
@@ -1137,9 +1422,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1137 // region doesn't take it 1422 // region doesn't take it
1138 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); 1423 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
1139 1424
1425 m_log.WarnFormat(
1426 "[ENTITY TRANSFER MODULE]: Region {0} would not accept update for agent {1} on cross attempt. Returning to original region.",
1427 neighbourRegion.RegionName, agent.Name);
1428
1140 ReInstantiateScripts(agent); 1429 ReInstantiateScripts(agent);
1141 agent.AddToPhysicalScene(isFlying); 1430 agent.AddToPhysicalScene(isFlying);
1142 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1143 1431
1144 return false; 1432 return false;
1145 } 1433 }
@@ -1576,6 +1864,37 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1576 } 1864 }
1577 1865
1578 /// <summary> 1866 /// <summary>
1867 /// Gets the range considered in view of this megaregion (assuming this is a megaregion).
1868 /// </summary>
1869 /// <remarks>Expressed in 256m units</remarks>
1870 /// <param name='swCorner'></param>
1871 /// <param name='neCorner'></param>
1872 private void GetMegaregionViewRange(out Vector2 swCorner, out Vector2 neCorner)
1873 {
1874 Border[] northBorders = Scene.NorthBorders.ToArray();
1875 Border[] eastBorders = Scene.EastBorders.ToArray();
1876
1877 Vector2 extent = Vector2.Zero;
1878 for (int i = 0; i < eastBorders.Length; i++)
1879 {
1880 extent.X = (eastBorders[i].BorderLine.Z > extent.X) ? eastBorders[i].BorderLine.Z : extent.X;
1881 }
1882 for (int i = 0; i < northBorders.Length; i++)
1883 {
1884 extent.Y = (northBorders[i].BorderLine.Z > extent.Y) ? northBorders[i].BorderLine.Z : extent.Y;
1885 }
1886
1887 // Loss of fraction on purpose
1888 extent.X = ((int)extent.X / (int)Constants.RegionSize);
1889 extent.Y = ((int)extent.Y / (int)Constants.RegionSize);
1890
1891 swCorner.X = Scene.RegionInfo.RegionLocX - 1;
1892 swCorner.Y = Scene.RegionInfo.RegionLocY - 1;
1893 neCorner.X = Scene.RegionInfo.RegionLocX + extent.X;
1894 neCorner.Y = Scene.RegionInfo.RegionLocY + extent.Y;
1895 }
1896
1897 /// <summary>
1579 /// Return the list of regions that are considered to be neighbours to the given scene. 1898 /// Return the list of regions that are considered to be neighbours to the given scene.
1580 /// </summary> 1899 /// </summary>
1581 /// <param name="pScene"></param> 1900 /// <param name="pScene"></param>
@@ -1587,15 +1906,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1587 Scene pScene = avatar.Scene; 1906 Scene pScene = avatar.Scene;
1588 RegionInfo m_regionInfo = pScene.RegionInfo; 1907 RegionInfo m_regionInfo = pScene.RegionInfo;
1589 1908
1590 Border[] northBorders = pScene.NorthBorders.ToArray();
1591 Border[] southBorders = pScene.SouthBorders.ToArray();
1592 Border[] eastBorders = pScene.EastBorders.ToArray();
1593 Border[] westBorders = pScene.WestBorders.ToArray();
1594
1595 // Leaving this as a "megaregions" computation vs "non-megaregions" computation; it isn't 1909 // Leaving this as a "megaregions" computation vs "non-megaregions" computation; it isn't
1596 // clear what should be done with a "far view" given that megaregions already extended the 1910 // clear what should be done with a "far view" given that megaregions already extended the
1597 // view to include everything in the megaregion 1911 // view to include everything in the megaregion
1598 if (northBorders.Length <= 1 && southBorders.Length <= 1 && eastBorders.Length <= 1 && westBorders.Length <= 1) 1912 if (m_regionCombinerModule == null || !m_regionCombinerModule.IsRootForMegaregion(Scene.RegionInfo.RegionID))
1599 { 1913 {
1600 int dd = avatar.DrawDistance < Constants.RegionSize ? (int)Constants.RegionSize : (int)avatar.DrawDistance; 1914 int dd = avatar.DrawDistance < Constants.RegionSize ? (int)Constants.RegionSize : (int)avatar.DrawDistance;
1601 1915
@@ -1613,27 +1927,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1613 } 1927 }
1614 else 1928 else
1615 { 1929 {
1616 Vector2 extent = Vector2.Zero; 1930 Vector2 swCorner, neCorner;
1617 for (int i = 0; i < eastBorders.Length; i++) 1931 GetMegaregionViewRange(out swCorner, out neCorner);
1618 {
1619 extent.X = (eastBorders[i].BorderLine.Z > extent.X) ? eastBorders[i].BorderLine.Z : extent.X;
1620 }
1621 for (int i = 0; i < northBorders.Length; i++)
1622 {
1623 extent.Y = (northBorders[i].BorderLine.Z > extent.Y) ? northBorders[i].BorderLine.Z : extent.Y;
1624 }
1625
1626 // Loss of fraction on purpose
1627 extent.X = ((int)extent.X / (int)Constants.RegionSize) + 1;
1628 extent.Y = ((int)extent.Y / (int)Constants.RegionSize) + 1;
1629
1630 int startX = (int)(pRegionLocX - 1) * (int)Constants.RegionSize;
1631 int startY = (int)(pRegionLocY - 1) * (int)Constants.RegionSize;
1632 1932
1633 int endX = ((int)pRegionLocX + (int)extent.X) * (int)Constants.RegionSize; 1933 List<GridRegion> neighbours
1634 int endY = ((int)pRegionLocY + (int)extent.Y) * (int)Constants.RegionSize; 1934 = pScene.GridService.GetRegionRange(
1935 m_regionInfo.ScopeID,
1936 (int)swCorner.X * (int)Constants.RegionSize,
1937 (int)neCorner.X * (int)Constants.RegionSize,
1938 (int)swCorner.Y * (int)Constants.RegionSize,
1939 (int)neCorner.Y * (int)Constants.RegionSize);
1635 1940
1636 List<GridRegion> neighbours = pScene.GridService.GetRegionRange(m_regionInfo.ScopeID, startX, endX, startY, endY);
1637 neighbours.RemoveAll(delegate(GridRegion r) { return r.RegionID == m_regionInfo.RegionID; }); 1941 neighbours.RemoveAll(delegate(GridRegion r) { return r.RegionID == m_regionInfo.RegionID; });
1638 1942
1639 return neighbours; 1943 return neighbours;
@@ -2054,7 +2358,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2054 2358
2055 public bool IsInTransit(UUID id) 2359 public bool IsInTransit(UUID id)
2056 { 2360 {
2057 return m_entityTransferStateMachine.IsInTransit(id); 2361 return m_entityTransferStateMachine.GetAgentTransferState(id) != null;
2058 } 2362 }
2059 2363
2060 protected void ReInstantiateScripts(ScenePresence sp) 2364 protected void ReInstantiateScripts(ScenePresence sp)
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
index 70dd1bc..e903383 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
@@ -51,10 +51,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
51 /// This is a state machine. 51 /// This is a state machine.
52 /// 52 ///
53 /// [Entry] => Preparing 53 /// [Entry] => Preparing
54 /// Preparing => { Transferring || CleaningUp || [Exit] } 54 /// Preparing => { Transferring || Cancelling || CleaningUp || Aborting || [Exit] }
55 /// Transferring => { ReceivedAtDestination || CleaningUp } 55 /// Transferring => { ReceivedAtDestination || Cancelling || CleaningUp || Aborting }
56 /// ReceivedAtDestination => CleaningUp 56 /// Cancelling => CleaningUp || Aborting
57 /// ReceivedAtDestination => CleaningUp || Aborting
57 /// CleaningUp => [Exit] 58 /// CleaningUp => [Exit]
59 /// Aborting => [Exit]
58 /// 60 ///
59 /// In other words, agents normally travel throwing Preparing => Transferring => ReceivedAtDestination => CleaningUp 61 /// In other words, agents normally travel throwing Preparing => Transferring => ReceivedAtDestination => CleaningUp
60 /// However, any state can transition to CleaningUp if the teleport has failed. 62 /// However, any state can transition to CleaningUp if the teleport has failed.
@@ -64,7 +66,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
64 Preparing, // The agent is being prepared for transfer 66 Preparing, // The agent is being prepared for transfer
65 Transferring, // The agent is in the process of being transferred to a destination 67 Transferring, // The agent is in the process of being transferred to a destination
66 ReceivedAtDestination, // The destination has notified us that the agent has been successfully received 68 ReceivedAtDestination, // The destination has notified us that the agent has been successfully received
67 CleaningUp // The agent is being changed to child/removed after a transfer 69 CleaningUp, // The agent is being changed to child/removed after a transfer
70 Cancelling, // The user has cancelled the teleport but we have yet to act upon this.
71 Aborting // The transfer is aborting. Unlike Cancelling, no compensating actions should be performed
68 } 72 }
69 73
70 /// <summary> 74 /// <summary>
@@ -115,42 +119,114 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
115 /// <param name='newState'></param> 119 /// <param name='newState'></param>
116 /// <returns></returns> 120 /// <returns></returns>
117 /// <exception cref='Exception'>Illegal transitions will throw an Exception</exception> 121 /// <exception cref='Exception'>Illegal transitions will throw an Exception</exception>
118 internal void UpdateInTransit(UUID id, AgentTransferState newState) 122 internal bool UpdateInTransit(UUID id, AgentTransferState newState)
119 { 123 {
124 bool transitionOkay = false;
125
126 // We don't want to throw an exception on cancel since this can come it at any time.
127 bool failIfNotOkay = true;
128
129 // Should be a failure message if failure is not okay.
130 string failureMessage = null;
131
132 AgentTransferState? oldState = null;
133
120 lock (m_agentsInTransit) 134 lock (m_agentsInTransit)
121 { 135 {
122 // Illegal to try and update an agent that's not actually in transit. 136 // Illegal to try and update an agent that's not actually in transit.
123 if (!m_agentsInTransit.ContainsKey(id)) 137 if (!m_agentsInTransit.ContainsKey(id))
124 throw new Exception( 138 {
125 string.Format( 139 if (newState != AgentTransferState.Cancelling && newState != AgentTransferState.Aborting)
126 "Agent with ID {0} is not registered as in transit in {1}", 140 failureMessage = string.Format(
127 id, m_mod.Scene.RegionInfo.RegionName)); 141 "Agent with ID {0} is not registered as in transit in {1}",
128 142 id, m_mod.Scene.RegionInfo.RegionName);
129 AgentTransferState oldState = m_agentsInTransit[id]; 143 else
144 failIfNotOkay = false;
145 }
146 else
147 {
148 oldState = m_agentsInTransit[id];
130 149
131 bool transitionOkay = false; 150 if (newState == AgentTransferState.Aborting)
151 {
152 transitionOkay = true;
153 }
154 else if (newState == AgentTransferState.CleaningUp && oldState != AgentTransferState.CleaningUp)
155 {
156 transitionOkay = true;
157 }
158 else if (newState == AgentTransferState.Transferring && oldState == AgentTransferState.Preparing)
159 {
160 transitionOkay = true;
161 }
162 else if (newState == AgentTransferState.ReceivedAtDestination && oldState == AgentTransferState.Transferring)
163 {
164 transitionOkay = true;
165 }
166 else
167 {
168 if (newState == AgentTransferState.Cancelling
169 && (oldState == AgentTransferState.Preparing || oldState == AgentTransferState.Transferring))
170 {
171 transitionOkay = true;
172 }
173 else
174 {
175 failIfNotOkay = false;
176 }
177 }
132 178
133 if (newState == AgentTransferState.CleaningUp && oldState != AgentTransferState.CleaningUp) 179 if (!transitionOkay)
134 transitionOkay = true; 180 failureMessage
135 else if (newState == AgentTransferState.Transferring && oldState == AgentTransferState.Preparing) 181 = string.Format(
136 transitionOkay = true; 182 "Agent with ID {0} is not allowed to move from old transit state {1} to new state {2} in {3}",
137 else if (newState == AgentTransferState.ReceivedAtDestination && oldState == AgentTransferState.Transferring) 183 id, oldState, newState, m_mod.Scene.RegionInfo.RegionName);
138 transitionOkay = true; 184 }
139 185
140 if (transitionOkay) 186 if (transitionOkay)
187 {
141 m_agentsInTransit[id] = newState; 188 m_agentsInTransit[id] = newState;
142 else 189
143 throw new Exception( 190// m_log.DebugFormat(
144 string.Format( 191// "[ENTITY TRANSFER STATE MACHINE]: Changed agent with id {0} from state {1} to {2} in {3}",
145 "Agent with ID {0} is not allowed to move from old transit state {1} to new state {2} in {3}", 192// id, oldState, newState, m_mod.Scene.Name);
146 id, oldState, newState, m_mod.Scene.RegionInfo.RegionName)); 193 }
194 else if (failIfNotOkay)
195 {
196 throw new Exception(failureMessage);
197 }
198// else
199// {
200// if (oldState != null)
201// m_log.DebugFormat(
202// "[ENTITY TRANSFER STATE MACHINE]: Ignored change of agent with id {0} from state {1} to {2} in {3}",
203// id, oldState, newState, m_mod.Scene.Name);
204// else
205// m_log.DebugFormat(
206// "[ENTITY TRANSFER STATE MACHINE]: Ignored change of agent with id {0} to state {1} in {2} since agent not in transit",
207// id, newState, m_mod.Scene.Name);
208// }
147 } 209 }
210
211 return transitionOkay;
148 } 212 }
149 213
150 internal bool IsInTransit(UUID id) 214 /// <summary>
215 /// Gets the current agent transfer state.
216 /// </summary>
217 /// <returns>Null if the agent is not in transit</returns>
218 /// <param name='id'>
219 /// Identifier.
220 /// </param>
221 internal AgentTransferState? GetAgentTransferState(UUID id)
151 { 222 {
152 lock (m_agentsInTransit) 223 lock (m_agentsInTransit)
153 return m_agentsInTransit.ContainsKey(id); 224 {
225 if (!m_agentsInTransit.ContainsKey(id))
226 return null;
227 else
228 return m_agentsInTransit[id];
229 }
154 } 230 }
155 231
156 /// <summary> 232 /// <summary>
@@ -203,14 +279,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
203 279
204 lock (m_agentsInTransit) 280 lock (m_agentsInTransit)
205 { 281 {
206 if (!IsInTransit(id)) 282 AgentTransferState? currentState = GetAgentTransferState(id);
283
284 if (currentState == null)
207 throw new Exception( 285 throw new Exception(
208 string.Format( 286 string.Format(
209 "Asked to wait for destination callback for agent with ID {0} in {1} but agent is not in transit", 287 "Asked to wait for destination callback for agent with ID {0} in {1} but agent is not in transit",
210 id, m_mod.Scene.RegionInfo.RegionName)); 288 id, m_mod.Scene.RegionInfo.RegionName));
211 289
212 AgentTransferState currentState = m_agentsInTransit[id];
213
214 if (currentState != AgentTransferState.Transferring && currentState != AgentTransferState.ReceivedAtDestination) 290 if (currentState != AgentTransferState.Transferring && currentState != AgentTransferState.ReceivedAtDestination)
215 throw new Exception( 291 throw new Exception(
216 string.Format( 292 string.Format(
@@ -222,8 +298,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
222 298
223 // There should be no race condition here since no other code should be removing the agent transfer or 299 // There should be no race condition here since no other code should be removing the agent transfer or
224 // changing the state to another other than Transferring => ReceivedAtDestination. 300 // changing the state to another other than Transferring => ReceivedAtDestination.
225 while (m_agentsInTransit[id] != AgentTransferState.ReceivedAtDestination && count-- > 0) 301
302 while (count-- > 0)
226 { 303 {
304 lock (m_agentsInTransit)
305 {
306 if (m_agentsInTransit[id] == AgentTransferState.ReceivedAtDestination)
307 break;
308 }
309
227// m_log.Debug(" >>> Waiting... " + count); 310// m_log.Debug(" >>> Waiting... " + count);
228 Thread.Sleep(100); 311 Thread.Sleep(100);
229 } 312 }
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
index f3a0b01..d372c0e 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
@@ -199,7 +199,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
199 199
200 public override void RemoveRegion(Scene scene) 200 public override void RemoveRegion(Scene scene)
201 { 201 {
202 base.AddRegion(scene); 202 base.RemoveRegion(scene);
203 203
204 if (m_Enabled) 204 if (m_Enabled)
205 scene.UnregisterModuleInterface<IUserAgentVerificationModule>(this); 205 scene.UnregisterModuleInterface<IUserAgentVerificationModule>(this);
@@ -212,11 +212,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
212 protected override GridRegion GetFinalDestination(GridRegion region) 212 protected override GridRegion GetFinalDestination(GridRegion region)
213 { 213 {
214 int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, region.RegionID); 214 int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, region.RegionID);
215 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: region {0} flags: {1}", region.RegionID, flags); 215 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: region {0} flags: {1}", region.RegionName, flags);
216 216
217 if ((flags & (int)OpenSim.Framework.RegionFlags.Hyperlink) != 0) 217 if ((flags & (int)OpenSim.Framework.RegionFlags.Hyperlink) != 0)
218 { 218 {
219 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Destination region {0} is hyperlink", region.RegionID); 219 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Destination region is hyperlink");
220 GridRegion real_destination = m_GatekeeperConnector.GetHyperlinkRegion(region, region.RegionID); 220 GridRegion real_destination = m_GatekeeperConnector.GetHyperlinkRegion(region, region.RegionID);
221 if (real_destination != null) 221 if (real_destination != null)
222 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: GetFinalDestination serveruri -> {0}", real_destination.ServerURI); 222 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: GetFinalDestination serveruri -> {0}", real_destination.ServerURI);
diff --git a/OpenSim/Region/CoreModules/Framework/InterfaceCommander/Command.cs b/OpenSim/Region/CoreModules/Framework/InterfaceCommander/Command.cs
index 4004135..b9786ae 100644
--- a/OpenSim/Region/CoreModules/Framework/InterfaceCommander/Command.cs
+++ b/OpenSim/Region/CoreModules/Framework/InterfaceCommander/Command.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using OpenSim.Region.Framework.Interfaces; 30using OpenSim.Region.Framework.Interfaces;
31using OpenMetaverse;
31 32
32namespace OpenSim.Region.CoreModules.Framework.InterfaceCommander 33namespace OpenSim.Region.CoreModules.Framework.InterfaceCommander
33{ 34{
@@ -152,6 +153,9 @@ namespace OpenSim.Region.CoreModules.Framework.InterfaceCommander
152 case "Boolean": 153 case "Boolean":
153 m_args[i].ArgumentValue = Boolean.Parse(arg.ToString()); 154 m_args[i].ArgumentValue = Boolean.Parse(arg.ToString());
154 break; 155 break;
156 case "UUID":
157 m_args[i].ArgumentValue = UUID.Parse(arg.ToString());
158 break;
155 default: 159 default:
156 Console.WriteLine("ERROR: Unknown desired type for argument " + m_args[i].Name + " on command " + m_name); 160 Console.WriteLine("ERROR: Unknown desired type for argument " + m_args[i].Name + " on command " + m_name);
157 break; 161 break;
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
index f8ec6de..7871eda 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
@@ -71,7 +71,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
71 71
72 #region Internal functions 72 #region Internal functions
73 73
74 public AssetMetadata FetchMetadata(string url, UUID assetID) 74 private AssetMetadata FetchMetadata(string url, UUID assetID)
75 { 75 {
76 if (!url.EndsWith("/") && !url.EndsWith("=")) 76 if (!url.EndsWith("/") && !url.EndsWith("="))
77 url = url + "/"; 77 url = url + "/";
@@ -86,6 +86,27 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
86 return meta; 86 return meta;
87 } 87 }
88 88
89 private AssetBase FetchAsset(string url, UUID assetID)
90 {
91 // Test if it's already here
92 AssetBase asset = m_scene.AssetService.Get(assetID.ToString());
93 if (asset == null)
94 {
95 if (!url.EndsWith("/") && !url.EndsWith("="))
96 url = url + "/";
97
98 asset = m_scene.AssetService.Get(url + assetID.ToString());
99
100 //if (asset != null)
101 // m_log.DebugFormat("[HG ASSET MAPPER]: Fetched asset {0} of type {1} from {2} ", assetID, asset.Metadata.Type, url);
102 //else
103 // m_log.DebugFormat("[HG ASSET MAPPER]: Unable to fetch asset {0} from {1} ", assetID, url);
104
105 }
106
107 return asset;
108 }
109
89 public bool PostAsset(string url, AssetBase asset) 110 public bool PostAsset(string url, AssetBase asset)
90 { 111 {
91 if (asset != null) 112 if (asset != null)
@@ -228,11 +249,22 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
228 if (meta == null) 249 if (meta == null)
229 return; 250 return;
230 251
231 // The act of gathering UUIDs downloads the assets from the remote server 252 // The act of gathering UUIDs downloads some assets from the remote server
253 // but not all...
232 Dictionary<UUID, AssetType> ids = new Dictionary<UUID, AssetType>(); 254 Dictionary<UUID, AssetType> ids = new Dictionary<UUID, AssetType>();
233 HGUuidGatherer uuidGatherer = new HGUuidGatherer(m_scene.AssetService, userAssetURL); 255 HGUuidGatherer uuidGatherer = new HGUuidGatherer(m_scene.AssetService, userAssetURL);
234 uuidGatherer.GatherAssetUuids(assetID, (AssetType)meta.Type, ids); 256 uuidGatherer.GatherAssetUuids(assetID, (AssetType)meta.Type, ids);
235 257 m_log.DebugFormat("[HG ASSET MAPPER]: Preparing to get {0} assets", ids.Count);
258 bool success = true;
259 foreach (UUID uuid in ids.Keys)
260 if (FetchAsset(userAssetURL, uuid) == null)
261 success = false;
262
263 // maybe all pieces got here...
264 if (!success)
265 m_log.DebugFormat("[HG ASSET MAPPER]: Problems getting item {0} from asset server {1}", assetID, userAssetURL);
266 else
267 m_log.DebugFormat("[HG ASSET MAPPER]: Successfully got item {0} from asset server {1}", assetID, userAssetURL);
236 } 268 }
237 269
238 270
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
index 964efda..b2b628d 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
@@ -88,12 +88,14 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
88 IConfig thisModuleConfig = source.Configs["HGInventoryAccessModule"]; 88 IConfig thisModuleConfig = source.Configs["HGInventoryAccessModule"];
89 if (thisModuleConfig != null) 89 if (thisModuleConfig != null)
90 { 90 {
91 // legacy configuration [obsolete] 91 m_HomeURI = Util.GetConfigVarFromSections<string>(source, "HomeURI",
92 m_HomeURI = thisModuleConfig.GetString("ProfileServerURI", string.Empty); 92 new string[] { "Startup", "Hypergrid", "HGInventoryAccessModule" }, String.Empty);
93 // preferred 93 m_ThisGatekeeper = Util.GetConfigVarFromSections<string>(source, "GatekeeperURI",
94 m_HomeURI = thisModuleConfig.GetString("HomeURI", m_HomeURI); 94 new string[] { "Startup", "Hypergrid", "HGInventoryAccessModule" }, String.Empty);
95 // Legacy. Renove soon!
96 m_ThisGatekeeper = thisModuleConfig.GetString("Gatekeeper", m_ThisGatekeeper);
97
95 m_OutboundPermission = thisModuleConfig.GetBoolean("OutboundPermission", true); 98 m_OutboundPermission = thisModuleConfig.GetBoolean("OutboundPermission", true);
96 m_ThisGatekeeper = thisModuleConfig.GetString("Gatekeeper", string.Empty);
97 m_RestrictInventoryAccessAbroad = thisModuleConfig.GetBoolean("RestrictInventoryAccessAbroad", true); 99 m_RestrictInventoryAccessAbroad = thisModuleConfig.GetBoolean("RestrictInventoryAccessAbroad", true);
98 } 100 }
99 else 101 else
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index 6e5a4a5..5aad7f0 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -47,6 +47,7 @@ using OpenMetaverse;
47using log4net; 47using log4net;
48using Nini.Config; 48using Nini.Config;
49using Mono.Addins; 49using Mono.Addins;
50using PermissionMask = OpenSim.Framework.PermissionMask;
50 51
51namespace OpenSim.Region.CoreModules.Framework.InventoryAccess 52namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
52{ 53{
@@ -398,7 +399,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
398 objectGroup.RootPart.NextOwnerMask &= 399 objectGroup.RootPart.NextOwnerMask &=
399 ((uint)PermissionMask.Copy | 400 ((uint)PermissionMask.Copy |
400 (uint)PermissionMask.Transfer | 401 (uint)PermissionMask.Transfer |
401 (uint)PermissionMask.Modify); 402 (uint)PermissionMask.Modify |
403 (uint)PermissionMask.Export);
402 objectGroup.RootPart.NextOwnerMask |= 404 objectGroup.RootPart.NextOwnerMask |=
403 (uint)PermissionMask.Move; 405 (uint)PermissionMask.Move;
404 406
@@ -506,7 +508,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
506 InventoryItemBase item, SceneObjectGroup so, List<SceneObjectGroup> objsForEffectivePermissions, 508 InventoryItemBase item, SceneObjectGroup so, List<SceneObjectGroup> objsForEffectivePermissions,
507 IClientAPI remoteClient) 509 IClientAPI remoteClient)
508 { 510 {
509 uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move) | 7; 511 uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move | PermissionMask.Export) | 7;
510 // For the porposes of inventory, an object is modify if the prims 512 // For the porposes of inventory, an object is modify if the prims
511 // are modify. This allows renaming an object that contains no 513 // are modify. This allows renaming an object that contains no
512 // mod items. 514 // mod items.
@@ -555,6 +557,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
555 (uint)PermissionMask.Transfer | 557 (uint)PermissionMask.Transfer |
556 (uint)PermissionMask.Modify | 558 (uint)PermissionMask.Modify |
557 (uint)PermissionMask.Move | 559 (uint)PermissionMask.Move |
560 (uint)PermissionMask.Export |
558 7); // Preserve folded permissions 561 7); // Preserve folded permissions
559 } 562 }
560 563
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs
index 21d8bd7..ad1a0e1 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs
@@ -49,7 +49,7 @@ using OpenSim.Tests.Common.Mock;
49namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests 49namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
50{ 50{
51 [TestFixture] 51 [TestFixture]
52 public class InventoryAccessModuleTests 52 public class InventoryAccessModuleTests : OpenSimTestCase
53 { 53 {
54 protected TestScene m_scene; 54 protected TestScene m_scene;
55 protected BasicInventoryAccessModule m_iam; 55 protected BasicInventoryAccessModule m_iam;
@@ -57,8 +57,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
57 protected TestClient m_tc; 57 protected TestClient m_tc;
58 58
59 [SetUp] 59 [SetUp]
60 public void SetUp() 60 public override void SetUp()
61 { 61 {
62 base.SetUp();
63
62 m_iam = new BasicInventoryAccessModule(); 64 m_iam = new BasicInventoryAccessModule();
63 65
64 IConfigSource config = new IniConfigSource(); 66 IConfigSource config = new IniConfigSource();
@@ -107,7 +109,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
107 item1.AssetID = asset1.FullID; 109 item1.AssetID = asset1.FullID;
108 item1.ID = item1Id; 110 item1.ID = item1Id;
109 InventoryFolderBase objsFolder 111 InventoryFolderBase objsFolder
110 = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, m_userId, "Objects")[0]; 112 = InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, m_userId, "Objects")[0];
111 item1.Folder = objsFolder.ID; 113 item1.Folder = objsFolder.ID;
112 m_scene.AddInventoryItem(item1); 114 m_scene.AddInventoryItem(item1);
113 115
@@ -157,7 +159,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests
157 item1.AssetID = asset1.FullID; 159 item1.AssetID = asset1.FullID;
158 item1.ID = item1Id; 160 item1.ID = item1Id;
159 InventoryFolderBase objsFolder 161 InventoryFolderBase objsFolder
160 = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, m_userId, "Objects")[0]; 162 = InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, m_userId, "Objects")[0];
161 item1.Folder = objsFolder.ID; 163 item1.Folder = objsFolder.ID;
162 m_scene.AddInventoryItem(item1); 164 m_scene.AddInventoryItem(item1);
163 165
diff --git a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs
index ec22146..d07cff4 100644
--- a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs
@@ -43,6 +43,7 @@ using OpenMetaverse;
43using log4net; 43using log4net;
44using Mono.Addins; 44using Mono.Addins;
45using Nini.Config; 45using Nini.Config;
46using PermissionMask = OpenSim.Framework.PermissionMask;
46 47
47namespace OpenSim.Region.CoreModules.Framework.Library 48namespace OpenSim.Region.CoreModules.Framework.Library
48{ 49{
diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs
index d84460a..64feec1 100644
--- a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs
@@ -33,6 +33,7 @@ using log4net;
33using Nini.Config; 33using Nini.Config;
34using OpenMetaverse; 34using OpenMetaverse;
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Framework.Monitoring;
36using OpenSim.Framework.Servers; 37using OpenSim.Framework.Servers;
37using OpenSim.Region.CoreModules.Framework.Monitoring.Alerts; 38using OpenSim.Region.CoreModules.Framework.Monitoring.Alerts;
38using OpenSim.Region.CoreModules.Framework.Monitoring.Monitors; 39using OpenSim.Region.CoreModules.Framework.Monitoring.Monitors;
@@ -100,6 +101,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
100 "/monitorstats/" + Uri.EscapeDataString(m_scene.RegionInfo.RegionName), StatsPage); 101 "/monitorstats/" + Uri.EscapeDataString(m_scene.RegionInfo.RegionName), StatsPage);
101 102
102 AddMonitors(); 103 AddMonitors();
104 RegisterStatsManagerRegionStatistics();
103 } 105 }
104 106
105 public void RemoveRegion(Scene scene) 107 public void RemoveRegion(Scene scene)
@@ -109,6 +111,9 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
109 111
110 MainServer.Instance.RemoveHTTPHandler("GET", "/monitorstats/" + m_scene.RegionInfo.RegionID); 112 MainServer.Instance.RemoveHTTPHandler("GET", "/monitorstats/" + m_scene.RegionInfo.RegionID);
111 MainServer.Instance.RemoveHTTPHandler("GET", "/monitorstats/" + Uri.EscapeDataString(m_scene.RegionInfo.RegionName)); 113 MainServer.Instance.RemoveHTTPHandler("GET", "/monitorstats/" + Uri.EscapeDataString(m_scene.RegionInfo.RegionName));
114
115 UnRegisterStatsManagerRegionStatistics();
116
112 m_scene = null; 117 m_scene = null;
113 } 118 }
114 119
@@ -399,6 +404,45 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
399 { 404 {
400 m_log.Error("[Monitor] " + reporter.Name + " for " + m_scene.RegionInfo.RegionName + " reports " + reason + " (Fatal: " + fatal + ")"); 405 m_log.Error("[Monitor] " + reporter.Name + " for " + m_scene.RegionInfo.RegionName + " reports " + reason + " (Fatal: " + fatal + ")");
401 } 406 }
407
408 private List<Stat> registeredStats = new List<Stat>();
409 private void MakeStat(string pName, string pUnitName, Action<Stat> act)
410 {
411 Stat tempStat = new Stat(pName, pName, pName, pUnitName, "scene", m_scene.RegionInfo.RegionName, StatType.Pull, act, StatVerbosity.Info);
412 StatsManager.RegisterStat(tempStat);
413 registeredStats.Add(tempStat);
414 }
415 private void RegisterStatsManagerRegionStatistics()
416 {
417 MakeStat("RootAgents", "avatars", (s) => { s.Value = m_scene.SceneGraph.GetRootAgentCount(); });
418 MakeStat("ChildAgents", "avatars", (s) => { s.Value = m_scene.SceneGraph.GetChildAgentCount(); });
419 MakeStat("TotalPrims", "objects", (s) => { s.Value = m_scene.SceneGraph.GetTotalObjectsCount(); });
420 MakeStat("ActivePrims", "objects", (s) => { s.Value = m_scene.SceneGraph.GetActiveObjectsCount(); });
421 MakeStat("ActiveScripts", "scripts", (s) => { s.Value = m_scene.SceneGraph.GetActiveScriptsCount(); });
422
423 MakeStat("TimeDilation", "sec/sec", (s) => { s.Value = m_scene.StatsReporter.LastReportedSimStats[0]; });
424 MakeStat("SimFPS", "fps", (s) => { s.Value = m_scene.StatsReporter.LastReportedSimStats[1]; });
425 MakeStat("PhysicsFPS", "fps", (s) => { s.Value = m_scene.StatsReporter.LastReportedSimStats[2]; });
426 MakeStat("AgentUpdates", "updates/sec", (s) => { s.Value = m_scene.StatsReporter.LastReportedSimStats[3]; });
427 MakeStat("FrameTime", "ms/sec", (s) => { s.Value = m_scene.StatsReporter.LastReportedSimStats[8]; });
428 MakeStat("NetTime", "ms/sec", (s) => { s.Value = m_scene.StatsReporter.LastReportedSimStats[9]; });
429 MakeStat("OtherTime", "ms/sec", (s) => { s.Value = m_scene.StatsReporter.LastReportedSimStats[12]; });
430 MakeStat("PhysicsTime", "ms/sec", (s) => { s.Value = m_scene.StatsReporter.LastReportedSimStats[10]; });
431 MakeStat("AgentTime", "ms/sec", (s) => { s.Value = m_scene.StatsReporter.LastReportedSimStats[16]; });
432 MakeStat("ImageTime", "ms/sec", (s) => { s.Value = m_scene.StatsReporter.LastReportedSimStats[11]; });
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]; });
435 }
436
437 private void UnRegisterStatsManagerRegionStatistics()
438 {
439 foreach (Stat stat in registeredStats)
440 {
441 StatsManager.DeregisterStat(stat);
442 stat.Dispose();
443 }
444 registeredStats.Clear();
445 }
402 446
403 } 447 }
404} 448} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Framework/Statistics/Logging/BinaryLoggingModule.cs b/OpenSim/Region/CoreModules/Framework/Statistics/Logging/BinaryLoggingModule.cs
index fb74cc6..f3436d1 100644
--- a/OpenSim/Region/CoreModules/Framework/Statistics/Logging/BinaryLoggingModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Statistics/Logging/BinaryLoggingModule.cs
@@ -57,7 +57,7 @@ namespace OpenSim.Region.CoreModules.Framework.Statistics.Logging
57 try 57 try
58 { 58 {
59 IConfig statConfig = source.Configs["Statistics.Binary"]; 59 IConfig statConfig = source.Configs["Statistics.Binary"];
60 if (statConfig.Contains("enabled") && statConfig.GetBoolean("enabled")) 60 if (statConfig != null && statConfig.Contains("enabled") && statConfig.GetBoolean("enabled"))
61 { 61 {
62 if (statConfig.Contains("collect_region_stats")) 62 if (statConfig.Contains("collect_region_stats"))
63 { 63 {
diff --git a/OpenSim/Region/CoreModules/Framework/Statistics/Logging/LogWriter.cs b/OpenSim/Region/CoreModules/Framework/Statistics/Logging/LogWriter.cs
index fd8d5e3..2fe9026 100755
--- a/OpenSim/Region/CoreModules/Framework/Statistics/Logging/LogWriter.cs
+++ b/OpenSim/Region/CoreModules/Framework/Statistics/Logging/LogWriter.cs
@@ -52,6 +52,7 @@ namespace OpenSim.Region.CoreModules.Framework.Statistics.Logging
52 private TimeSpan m_logFileLife; 52 private TimeSpan m_logFileLife;
53 private DateTime m_logFileEndTime; 53 private DateTime m_logFileEndTime;
54 private Object m_logFileWriteLock = new Object(); 54 private Object m_logFileWriteLock = new Object();
55 private bool m_flushWrite;
55 56
56 // set externally when debugging. If let 'null', this does not write any error messages. 57 // set externally when debugging. If let 'null', this does not write any error messages.
57 public ILog ErrorLogger = null; 58 public ILog ErrorLogger = null;
@@ -73,7 +74,9 @@ namespace OpenSim.Region.CoreModules.Framework.Statistics.Logging
73 /// <param name="dir">The directory to create the log file in. May be 'null' for default.</param> 74 /// <param name="dir">The directory to create the log file in. May be 'null' for default.</param>
74 /// <param name="headr">The characters that begin the log file name. May be 'null' for default.</param> 75 /// <param name="headr">The characters that begin the log file name. May be 'null' for default.</param>
75 /// <param name="maxFileTime">Maximum age of a log file in minutes. If zero, will set default.</param> 76 /// <param name="maxFileTime">Maximum age of a log file in minutes. If zero, will set default.</param>
76 public LogWriter(string dir, string headr, int maxFileTime) 77 /// <param name="flushWrite">Whether to do a flush after every log write. Best left off but
78 /// if one is looking for a crash, this is a good thing to turn on.</param>
79 public LogWriter(string dir, string headr, int maxFileTime, bool flushWrite)
77 { 80 {
78 m_logDirectory = dir == null ? "." : dir; 81 m_logDirectory = dir == null ? "." : dir;
79 82
@@ -86,8 +89,14 @@ namespace OpenSim.Region.CoreModules.Framework.Statistics.Logging
86 m_logFileLife = new TimeSpan(0, m_logMaxFileTimeMin, 0); 89 m_logFileLife = new TimeSpan(0, m_logMaxFileTimeMin, 0);
87 m_logFileEndTime = DateTime.Now + m_logFileLife; 90 m_logFileEndTime = DateTime.Now + m_logFileLife;
88 91
92 m_flushWrite = flushWrite;
93
89 Enabled = true; 94 Enabled = true;
90 } 95 }
96 // Constructor that assumes flushWrite is off.
97 public LogWriter(string dir, string headr, int maxFileTime) : this(dir, headr, maxFileTime, false)
98 {
99 }
91 100
92 public void Dispose() 101 public void Dispose()
93 { 102 {
@@ -127,7 +136,7 @@ namespace OpenSim.Region.CoreModules.Framework.Statistics.Logging
127 { 136 {
128 lock (m_logFileWriteLock) 137 lock (m_logFileWriteLock)
129 { 138 {
130 DateTime now = DateTime.Now; 139 DateTime now = DateTime.UtcNow;
131 if (m_logFile == null || now > m_logFileEndTime) 140 if (m_logFile == null || now > m_logFileEndTime)
132 { 141 {
133 if (m_logFile != null) 142 if (m_logFile != null)
@@ -153,6 +162,8 @@ namespace OpenSim.Region.CoreModules.Framework.Statistics.Logging
153 buff.Append(line); 162 buff.Append(line);
154 buff.Append("\r\n"); 163 buff.Append("\r\n");
155 m_logFile.Write(buff.ToString()); 164 m_logFile.Write(buff.ToString());
165 if (m_flushWrite)
166 m_logFile.Flush();
156 } 167 }
157 } 168 }
158 } 169 }
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
index 86e7004..77e8b00 100644
--- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
@@ -181,6 +181,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
181 181
182 m_log.DebugFormat("[USER MANAGEMENT MODULE]: HandleAvatarPickerRequest for {0}", query); 182 m_log.DebugFormat("[USER MANAGEMENT MODULE]: HandleAvatarPickerRequest for {0}", query);
183 183
184 // searhc the user accounts service
184 List<UserAccount> accs = m_Scenes[0].UserAccountService.GetUserAccounts(m_Scenes[0].RegionInfo.ScopeID, query); 185 List<UserAccount> accs = m_Scenes[0].UserAccountService.GetUserAccounts(m_Scenes[0].RegionInfo.ScopeID, query);
185 186
186 List<UserData> users = new List<UserData>(); 187 List<UserData> users = new List<UserData>();
@@ -196,6 +197,12 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
196 } 197 }
197 } 198 }
198 199
200 // search the local cache
201 foreach (UserData data in m_UserCache.Values)
202 if (users.Find(delegate(UserData d) { return d.Id == data.Id; }) == null &&
203 (data.FirstName.StartsWith(query) || data.LastName.StartsWith(query)))
204 users.Add(data);
205
199 AddAdditionalUsers(avatarID, query, users); 206 AddAdditionalUsers(avatarID, query, users);
200 207
201 AvatarPickerReplyPacket replyPacket = (AvatarPickerReplyPacket)PacketPool.Instance.GetPacket(PacketType.AvatarPickerReply); 208 AvatarPickerReplyPacket replyPacket = (AvatarPickerReplyPacket)PacketPool.Instance.GetPacket(PacketType.AvatarPickerReply);
@@ -433,6 +440,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
433 public void AddUser(UUID uuid, string first, string last, string homeURL) 440 public void AddUser(UUID uuid, string first, string last, string homeURL)
434 { 441 {
435 //m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, first {1}, last {2}, url {3}", uuid, first, last, homeURL); 442 //m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, first {1}, last {2}, url {3}", uuid, first, last, homeURL);
443 if (homeURL == string.Empty)
444 return;
445
436 AddUser(uuid, homeURL + ";" + first + " " + last); 446 AddUser(uuid, homeURL + ";" + first + " " + last);
437 } 447 }
438 448