diff options
author | UbitUmarov | 2012-07-17 00:54:23 +0100 |
---|---|---|
committer | UbitUmarov | 2012-07-17 00:54:23 +0100 |
commit | d5f4fb7b50fb7c594b018f8241399e22f88fc951 (patch) | |
tree | 8f3dab3d170596f02b1d1d836a0bc08a3e6b8ebd /OpenSim/Region/CoreModules | |
parent | UbitOde: remove useless water collider from active code. (diff) | |
parent | Merge branch 'avination' into careminster (diff) | |
download | opensim-SC-d5f4fb7b50fb7c594b018f8241399e22f88fc951.zip opensim-SC-d5f4fb7b50fb7c594b018f8241399e22f88fc951.tar.gz opensim-SC-d5f4fb7b50fb7c594b018f8241399e22f88fc951.tar.bz2 opensim-SC-d5f4fb7b50fb7c594b018f8241399e22f88fc951.tar.xz |
Merge branch 'avination' into ubitwork
Diffstat (limited to 'OpenSim/Region/CoreModules')
74 files changed, 3680 insertions, 1885 deletions
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs index 874693e..7081989 100644 --- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs +++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs | |||
@@ -42,8 +42,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
42 | public class AssetTransactionModule : INonSharedRegionModule, | 42 | public class AssetTransactionModule : INonSharedRegionModule, |
43 | IAgentAssetTransactions | 43 | IAgentAssetTransactions |
44 | { | 44 | { |
45 | // private static readonly ILog m_log = LogManager.GetLogger( | 45 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
46 | // MethodBase.GetCurrentMethod().DeclaringType); | ||
47 | 46 | ||
48 | protected Scene m_Scene; | 47 | protected Scene m_Scene; |
49 | private bool m_dumpAssetsToFile = false; | 48 | private bool m_dumpAssetsToFile = false; |
@@ -209,15 +208,15 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
209 | /// and comes through this method. | 208 | /// and comes through this method. |
210 | /// </summary> | 209 | /// </summary> |
211 | /// <param name="remoteClient"></param> | 210 | /// <param name="remoteClient"></param> |
211 | /// <param name="part"></param> | ||
212 | /// <param name="transactionID"></param> | 212 | /// <param name="transactionID"></param> |
213 | /// <param name="item"></param> | 213 | /// <param name="item"></param> |
214 | public void HandleTaskItemUpdateFromTransaction(IClientAPI remoteClient, | 214 | public void HandleTaskItemUpdateFromTransaction( |
215 | SceneObjectPart part, UUID transactionID, | 215 | IClientAPI remoteClient, SceneObjectPart part, UUID transactionID, TaskInventoryItem item) |
216 | TaskInventoryItem item) | ||
217 | { | 216 | { |
218 | // m_log.DebugFormat( | 217 | m_log.DebugFormat( |
219 | // "[TRANSACTIONS MANAGER] Called HandleTaskItemUpdateFromTransaction with item {0}", | 218 | "[TRANSACTIONS MANAGER] Called HandleTaskItemUpdateFromTransaction with item {0} in {1} for {2} in {3}", |
220 | // item.Name); | 219 | item.Name, part.Name, remoteClient.Name, m_Scene.RegionInfo.RegionName); |
221 | 220 | ||
222 | AgentAssetTransactions transactions = | 221 | AgentAssetTransactions transactions = |
223 | GetUserTransactions(remoteClient.AgentId); | 222 | GetUserTransactions(remoteClient.AgentId); |
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs index 127ca1d..7d7176f 100644 --- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs | |||
@@ -83,7 +83,7 @@ namespace Flotsam.RegionModules.AssetCache | |||
83 | private Dictionary<string, ManualResetEvent> m_CurrentlyWriting = new Dictionary<string, ManualResetEvent>(); | 83 | private Dictionary<string, ManualResetEvent> m_CurrentlyWriting = new Dictionary<string, ManualResetEvent>(); |
84 | private int m_WaitOnInprogressTimeout = 3000; | 84 | private int m_WaitOnInprogressTimeout = 3000; |
85 | #else | 85 | #else |
86 | private List<string> m_CurrentlyWriting = new List<string>(); | 86 | private HashSet<string> m_CurrentlyWriting = new HashSet<string>(); |
87 | #endif | 87 | #endif |
88 | 88 | ||
89 | private bool m_FileCacheEnabled = true; | 89 | private bool m_FileCacheEnabled = true; |
@@ -143,7 +143,7 @@ namespace Flotsam.RegionModules.AssetCache | |||
143 | IConfig assetConfig = source.Configs["AssetCache"]; | 143 | IConfig assetConfig = source.Configs["AssetCache"]; |
144 | if (assetConfig == null) | 144 | if (assetConfig == null) |
145 | { | 145 | { |
146 | m_log.Warn( | 146 | m_log.Debug( |
147 | "[FLOTSAM ASSET CACHE]: AssetCache section missing from config (not copied config-include/FlotsamCache.ini.example? Using defaults."); | 147 | "[FLOTSAM ASSET CACHE]: AssetCache section missing from config (not copied config-include/FlotsamCache.ini.example? Using defaults."); |
148 | } | 148 | } |
149 | else | 149 | else |
@@ -272,7 +272,11 @@ namespace Flotsam.RegionModules.AssetCache | |||
272 | // the other thread has updated the time for us. | 272 | // the other thread has updated the time for us. |
273 | try | 273 | try |
274 | { | 274 | { |
275 | File.SetLastAccessTime(filename, DateTime.Now); | 275 | lock (m_CurrentlyWriting) |
276 | { | ||
277 | if (!m_CurrentlyWriting.Contains(filename)) | ||
278 | File.SetLastAccessTime(filename, DateTime.Now); | ||
279 | } | ||
276 | } | 280 | } |
277 | catch | 281 | catch |
278 | { | 282 | { |
diff --git a/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs b/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs index 5adb845..c91b25f 100644 --- a/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs +++ b/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs | |||
@@ -65,7 +65,7 @@ namespace OpenSim.Region.CoreModules.Asset.Tests | |||
65 | config.Configs["AssetCache"].Set("MemoryCacheEnabled", "true"); | 65 | config.Configs["AssetCache"].Set("MemoryCacheEnabled", "true"); |
66 | 66 | ||
67 | m_cache = new FlotsamAssetCache(); | 67 | m_cache = new FlotsamAssetCache(); |
68 | m_scene = SceneHelpers.SetupScene(); | 68 | m_scene = new SceneHelpers().SetupScene(); |
69 | SceneHelpers.SetupSceneModules(m_scene, config, m_cache); | 69 | SceneHelpers.SetupSceneModules(m_scene, config, m_cache); |
70 | } | 70 | } |
71 | 71 | ||
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index fd7cad2..394b90a 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | |||
@@ -50,7 +50,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
50 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 50 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
51 | 51 | ||
52 | private Scene m_scene; | 52 | private Scene m_scene; |
53 | private IDialogModule m_dialogModule; | 53 | private IInventoryAccessModule m_invAccessModule; |
54 | 54 | ||
55 | /// <summary> | 55 | /// <summary> |
56 | /// Are attachments enabled? | 56 | /// Are attachments enabled? |
@@ -72,7 +72,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
72 | public void AddRegion(Scene scene) | 72 | public void AddRegion(Scene scene) |
73 | { | 73 | { |
74 | m_scene = scene; | 74 | m_scene = scene; |
75 | m_dialogModule = m_scene.RequestModuleInterface<IDialogModule>(); | ||
76 | m_scene.RegisterModuleInterface<IAttachmentsModule>(this); | 75 | m_scene.RegisterModuleInterface<IAttachmentsModule>(this); |
77 | 76 | ||
78 | if (Enabled) | 77 | if (Enabled) |
@@ -89,7 +88,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
89 | m_scene.EventManager.OnNewClient -= SubscribeToClientEvents; | 88 | m_scene.EventManager.OnNewClient -= SubscribeToClientEvents; |
90 | } | 89 | } |
91 | 90 | ||
92 | public void RegionLoaded(Scene scene) {} | 91 | public void RegionLoaded(Scene scene) |
92 | { | ||
93 | m_invAccessModule = m_scene.RequestModuleInterface<IInventoryAccessModule>(); | ||
94 | } | ||
93 | 95 | ||
94 | public void Close() | 96 | public void Close() |
95 | { | 97 | { |
@@ -100,6 +102,56 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
100 | 102 | ||
101 | #region IAttachmentsModule | 103 | #region IAttachmentsModule |
102 | 104 | ||
105 | public void CopyAttachments(IScenePresence sp, AgentData ad) | ||
106 | { | ||
107 | lock (sp.AttachmentsSyncLock) | ||
108 | { | ||
109 | // Attachment objects | ||
110 | List<SceneObjectGroup> attachments = sp.GetAttachments(); | ||
111 | if (attachments.Count > 0) | ||
112 | { | ||
113 | ad.AttachmentObjects = new List<ISceneObject>(); | ||
114 | ad.AttachmentObjectStates = new List<string>(); | ||
115 | // IScriptModule se = m_scene.RequestModuleInterface<IScriptModule>(); | ||
116 | sp.InTransitScriptStates.Clear(); | ||
117 | |||
118 | foreach (SceneObjectGroup sog in attachments) | ||
119 | { | ||
120 | // We need to make a copy and pass that copy | ||
121 | // because of transfers withn the same sim | ||
122 | ISceneObject clone = sog.CloneForNewScene(); | ||
123 | // Attachment module assumes that GroupPosition holds the offsets...! | ||
124 | ((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos; | ||
125 | ((SceneObjectGroup)clone).IsAttachment = false; | ||
126 | ad.AttachmentObjects.Add(clone); | ||
127 | string state = sog.GetStateSnapshot(); | ||
128 | ad.AttachmentObjectStates.Add(state); | ||
129 | sp.InTransitScriptStates.Add(state); | ||
130 | // Let's remove the scripts of the original object here | ||
131 | sog.RemoveScriptInstances(true); | ||
132 | } | ||
133 | } | ||
134 | } | ||
135 | } | ||
136 | |||
137 | public void CopyAttachments(AgentData ad, IScenePresence sp) | ||
138 | { | ||
139 | if (ad.AttachmentObjects != null && ad.AttachmentObjects.Count > 0) | ||
140 | { | ||
141 | lock (sp.AttachmentsSyncLock) | ||
142 | sp.ClearAttachments(); | ||
143 | |||
144 | int i = 0; | ||
145 | foreach (ISceneObject so in ad.AttachmentObjects) | ||
146 | { | ||
147 | ((SceneObjectGroup)so).LocalId = 0; | ||
148 | ((SceneObjectGroup)so).RootPart.ClearUpdateSchedule(); | ||
149 | so.SetState(ad.AttachmentObjectStates[i++], m_scene); | ||
150 | m_scene.IncomingCreateObject(Vector3.Zero, so); | ||
151 | } | ||
152 | } | ||
153 | } | ||
154 | |||
103 | /// <summary> | 155 | /// <summary> |
104 | /// RezAttachments. This should only be called upon login on the first region. | 156 | /// RezAttachments. This should only be called upon login on the first region. |
105 | /// Attachment rezzings on crossings and TPs are done in a different way. | 157 | /// Attachment rezzings on crossings and TPs are done in a different way. |
@@ -185,40 +237,55 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
185 | if (sp.PresenceType == PresenceType.Npc) | 237 | if (sp.PresenceType == PresenceType.Npc) |
186 | RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p, null); | 238 | RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p, null); |
187 | else | 239 | else |
188 | RezSingleAttachmentFromInventory(sp, attach.ItemID, p, true, d); | 240 | RezSingleAttachmentFromInventory(sp, attach.ItemID, p, d); |
189 | } | 241 | } |
190 | catch (Exception e) | 242 | catch (Exception e) |
191 | { | 243 | { |
192 | m_log.ErrorFormat("[ATTACHMENTS MODULE]: Unable to rez attachment: {0}{1}", e.Message, e.StackTrace); | 244 | UUID agentId = (sp.ControllingClient == null) ? (UUID)null : sp.ControllingClient.AgentId; |
245 | m_log.ErrorFormat("[ATTACHMENTS MODULE]: Unable to rez attachment with itemID {0}, assetID {1}, point {2} for {3}: {4}\n{5}", | ||
246 | attach.ItemID, attach.AssetID, p, agentId, e.Message, e.StackTrace); | ||
193 | } | 247 | } |
194 | } | 248 | } |
195 | } | 249 | } |
196 | 250 | ||
197 | public void SaveChangedAttachments(IScenePresence sp, bool saveAllScripted) | 251 | public void DeRezAttachments(IScenePresence sp, bool saveChanged, bool saveAllScripted) |
198 | { | 252 | { |
199 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name); | ||
200 | |||
201 | if (!Enabled) | 253 | if (!Enabled) |
202 | return; | 254 | return; |
203 | 255 | ||
204 | foreach (SceneObjectGroup grp in sp.GetAttachments()) | 256 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name); |
257 | |||
258 | lock (sp.AttachmentsSyncLock) | ||
205 | { | 259 | { |
206 | grp.IsAttachment = false; | 260 | foreach (SceneObjectGroup so in sp.GetAttachments()) |
207 | grp.AbsolutePosition = grp.RootPart.AttachedPos; | 261 | { |
208 | UpdateKnownItem(sp, grp, saveAllScripted); | 262 | // We can only remove the script instances from the script engine after we've retrieved their xml state |
209 | grp.IsAttachment = true; | 263 | // when we update the attachment item. |
264 | m_scene.DeleteSceneObject(so, false, false); | ||
265 | |||
266 | if (saveChanged || saveAllScripted) | ||
267 | { | ||
268 | so.IsAttachment = false; | ||
269 | so.AbsolutePosition = so.RootPart.AttachedPos; | ||
270 | UpdateKnownItem(sp, so, saveAllScripted); | ||
271 | } | ||
272 | |||
273 | so.RemoveScriptInstances(true); | ||
274 | } | ||
275 | |||
276 | sp.ClearAttachments(); | ||
210 | } | 277 | } |
211 | } | 278 | } |
212 | 279 | ||
213 | public void DeleteAttachmentsFromScene(IScenePresence sp, bool silent) | 280 | public void DeleteAttachmentsFromScene(IScenePresence sp, bool silent) |
214 | { | 281 | { |
215 | // m_log.DebugFormat( | ||
216 | // "[ATTACHMENTS MODULE]: Deleting attachments from scene {0} for {1}, silent = {2}", | ||
217 | // m_scene.RegionInfo.RegionName, sp.Name, silent); | ||
218 | |||
219 | if (!Enabled) | 282 | if (!Enabled) |
220 | return; | 283 | return; |
221 | 284 | ||
285 | // m_log.DebugFormat( | ||
286 | // "[ATTACHMENTS MODULE]: Deleting attachments from scene {0} for {1}, silent = {2}", | ||
287 | // m_scene.RegionInfo.RegionName, sp.Name, silent); | ||
288 | |||
222 | foreach (SceneObjectGroup sop in sp.GetAttachments()) | 289 | foreach (SceneObjectGroup sop in sp.GetAttachments()) |
223 | { | 290 | { |
224 | sop.Scene.DeleteSceneObject(sop, silent); | 291 | sop.Scene.DeleteSceneObject(sop, silent); |
@@ -234,6 +301,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
234 | // m_log.DebugFormat( | 301 | // m_log.DebugFormat( |
235 | // "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})", | 302 | // "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})", |
236 | // group.Name, group.LocalId, sp.Name, attachmentPt, silent); | 303 | // group.Name, group.LocalId, sp.Name, attachmentPt, silent); |
304 | |||
305 | if (group.GetSittingAvatarsCount() != 0) | ||
306 | { | ||
307 | // m_log.WarnFormat( | ||
308 | // "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since {4} avatars are still sitting on it", | ||
309 | // group.Name, group.LocalId, sp.Name, attachmentPt, group.GetSittingAvatarsCount()); | ||
310 | |||
311 | return false; | ||
312 | } | ||
237 | 313 | ||
238 | if (sp.GetAttachments(attachmentPt).Contains(group)) | 314 | if (sp.GetAttachments(attachmentPt).Contains(group)) |
239 | { | 315 | { |
@@ -294,32 +370,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
294 | group.AttachmentPoint = attachmentPt; | 370 | group.AttachmentPoint = attachmentPt; |
295 | group.AbsolutePosition = attachPos; | 371 | group.AbsolutePosition = attachPos; |
296 | 372 | ||
297 | // We also don't want to do any of the inventory operations for an NPC. | ||
298 | if (sp.PresenceType != PresenceType.Npc) | 373 | if (sp.PresenceType != PresenceType.Npc) |
299 | { | 374 | UpdateUserInventoryWithAttachment(sp, group, attachmentPt); |
300 | // Remove any previous attachments | ||
301 | List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt); | ||
302 | |||
303 | // At the moment we can only deal with a single attachment | ||
304 | if (attachments.Count != 0) | ||
305 | { | ||
306 | UUID oldAttachmentItemID = attachments[0].FromItemID; | ||
307 | |||
308 | if (oldAttachmentItemID != UUID.Zero) | ||
309 | DetachSingleAttachmentToInvInternal(sp, oldAttachmentItemID); | ||
310 | else | ||
311 | m_log.WarnFormat( | ||
312 | "[ATTACHMENTS MODULE]: When detaching existing attachment {0} {1} at point {2} to make way for {3} {4} for {5}, couldn't find the associated item ID to adjust inventory attachment record!", | ||
313 | attachments[0].Name, attachments[0].LocalId, attachmentPt, group.Name, group.LocalId, sp.Name); | ||
314 | } | ||
315 | |||
316 | // Add the new attachment to inventory if we don't already have it. | ||
317 | UUID newAttachmentItemID = group.FromItemID; | ||
318 | if (newAttachmentItemID == UUID.Zero) | ||
319 | newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID; | ||
320 | |||
321 | ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group); | ||
322 | } | ||
323 | 375 | ||
324 | AttachToAgent(sp, group, attachmentPt, attachPos, silent); | 376 | AttachToAgent(sp, group, attachmentPt, attachPos, silent); |
325 | } | 377 | } |
@@ -327,12 +379,36 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
327 | return true; | 379 | return true; |
328 | } | 380 | } |
329 | 381 | ||
382 | private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt) | ||
383 | { | ||
384 | // Remove any previous attachments | ||
385 | List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt); | ||
386 | |||
387 | // At the moment we can only deal with a single attachment | ||
388 | if (attachments.Count != 0) | ||
389 | { | ||
390 | if (attachments[0].FromItemID != UUID.Zero) | ||
391 | DetachSingleAttachmentToInvInternal(sp, attachments[0]); | ||
392 | else | ||
393 | m_log.WarnFormat( | ||
394 | "[ATTACHMENTS MODULE]: When detaching existing attachment {0} {1} at point {2} to make way for {3} {4} for {5}, couldn't find the associated item ID to adjust inventory attachment record!", | ||
395 | attachments[0].Name, attachments[0].LocalId, attachmentPt, group.Name, group.LocalId, sp.Name); | ||
396 | } | ||
397 | |||
398 | // Add the new attachment to inventory if we don't already have it. | ||
399 | UUID newAttachmentItemID = group.FromItemID; | ||
400 | if (newAttachmentItemID == UUID.Zero) | ||
401 | newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID; | ||
402 | |||
403 | ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group); | ||
404 | } | ||
405 | |||
330 | public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt) | 406 | public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt) |
331 | { | 407 | { |
332 | return RezSingleAttachmentFromInventory(sp, itemID, AttachmentPt, true, null); | 408 | return RezSingleAttachmentFromInventory(sp, itemID, AttachmentPt, null); |
333 | } | 409 | } |
334 | 410 | ||
335 | public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt, bool updateInventoryStatus, XmlDocument doc) | 411 | public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt, XmlDocument doc) |
336 | { | 412 | { |
337 | if (!Enabled) | 413 | if (!Enabled) |
338 | return null; | 414 | return null; |
@@ -371,12 +447,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
371 | return null; | 447 | return null; |
372 | } | 448 | } |
373 | 449 | ||
374 | SceneObjectGroup att = RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, doc); | 450 | return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, doc); |
375 | |||
376 | if (att == null) | ||
377 | DetachSingleAttachmentToInv(sp, itemID); | ||
378 | |||
379 | return att; | ||
380 | } | 451 | } |
381 | 452 | ||
382 | public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist) | 453 | public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist) |
@@ -453,18 +524,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
453 | m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero); | 524 | m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero); |
454 | } | 525 | } |
455 | 526 | ||
456 | public void DetachSingleAttachmentToInv(IScenePresence sp, UUID itemID) | 527 | public void DetachSingleAttachmentToInv(IScenePresence sp, SceneObjectGroup so) |
457 | { | 528 | { |
458 | lock (sp.AttachmentsSyncLock) | 529 | lock (sp.AttachmentsSyncLock) |
459 | { | 530 | { |
460 | // Save avatar attachment information | 531 | // Save avatar attachment information |
461 | m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + sp.UUID + ", ItemID: " + itemID); | 532 | // m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + sp.UUID + ", ItemID: " + itemID); |
533 | |||
534 | if (so.AttachedAvatar != sp.UUID) | ||
535 | { | ||
536 | m_log.WarnFormat( | ||
537 | "[ATTACHMENTS MODULE]: Tried to detach object {0} from {1} {2} but attached avatar id was {3} in {4}", | ||
538 | so.Name, sp.Name, sp.UUID, so.AttachedAvatar, m_scene.RegionInfo.RegionName); | ||
462 | 539 | ||
463 | bool changed = sp.Appearance.DetachAttachment(itemID); | 540 | return; |
541 | } | ||
542 | |||
543 | bool changed = sp.Appearance.DetachAttachment(so.FromItemID); | ||
464 | if (changed && m_scene.AvatarFactory != null) | 544 | if (changed && m_scene.AvatarFactory != null) |
465 | m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); | 545 | m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); |
466 | 546 | ||
467 | DetachSingleAttachmentToInvInternal(sp, itemID); | 547 | DetachSingleAttachmentToInvInternal(sp, so); |
468 | } | 548 | } |
469 | } | 549 | } |
470 | 550 | ||
@@ -473,17 +553,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
473 | if (!Enabled) | 553 | if (!Enabled) |
474 | return; | 554 | return; |
475 | 555 | ||
476 | // First we save the | ||
477 | // attachment point information, then we update the relative | ||
478 | // positioning. Then we have to mark the object as NOT an | ||
479 | // attachment. This is necessary in order to correctly save | ||
480 | // and retrieve GroupPosition information for the attachment. | ||
481 | // Finally, we restore the object's attachment status. | ||
482 | uint attachmentPoint = sog.AttachmentPoint; | ||
483 | sog.UpdateGroupPosition(pos); | 556 | sog.UpdateGroupPosition(pos); |
484 | sog.IsAttachment = false; | ||
485 | sog.AbsolutePosition = sog.RootPart.AttachedPos; | ||
486 | sog.AttachmentPoint = attachmentPoint; | ||
487 | sog.HasGroupChanged = true; | 557 | sog.HasGroupChanged = true; |
488 | } | 558 | } |
489 | 559 | ||
@@ -526,6 +596,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
526 | /// </remarks> | 596 | /// </remarks> |
527 | /// <param name="sp"></param> | 597 | /// <param name="sp"></param> |
528 | /// <param name="grp"></param> | 598 | /// <param name="grp"></param> |
599 | /// <param name="saveAllScripted"></param> | ||
529 | private void UpdateKnownItem(IScenePresence sp, SceneObjectGroup grp, bool saveAllScripted) | 600 | private void UpdateKnownItem(IScenePresence sp, SceneObjectGroup grp, bool saveAllScripted) |
530 | { | 601 | { |
531 | // Saving attachments for NPCs messes them up for the real owner! | 602 | // Saving attachments for NPCs messes them up for the real owner! |
@@ -538,9 +609,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
538 | 609 | ||
539 | if (grp.HasGroupChanged || (saveAllScripted && grp.ContainsScripts())) | 610 | if (grp.HasGroupChanged || (saveAllScripted && grp.ContainsScripts())) |
540 | { | 611 | { |
541 | m_log.DebugFormat( | 612 | // m_log.DebugFormat( |
542 | "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}", | 613 | // "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}", |
543 | grp.UUID, grp.AttachmentPoint); | 614 | // grp.UUID, grp.AttachmentPoint); |
544 | 615 | ||
545 | string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp); | 616 | string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp); |
546 | 617 | ||
@@ -571,12 +642,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
571 | } | 642 | } |
572 | grp.HasGroupChanged = false; // Prevent it being saved over and over | 643 | grp.HasGroupChanged = false; // Prevent it being saved over and over |
573 | } | 644 | } |
574 | else | 645 | // else |
575 | { | 646 | // { |
576 | m_log.DebugFormat( | 647 | // m_log.DebugFormat( |
577 | "[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}", | 648 | // "[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}", |
578 | grp.UUID, grp.AttachmentPoint); | 649 | // grp.UUID, grp.AttachmentPoint); |
579 | } | 650 | // } |
580 | } | 651 | } |
581 | 652 | ||
582 | /// <summary> | 653 | /// <summary> |
@@ -594,9 +665,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
594 | private void AttachToAgent( | 665 | private void AttachToAgent( |
595 | IScenePresence sp, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent) | 666 | IScenePresence sp, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent) |
596 | { | 667 | { |
597 | // m_log.DebugFormat( | 668 | // m_log.DebugFormat( |
598 | // "[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", | 669 | // "[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", |
599 | // so.Name, avatar.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos); | 670 | // so.Name, sp.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos); |
600 | 671 | ||
601 | so.DetachFromBackup(); | 672 | so.DetachFromBackup(); |
602 | 673 | ||
@@ -627,6 +698,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
627 | { | 698 | { |
628 | m_scene.SendKillObject(new List<uint> { so.RootPart.LocalId }); | 699 | m_scene.SendKillObject(new List<uint> { so.RootPart.LocalId }); |
629 | } | 700 | } |
701 | else if (so.HasPrivateAttachmentPoint) | ||
702 | { | ||
703 | // m_log.DebugFormat( | ||
704 | // "[ATTACHMENTS MODULE]: Killing private HUD {0} for avatars other than {1} at attachment point {2}", | ||
705 | // so.Name, sp.Name, so.AttachmentPoint); | ||
706 | |||
707 | // As this scene object can now only be seen by the attaching avatar, tell everybody else in the | ||
708 | // scene that it's no longer in their awareness. | ||
709 | m_scene.ForEachClient( | ||
710 | client => | ||
711 | { if (client.AgentId != so.AttachedAvatar) | ||
712 | client.SendKillObject(m_scene.RegionInfo.RegionHandle, new List<uint>() { so.LocalId }); | ||
713 | }); | ||
714 | } | ||
630 | 715 | ||
631 | so.IsSelected = false; // fudge.... | 716 | so.IsSelected = false; // fudge.... |
632 | so.ScheduleGroupForFullUpdate(); | 717 | so.ScheduleGroupForFullUpdate(); |
@@ -645,210 +730,124 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
645 | /// <returns>The user inventory item created that holds the attachment.</returns> | 730 | /// <returns>The user inventory item created that holds the attachment.</returns> |
646 | private InventoryItemBase AddSceneObjectAsNewAttachmentInInv(IScenePresence sp, SceneObjectGroup grp) | 731 | private InventoryItemBase AddSceneObjectAsNewAttachmentInInv(IScenePresence sp, SceneObjectGroup grp) |
647 | { | 732 | { |
733 | if (m_invAccessModule == null) | ||
734 | return null; | ||
735 | |||
648 | // m_log.DebugFormat( | 736 | // m_log.DebugFormat( |
649 | // "[ATTACHMENTS MODULE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2}", | 737 | // "[ATTACHMENTS MODULE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2}", |
650 | // grp.Name, grp.LocalId, remoteClient.Name); | 738 | // grp.Name, grp.LocalId, remoteClient.Name); |
651 | 739 | ||
652 | // Vector3 inventoryStoredPosition = new Vector3 | 740 | InventoryItemBase newItem |
653 | // (((grp.AbsolutePosition.X > (int)Constants.RegionSize) | 741 | = m_invAccessModule.CopyToInventory( |
654 | // ? (float)Constants.RegionSize - 6 | 742 | DeRezAction.TakeCopy, |
655 | // : grp.AbsolutePosition.X) | 743 | m_scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object).ID, |
656 | // , | 744 | new List<SceneObjectGroup> { grp }, |
657 | // (grp.AbsolutePosition.Y > (int)Constants.RegionSize) | 745 | sp.ControllingClient, true)[0]; |
658 | // ? (float)Constants.RegionSize - 6 | ||
659 | // : grp.AbsolutePosition.Y, | ||
660 | // grp.AbsolutePosition.Z); | ||
661 | // | ||
662 | // Vector3 originalPosition = grp.AbsolutePosition; | ||
663 | // | ||
664 | // grp.AbsolutePosition = inventoryStoredPosition; | ||
665 | |||
666 | // If we're being called from a script, then trying to serialize that same script's state will not complete | ||
667 | // in any reasonable time period. Therefore, we'll avoid it. The worst that can happen is that if | ||
668 | // the client/server crashes rather than logging out normally, the attachment's scripts will resume | ||
669 | // without state on relog. Arguably, this is what we want anyway. | ||
670 | string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp, false); | ||
671 | |||
672 | // grp.AbsolutePosition = originalPosition; | ||
673 | |||
674 | AssetBase asset = m_scene.CreateAsset( | ||
675 | grp.GetPartName(grp.LocalId), | ||
676 | grp.GetPartDescription(grp.LocalId), | ||
677 | (sbyte)AssetType.Object, | ||
678 | Utils.StringToBytes(sceneObjectXml), | ||
679 | sp.UUID); | ||
680 | |||
681 | m_scene.AssetService.Store(asset); | ||
682 | |||
683 | InventoryItemBase item = new InventoryItemBase(); | ||
684 | item.CreatorId = grp.RootPart.CreatorID.ToString(); | ||
685 | item.CreatorData = grp.RootPart.CreatorData; | ||
686 | item.Owner = sp.UUID; | ||
687 | item.ID = UUID.Random(); | ||
688 | item.AssetID = asset.FullID; | ||
689 | item.Description = asset.Description; | ||
690 | item.Name = asset.Name; | ||
691 | item.AssetType = asset.Type; | ||
692 | item.InvType = (int)InventoryType.Object; | ||
693 | |||
694 | InventoryFolderBase folder = m_scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object); | ||
695 | if (folder != null) | ||
696 | item.Folder = folder.ID; | ||
697 | else // oopsies | ||
698 | item.Folder = UUID.Zero; | ||
699 | |||
700 | // Nix the special bits we used to use for slam and the folded perms | ||
701 | uint allowablePermissionsMask = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move); | ||
702 | |||
703 | if ((sp.UUID != grp.RootPart.OwnerID) && m_scene.Permissions.PropagatePermissions()) | ||
704 | { | ||
705 | item.BasePermissions = grp.RootPart.BaseMask & grp.RootPart.NextOwnerMask & allowablePermissionsMask; | ||
706 | item.CurrentPermissions = grp.RootPart.BaseMask & grp.RootPart.NextOwnerMask & allowablePermissionsMask; | ||
707 | item.NextPermissions = grp.RootPart.NextOwnerMask & allowablePermissionsMask; | ||
708 | item.EveryOnePermissions = grp.RootPart.EveryoneMask & grp.RootPart.NextOwnerMask & allowablePermissionsMask; | ||
709 | item.GroupPermissions = grp.RootPart.GroupMask & grp.RootPart.NextOwnerMask & allowablePermissionsMask; | ||
710 | } | ||
711 | else | ||
712 | { | ||
713 | item.BasePermissions = grp.RootPart.BaseMask & allowablePermissionsMask; | ||
714 | item.CurrentPermissions = grp.RootPart.OwnerMask & allowablePermissionsMask; | ||
715 | item.NextPermissions = grp.RootPart.NextOwnerMask & allowablePermissionsMask; | ||
716 | item.EveryOnePermissions = grp.RootPart.EveryoneMask & allowablePermissionsMask; | ||
717 | item.GroupPermissions = grp.RootPart.GroupMask & allowablePermissionsMask; | ||
718 | } | ||
719 | item.CreationDate = Util.UnixTimeSinceEpoch(); | ||
720 | 746 | ||
721 | // sets itemID so client can show item as 'attached' in inventory | 747 | // sets itemID so client can show item as 'attached' in inventory |
722 | grp.FromItemID = item.ID; | 748 | grp.FromItemID = newItem.ID; |
723 | |||
724 | if (m_scene.AddInventoryItem(item)) | ||
725 | { | ||
726 | sp.ControllingClient.SendInventoryItemCreateUpdate(item, 0); | ||
727 | } | ||
728 | else | ||
729 | { | ||
730 | if (m_dialogModule != null) | ||
731 | m_dialogModule.SendAlertToUser(sp.ControllingClient, "Operation failed"); | ||
732 | } | ||
733 | 749 | ||
734 | return item; | 750 | return newItem; |
735 | } | 751 | } |
736 | 752 | ||
737 | // What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards. | 753 | private void DetachSingleAttachmentToInvInternal(IScenePresence sp, SceneObjectGroup so) |
738 | // To LocalId or UUID, *THAT* is the question. How now Brown UUID?? | ||
739 | private void DetachSingleAttachmentToInvInternal(IScenePresence sp, UUID itemID) | ||
740 | { | 754 | { |
741 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Detaching item {0} to inventory for {1}", itemID, sp.Name); | 755 | // m_log.DebugFormat("[ATTACHMENTS MODULE]: Detaching item {0} to inventory for {1}", itemID, sp.Name); |
742 | 756 | ||
743 | if (itemID == UUID.Zero) // If this happened, someone made a mistake.... | 757 | m_scene.EventManager.TriggerOnAttach(so.LocalId, so.FromItemID, UUID.Zero); |
744 | return; | 758 | sp.RemoveAttachment(so); |
745 | |||
746 | // We can NOT use the dictionries here, as we are looking | ||
747 | // for an entity by the fromAssetID, which is NOT the prim UUID | ||
748 | EntityBase[] detachEntities = m_scene.GetEntities(); | ||
749 | SceneObjectGroup group; | ||
750 | |||
751 | lock (sp.AttachmentsSyncLock) | ||
752 | { | ||
753 | foreach (EntityBase entity in detachEntities) | ||
754 | { | ||
755 | if (entity is SceneObjectGroup) | ||
756 | { | ||
757 | group = (SceneObjectGroup)entity; | ||
758 | if (group.FromItemID == itemID) | ||
759 | { | ||
760 | m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero); | ||
761 | sp.RemoveAttachment(group); | ||
762 | 759 | ||
763 | // Prepare sog for storage | 760 | // We can only remove the script instances from the script engine after we've retrieved their xml state |
764 | group.AttachedAvatar = UUID.Zero; | 761 | // when we update the attachment item. |
765 | group.RootPart.SetParentLocalId(0); | 762 | m_scene.DeleteSceneObject(so, false, false); |
766 | group.IsAttachment = false; | ||
767 | group.AbsolutePosition = group.RootPart.AttachedPos; | ||
768 | 763 | ||
769 | UpdateKnownItem(sp, group, true); | 764 | // Prepare sog for storage |
770 | m_scene.DeleteSceneObject(group, false); | 765 | so.AttachedAvatar = UUID.Zero; |
766 | so.RootPart.SetParentLocalId(0); | ||
767 | so.IsAttachment = false; | ||
768 | so.AbsolutePosition = so.RootPart.AttachedPos; | ||
771 | 769 | ||
772 | return; | 770 | UpdateKnownItem(sp, so, true); |
773 | } | 771 | so.RemoveScriptInstances(true); |
774 | } | ||
775 | } | ||
776 | } | ||
777 | } | 772 | } |
778 | 773 | ||
779 | protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal( | 774 | protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal( |
780 | IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, XmlDocument doc) | 775 | IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, XmlDocument doc) |
781 | { | 776 | { |
782 | IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>(); | 777 | if (m_invAccessModule == null) |
783 | if (invAccess != null) | 778 | return null; |
779 | |||
780 | lock (sp.AttachmentsSyncLock) | ||
784 | { | 781 | { |
785 | lock (sp.AttachmentsSyncLock) | 782 | SceneObjectGroup objatt; |
783 | |||
784 | if (itemID != UUID.Zero) | ||
785 | objatt = m_invAccessModule.RezObject(sp.ControllingClient, | ||
786 | itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, | ||
787 | false, false, sp.UUID, true); | ||
788 | else | ||
789 | objatt = m_invAccessModule.RezObject(sp.ControllingClient, | ||
790 | null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, | ||
791 | false, false, sp.UUID, true); | ||
792 | |||
793 | if (objatt != null) | ||
786 | { | 794 | { |
787 | SceneObjectGroup objatt; | 795 | // m_log.DebugFormat( |
788 | 796 | // "[ATTACHMENTS MODULE]: Rezzed single object {0} for attachment to {1} on point {2} in {3}", | |
789 | if (itemID != UUID.Zero) | 797 | // objatt.Name, sp.Name, attachmentPt, m_scene.Name); |
790 | objatt = invAccess.RezObject(sp.ControllingClient, | 798 | |
791 | itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, | 799 | // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller. |
792 | false, false, sp.UUID, true); | 800 | objatt.HasGroupChanged = false; |
793 | else | 801 | bool tainted = false; |
794 | objatt = invAccess.RezObject(sp.ControllingClient, | 802 | if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint) |
795 | null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, | 803 | tainted = true; |
796 | false, false, sp.UUID, true); | 804 | |
797 | 805 | // FIXME: Detect whether it's really likely for AttachObject to throw an exception in the normal | |
798 | // m_log.DebugFormat( | 806 | // course of events. If not, then it's probably not worth trying to recover the situation |
799 | // "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}", | 807 | // since this is more likely to trigger further exceptions and confuse later debugging. If |
800 | // objatt.Name, remoteClient.Name, AttachmentPt); | 808 | // exceptions can be thrown in expected error conditions (not NREs) then make this consistent |
801 | 809 | // since other normal error conditions will simply return false instead. | |
802 | if (objatt != null) | 810 | // This will throw if the attachment fails |
811 | try | ||
803 | { | 812 | { |
804 | // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller. | 813 | AttachObject(sp, objatt, attachmentPt, false, false); |
805 | objatt.HasGroupChanged = false; | ||
806 | bool tainted = false; | ||
807 | if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint) | ||
808 | tainted = true; | ||
809 | |||
810 | // This will throw if the attachment fails | ||
811 | try | ||
812 | { | ||
813 | AttachObject(sp, objatt, attachmentPt, false, false); | ||
814 | } | ||
815 | catch (Exception e) | ||
816 | { | ||
817 | m_log.ErrorFormat( | ||
818 | "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}", | ||
819 | objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace); | ||
820 | |||
821 | // Make sure the object doesn't stick around and bail | ||
822 | sp.RemoveAttachment(objatt); | ||
823 | m_scene.DeleteSceneObject(objatt, false); | ||
824 | return null; | ||
825 | } | ||
826 | |||
827 | if (tainted) | ||
828 | objatt.HasGroupChanged = true; | ||
829 | |||
830 | if (doc != null) | ||
831 | { | ||
832 | objatt.LoadScriptState(doc); | ||
833 | objatt.ResetOwnerChangeFlag(); | ||
834 | } | ||
835 | |||
836 | // Fire after attach, so we don't get messy perms dialogs | ||
837 | // 4 == AttachedRez | ||
838 | objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4); | ||
839 | objatt.ResumeScripts(); | ||
840 | |||
841 | // Do this last so that event listeners have access to all the effects of the attachment | ||
842 | m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID); | ||
843 | |||
844 | return objatt; | ||
845 | } | 814 | } |
846 | else | 815 | catch (Exception e) |
816 | { | ||
817 | m_log.ErrorFormat( | ||
818 | "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}", | ||
819 | objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace); | ||
820 | |||
821 | // Make sure the object doesn't stick around and bail | ||
822 | sp.RemoveAttachment(objatt); | ||
823 | m_scene.DeleteSceneObject(objatt, false); | ||
824 | return null; | ||
825 | } | ||
826 | |||
827 | if (tainted) | ||
828 | objatt.HasGroupChanged = true; | ||
829 | |||
830 | if (doc != null) | ||
847 | { | 831 | { |
848 | m_log.WarnFormat( | 832 | objatt.LoadScriptState(doc); |
849 | "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}", | 833 | objatt.ResetOwnerChangeFlag(); |
850 | itemID, sp.Name, attachmentPt); | ||
851 | } | 834 | } |
835 | |||
836 | // Fire after attach, so we don't get messy perms dialogs | ||
837 | // 4 == AttachedRez | ||
838 | objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4); | ||
839 | objatt.ResumeScripts(); | ||
840 | |||
841 | // Do this last so that event listeners have access to all the effects of the attachment | ||
842 | m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID); | ||
843 | |||
844 | return objatt; | ||
845 | } | ||
846 | else | ||
847 | { | ||
848 | m_log.WarnFormat( | ||
849 | "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}", | ||
850 | itemID, sp.Name, attachmentPt); | ||
852 | } | 851 | } |
853 | } | 852 | } |
854 | 853 | ||
@@ -864,9 +863,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
864 | /// <param name="att"></param> | 863 | /// <param name="att"></param> |
865 | private void ShowAttachInUserInventory(IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att) | 864 | private void ShowAttachInUserInventory(IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att) |
866 | { | 865 | { |
867 | // m_log.DebugFormat( | 866 | // m_log.DebugFormat( |
868 | // "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}", | 867 | // "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}", |
869 | // att.Name, sp.Name, AttachmentPt, itemID); | 868 | // att.Name, sp.Name, AttachmentPt, itemID); |
870 | 869 | ||
871 | if (UUID.Zero == itemID) | 870 | if (UUID.Zero == itemID) |
872 | { | 871 | { |
@@ -884,7 +883,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
884 | item = m_scene.InventoryService.GetItem(item); | 883 | item = m_scene.InventoryService.GetItem(item); |
885 | bool changed = sp.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID); | 884 | bool changed = sp.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID); |
886 | if (changed && m_scene.AvatarFactory != null) | 885 | if (changed && m_scene.AvatarFactory != null) |
886 | { | ||
887 | // m_log.DebugFormat( | ||
888 | // "[ATTACHMENTS MODULE]: Queueing appearance save for {0}, attachment {1} point {2} in ShowAttachInUserInventory()", | ||
889 | // sp.Name, att.Name, AttachmentPt); | ||
890 | |||
887 | m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); | 891 | m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); |
892 | } | ||
888 | } | 893 | } |
889 | 894 | ||
890 | #endregion | 895 | #endregion |
@@ -929,9 +934,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
929 | 934 | ||
930 | private void Client_OnObjectAttach(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent) | 935 | private void Client_OnObjectAttach(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent) |
931 | { | 936 | { |
932 | // m_log.DebugFormat( | 937 | // m_log.DebugFormat( |
933 | // "[ATTACHMENTS MODULE]: Attaching object local id {0} to {1} point {2} from ground (silent = {3})", | 938 | // "[ATTACHMENTS MODULE]: Attaching object local id {0} to {1} point {2} from ground (silent = {3})", |
934 | // objectLocalID, remoteClient.Name, AttachmentPt, silent); | 939 | // objectLocalID, remoteClient.Name, AttachmentPt, silent); |
935 | 940 | ||
936 | if (!Enabled) | 941 | if (!Enabled) |
937 | return; | 942 | return; |
@@ -967,13 +972,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
967 | // Calls attach with a Zero position | 972 | // Calls attach with a Zero position |
968 | if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, true)) | 973 | if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, true)) |
969 | { | 974 | { |
970 | m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.FromItemID, remoteClient.AgentId); | 975 | // m_log.Debug( |
976 | // "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId | ||
977 | // + ", AttachmentPoint: " + AttachmentPt); | ||
971 | 978 | ||
972 | // Save avatar attachment information | 979 | // Save avatar attachment information |
973 | m_log.Debug( | 980 | m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.FromItemID, remoteClient.AgentId); |
974 | "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId | ||
975 | + ", AttachmentPoint: " + AttachmentPt); | ||
976 | |||
977 | } | 981 | } |
978 | } | 982 | } |
979 | catch (Exception e) | 983 | catch (Exception e) |
@@ -989,8 +993,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
989 | 993 | ||
990 | ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); | 994 | ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); |
991 | SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID); | 995 | SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID); |
996 | |||
992 | if (sp != null && group != null) | 997 | if (sp != null && group != null) |
993 | DetachSingleAttachmentToInv(sp, group.FromItemID); | 998 | DetachSingleAttachmentToInv(sp, group); |
994 | } | 999 | } |
995 | 1000 | ||
996 | private void Client_OnDetachAttachmentIntoInv(UUID itemID, IClientAPI remoteClient) | 1001 | private void Client_OnDetachAttachmentIntoInv(UUID itemID, IClientAPI remoteClient) |
@@ -1000,7 +1005,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
1000 | 1005 | ||
1001 | ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); | 1006 | ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); |
1002 | if (sp != null) | 1007 | if (sp != null) |
1003 | DetachSingleAttachmentToInv(sp, itemID); | 1008 | { |
1009 | lock (sp.AttachmentsSyncLock) | ||
1010 | { | ||
1011 | List<SceneObjectGroup> attachments = sp.GetAttachments(); | ||
1012 | |||
1013 | foreach (SceneObjectGroup group in attachments) | ||
1014 | { | ||
1015 | if (group.FromItemID == itemID) | ||
1016 | { | ||
1017 | DetachSingleAttachmentToInv(sp, group); | ||
1018 | return; | ||
1019 | } | ||
1020 | } | ||
1021 | } | ||
1022 | } | ||
1004 | } | 1023 | } |
1005 | 1024 | ||
1006 | private void Client_OnObjectDrop(uint soLocalId, IClientAPI remoteClient) | 1025 | private void Client_OnObjectDrop(uint soLocalId, IClientAPI remoteClient) |
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 7119ad2..cd1e1c1 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs | |||
@@ -31,6 +31,7 @@ using System.Reflection; | |||
31 | using System.Text; | 31 | using System.Text; |
32 | using System.Threading; | 32 | using System.Threading; |
33 | using System.Timers; | 33 | using System.Timers; |
34 | using System.Xml; | ||
34 | using Timer=System.Timers.Timer; | 35 | using Timer=System.Timers.Timer; |
35 | using Nini.Config; | 36 | using Nini.Config; |
36 | using NUnit.Framework; | 37 | using NUnit.Framework; |
@@ -38,11 +39,16 @@ using OpenMetaverse; | |||
38 | using OpenSim.Framework; | 39 | using OpenSim.Framework; |
39 | using OpenSim.Framework.Communications; | 40 | using OpenSim.Framework.Communications; |
40 | using OpenSim.Region.CoreModules.Avatar.Attachments; | 41 | using OpenSim.Region.CoreModules.Avatar.Attachments; |
42 | using OpenSim.Region.CoreModules.Framework; | ||
43 | using OpenSim.Region.CoreModules.Framework.EntityTransfer; | ||
41 | using OpenSim.Region.CoreModules.Framework.InventoryAccess; | 44 | using OpenSim.Region.CoreModules.Framework.InventoryAccess; |
42 | using OpenSim.Region.CoreModules.World.Serialiser; | 45 | using OpenSim.Region.CoreModules.Scripting.WorldComm; |
43 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; | 46 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; |
47 | using OpenSim.Region.CoreModules.World.Serialiser; | ||
44 | using OpenSim.Region.Framework.Scenes; | 48 | using OpenSim.Region.Framework.Scenes; |
45 | using OpenSim.Region.Framework.Interfaces; | 49 | using OpenSim.Region.Framework.Interfaces; |
50 | using OpenSim.Region.ScriptEngine.XEngine; | ||
51 | using OpenSim.Services.Interfaces; | ||
46 | using OpenSim.Tests.Common; | 52 | using OpenSim.Tests.Common; |
47 | using OpenSim.Tests.Common.Mock; | 53 | using OpenSim.Tests.Common.Mock; |
48 | 54 | ||
@@ -52,11 +58,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
52 | /// Attachment tests | 58 | /// Attachment tests |
53 | /// </summary> | 59 | /// </summary> |
54 | [TestFixture] | 60 | [TestFixture] |
55 | public class AttachmentsModuleTests | 61 | public class AttachmentsModuleTests : OpenSimTestCase |
56 | { | 62 | { |
57 | private Scene scene; | 63 | private AutoResetEvent m_chatEvent = new AutoResetEvent(false); |
58 | private AttachmentsModule m_attMod; | 64 | private OSChatMessage m_osChatMessageReceived; |
59 | private ScenePresence m_presence; | ||
60 | 65 | ||
61 | [TestFixtureSetUp] | 66 | [TestFixtureSetUp] |
62 | public void FixtureInit() | 67 | public void FixtureInit() |
@@ -65,52 +70,129 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
65 | Util.FireAndForgetMethod = FireAndForgetMethod.None; | 70 | Util.FireAndForgetMethod = FireAndForgetMethod.None; |
66 | } | 71 | } |
67 | 72 | ||
68 | [SetUp] | 73 | [TestFixtureTearDown] |
69 | public void Init() | 74 | public void TearDown() |
75 | { | ||
76 | // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple | ||
77 | // threads. Possibly, later tests should be rewritten not to worry about such things. | ||
78 | Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod; | ||
79 | } | ||
80 | |||
81 | private void OnChatFromWorld(object sender, OSChatMessage oscm) | ||
82 | { | ||
83 | // Console.WriteLine("Got chat [{0}]", oscm.Message); | ||
84 | |||
85 | m_osChatMessageReceived = oscm; | ||
86 | m_chatEvent.Set(); | ||
87 | } | ||
88 | |||
89 | private Scene CreateTestScene() | ||
70 | { | 90 | { |
71 | IConfigSource config = new IniConfigSource(); | 91 | IConfigSource config = new IniConfigSource(); |
92 | List<object> modules = new List<object>(); | ||
93 | |||
94 | AddCommonConfig(config, modules); | ||
95 | |||
96 | Scene scene | ||
97 | = new SceneHelpers().SetupScene( | ||
98 | "attachments-test-scene", TestHelpers.ParseTail(999), 1000, 1000, config); | ||
99 | SceneHelpers.SetupSceneModules(scene, config, modules.ToArray()); | ||
100 | |||
101 | return scene; | ||
102 | } | ||
103 | |||
104 | private Scene CreateScriptingEnabledTestScene() | ||
105 | { | ||
106 | IConfigSource config = new IniConfigSource(); | ||
107 | List<object> modules = new List<object>(); | ||
108 | |||
109 | AddCommonConfig(config, modules); | ||
110 | AddScriptingConfig(config, modules); | ||
111 | |||
112 | Scene scene | ||
113 | = new SceneHelpers().SetupScene( | ||
114 | "attachments-test-scene", TestHelpers.ParseTail(999), 1000, 1000, config); | ||
115 | SceneHelpers.SetupSceneModules(scene, config, modules.ToArray()); | ||
116 | |||
117 | scene.StartScripts(); | ||
118 | |||
119 | return scene; | ||
120 | } | ||
121 | |||
122 | private void AddCommonConfig(IConfigSource config, List<object> modules) | ||
123 | { | ||
72 | config.AddConfig("Modules"); | 124 | config.AddConfig("Modules"); |
73 | config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule"); | 125 | config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule"); |
74 | 126 | ||
75 | scene = SceneHelpers.SetupScene(); | 127 | modules.Add(new AttachmentsModule()); |
76 | m_attMod = new AttachmentsModule(); | 128 | modules.Add(new BasicInventoryAccessModule()); |
77 | SceneHelpers.SetupSceneModules(scene, config, m_attMod, new BasicInventoryAccessModule()); | ||
78 | } | 129 | } |
79 | 130 | ||
80 | [TestFixtureTearDown] | 131 | private void AddScriptingConfig(IConfigSource config, List<object> modules) |
81 | public void TearDown() | ||
82 | { | 132 | { |
83 | // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple | 133 | IConfig startupConfig = config.AddConfig("Startup"); |
84 | // threads. Possibly, later tests should be rewritten not to worry about such things. | 134 | startupConfig.Set("DefaultScriptEngine", "XEngine"); |
85 | Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod; | 135 | |
136 | IConfig xEngineConfig = config.AddConfig("XEngine"); | ||
137 | xEngineConfig.Set("Enabled", "true"); | ||
138 | xEngineConfig.Set("StartDelay", "0"); | ||
139 | |||
140 | // These tests will not run with AppDomainLoading = true, at least on mono. For unknown reasons, the call | ||
141 | // to AssemblyResolver.OnAssemblyResolve fails. | ||
142 | xEngineConfig.Set("AppDomainLoading", "false"); | ||
143 | |||
144 | modules.Add(new XEngine()); | ||
145 | |||
146 | // Necessary to stop serialization complaining | ||
147 | // FIXME: Stop this being necessary if at all possible | ||
148 | // modules.Add(new WorldCommModule()); | ||
86 | } | 149 | } |
87 | 150 | ||
88 | /// <summary> | 151 | /// <summary> |
89 | /// Add the standard presence for a test. | 152 | /// Creates an attachment item in the given user's inventory. Does not attach. |
90 | /// </summary> | 153 | /// </summary> |
91 | private void AddPresence() | 154 | /// <remarks> |
155 | /// A user with the given ID and an inventory must already exist. | ||
156 | /// </remarks> | ||
157 | /// <returns> | ||
158 | /// The attachment item. | ||
159 | /// </returns> | ||
160 | /// <param name='scene'></param> | ||
161 | /// <param name='userId'></param> | ||
162 | /// <param name='attName'></param> | ||
163 | /// <param name='rawItemId'></param> | ||
164 | /// <param name='rawAssetId'></param> | ||
165 | private InventoryItemBase CreateAttachmentItem( | ||
166 | Scene scene, UUID userId, string attName, int rawItemId, int rawAssetId) | ||
92 | { | 167 | { |
93 | UUID userId = TestHelpers.ParseTail(0x1); | 168 | return UserInventoryHelpers.CreateInventoryItem( |
94 | UserAccountHelpers.CreateUserWithInventory(scene, userId); | 169 | scene, |
95 | m_presence = SceneHelpers.AddScenePresence(scene, userId); | 170 | attName, |
171 | TestHelpers.ParseTail(rawItemId), | ||
172 | TestHelpers.ParseTail(rawAssetId), | ||
173 | userId, | ||
174 | InventoryType.Object); | ||
96 | } | 175 | } |
97 | 176 | ||
98 | [Test] | 177 | [Test] |
99 | public void TestAddAttachmentFromGround() | 178 | public void TestAddAttachmentFromGround() |
100 | { | 179 | { |
101 | TestHelpers.InMethod(); | 180 | TestHelpers.InMethod(); |
102 | // log4net.Config.XmlConfigurator.Configure(); | 181 | // TestHelpers.EnableLogging(); |
182 | |||
183 | Scene scene = CreateTestScene(); | ||
184 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); | ||
185 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1); | ||
103 | 186 | ||
104 | AddPresence(); | ||
105 | string attName = "att"; | 187 | string attName = "att"; |
106 | 188 | ||
107 | SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName).ParentGroup; | 189 | SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID); |
108 | 190 | ||
109 | m_attMod.AttachObject(m_presence, so, (uint)AttachmentPoint.Chest, false, false); | 191 | scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false); |
110 | 192 | ||
111 | // Check status on scene presence | 193 | // Check status on scene presence |
112 | Assert.That(m_presence.HasAttachments(), Is.True); | 194 | Assert.That(sp.HasAttachments(), Is.True); |
113 | List<SceneObjectGroup> attachments = m_presence.GetAttachments(); | 195 | List<SceneObjectGroup> attachments = sp.GetAttachments(); |
114 | Assert.That(attachments.Count, Is.EqualTo(1)); | 196 | Assert.That(attachments.Count, Is.EqualTo(1)); |
115 | SceneObjectGroup attSo = attachments[0]; | 197 | SceneObjectGroup attSo = attachments[0]; |
116 | Assert.That(attSo.Name, Is.EqualTo(attName)); | 198 | Assert.That(attSo.Name, Is.EqualTo(attName)); |
@@ -121,42 +203,107 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
121 | 203 | ||
122 | // Check item status | 204 | // Check item status |
123 | Assert.That( | 205 | Assert.That( |
124 | m_presence.Appearance.GetAttachpoint(attSo.FromItemID), | 206 | sp.Appearance.GetAttachpoint(attSo.FromItemID), |
125 | Is.EqualTo((int)AttachmentPoint.Chest)); | 207 | Is.EqualTo((int)AttachmentPoint.Chest)); |
208 | |||
209 | InventoryItemBase attachmentItem = scene.InventoryService.GetItem(new InventoryItemBase(attSo.FromItemID)); | ||
210 | Assert.That(attachmentItem, Is.Not.Null); | ||
211 | Assert.That(attachmentItem.Name, Is.EqualTo(attName)); | ||
212 | |||
213 | InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object); | ||
214 | Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID)); | ||
215 | |||
216 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); | ||
217 | |||
218 | // TestHelpers.DisableLogging(); | ||
126 | } | 219 | } |
127 | 220 | ||
221 | /// <summary> | ||
222 | /// Test that we do not attempt to attach an in-world object that someone else is sitting on. | ||
223 | /// </summary> | ||
128 | [Test] | 224 | [Test] |
129 | public void TestAddAttachmentFromInventory() | 225 | public void TestAddSatOnAttachmentFromGround() |
130 | { | 226 | { |
131 | TestHelpers.InMethod(); | 227 | TestHelpers.InMethod(); |
132 | // log4net.Config.XmlConfigurator.Configure(); | 228 | // TestHelpers.EnableLogging(); |
133 | 229 | ||
134 | AddPresence(); | 230 | Scene scene = CreateTestScene(); |
231 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); | ||
232 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1); | ||
135 | 233 | ||
136 | UUID attItemId = TestHelpers.ParseTail(0x2); | ||
137 | UUID attAssetId = TestHelpers.ParseTail(0x3); | ||
138 | string attName = "att"; | 234 | string attName = "att"; |
139 | 235 | ||
140 | UserInventoryHelpers.CreateInventoryItem( | 236 | SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID); |
141 | scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); | 237 | |
238 | UserAccount ua2 = UserAccountHelpers.CreateUserWithInventory(scene, 0x2); | ||
239 | ScenePresence sp2 = SceneHelpers.AddScenePresence(scene, ua2); | ||
240 | |||
241 | // Put avatar within 10m of the prim so that sit doesn't fail. | ||
242 | sp2.AbsolutePosition = new Vector3(0, 0, 0); | ||
243 | sp2.HandleAgentRequestSit(sp2.ControllingClient, sp2.UUID, so.UUID, Vector3.Zero); | ||
244 | |||
245 | scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false, false); | ||
246 | |||
247 | Assert.That(sp.HasAttachments(), Is.False); | ||
248 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); | ||
249 | } | ||
250 | |||
251 | [Test] | ||
252 | public void TestRezAttachmentFromInventory() | ||
253 | { | ||
254 | TestHelpers.InMethod(); | ||
255 | // log4net.Config.XmlConfigurator.Configure(); | ||
256 | |||
257 | Scene scene = CreateTestScene(); | ||
258 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); | ||
259 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID); | ||
142 | 260 | ||
143 | m_attMod.RezSingleAttachmentFromInventory( | 261 | InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20); |
144 | m_presence, attItemId, (uint)AttachmentPoint.Chest); | 262 | |
263 | scene.AttachmentsModule.RezSingleAttachmentFromInventory( | ||
264 | sp, attItem.ID, (uint)AttachmentPoint.Chest); | ||
145 | 265 | ||
146 | // Check scene presence status | 266 | // Check scene presence status |
147 | Assert.That(m_presence.HasAttachments(), Is.True); | 267 | Assert.That(sp.HasAttachments(), Is.True); |
148 | List<SceneObjectGroup> attachments = m_presence.GetAttachments(); | 268 | List<SceneObjectGroup> attachments = sp.GetAttachments(); |
149 | Assert.That(attachments.Count, Is.EqualTo(1)); | 269 | Assert.That(attachments.Count, Is.EqualTo(1)); |
150 | SceneObjectGroup attSo = attachments[0]; | 270 | SceneObjectGroup attSo = attachments[0]; |
151 | Assert.That(attSo.Name, Is.EqualTo(attName)); | 271 | Assert.That(attSo.Name, Is.EqualTo(attItem.Name)); |
152 | Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest)); | 272 | Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest)); |
153 | Assert.That(attSo.IsAttachment); | 273 | Assert.That(attSo.IsAttachment); |
154 | Assert.That(attSo.UsesPhysics, Is.False); | 274 | Assert.That(attSo.UsesPhysics, Is.False); |
155 | Assert.That(attSo.IsTemporary, Is.False); | 275 | Assert.That(attSo.IsTemporary, Is.False); |
156 | 276 | ||
157 | // Check appearance status | 277 | // Check appearance status |
158 | Assert.That(m_presence.Appearance.GetAttachments().Count, Is.EqualTo(1)); | 278 | Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1)); |
159 | Assert.That(m_presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo((int)AttachmentPoint.Chest)); | 279 | Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); |
280 | |||
281 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); | ||
282 | } | ||
283 | |||
284 | /// <summary> | ||
285 | /// Test specific conditions associated with rezzing a scripted attachment from inventory. | ||
286 | /// </summary> | ||
287 | [Test] | ||
288 | public void TestRezScriptedAttachmentFromInventory() | ||
289 | { | ||
290 | TestHelpers.InMethod(); | ||
291 | |||
292 | Scene scene = CreateTestScene(); | ||
293 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); | ||
294 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID); | ||
295 | |||
296 | SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, sp.UUID, "att-name", 0x10); | ||
297 | TaskInventoryHelpers.AddScript(scene, so.RootPart); | ||
298 | InventoryItemBase userItem = UserInventoryHelpers.AddInventoryItem(scene, so, 0x100, 0x1000); | ||
299 | |||
300 | scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest); | ||
301 | |||
302 | // TODO: Need to have a test that checks the script is actually started but this involves a lot more | ||
303 | // plumbing of the script engine and either pausing for events or more infrastructure to turn off various | ||
304 | // script engine delays/asychronicity that isn't helpful in an automated regression testing context. | ||
305 | SceneObjectGroup attSo = scene.GetSceneObjectGroup(so.Name); | ||
306 | Assert.That(attSo.ContainsScripts(), Is.True); | ||
160 | } | 307 | } |
161 | 308 | ||
162 | [Test] | 309 | [Test] |
@@ -165,29 +312,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
165 | TestHelpers.InMethod(); | 312 | TestHelpers.InMethod(); |
166 | // log4net.Config.XmlConfigurator.Configure(); | 313 | // log4net.Config.XmlConfigurator.Configure(); |
167 | 314 | ||
168 | AddPresence(); | 315 | Scene scene = CreateTestScene(); |
316 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); | ||
317 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID); | ||
169 | 318 | ||
170 | UUID attItemId = TestHelpers.ParseTail(0x2); | 319 | InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20); |
171 | UUID attAssetId = TestHelpers.ParseTail(0x3); | ||
172 | string attName = "att"; | ||
173 | 320 | ||
174 | UserInventoryHelpers.CreateInventoryItem( | 321 | ISceneEntity so |
175 | scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); | 322 | = scene.AttachmentsModule.RezSingleAttachmentFromInventory( |
176 | 323 | sp, attItem.ID, (uint)AttachmentPoint.Chest); | |
177 | ISceneEntity so = m_attMod.RezSingleAttachmentFromInventory( | 324 | scene.AttachmentsModule.DetachSingleAttachmentToGround(sp, so.LocalId); |
178 | m_presence, attItemId, (uint)AttachmentPoint.Chest); | ||
179 | m_attMod.DetachSingleAttachmentToGround(m_presence, so.LocalId); | ||
180 | 325 | ||
181 | // Check scene presence status | 326 | // Check scene presence status |
182 | Assert.That(m_presence.HasAttachments(), Is.False); | 327 | Assert.That(sp.HasAttachments(), Is.False); |
183 | List<SceneObjectGroup> attachments = m_presence.GetAttachments(); | 328 | List<SceneObjectGroup> attachments = sp.GetAttachments(); |
184 | Assert.That(attachments.Count, Is.EqualTo(0)); | 329 | Assert.That(attachments.Count, Is.EqualTo(0)); |
185 | 330 | ||
186 | // Check appearance status | 331 | // Check appearance status |
187 | Assert.That(m_presence.Appearance.GetAttachments().Count, Is.EqualTo(0)); | 332 | Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(0)); |
188 | 333 | ||
189 | // Check item status | 334 | // Check item status |
190 | Assert.That(scene.InventoryService.GetItem(new InventoryItemBase(attItemId)), Is.Null); | 335 | Assert.That(scene.InventoryService.GetItem(new InventoryItemBase(attItem.ID)), Is.Null); |
191 | 336 | ||
192 | // Check object in scene | 337 | // Check object in scene |
193 | Assert.That(scene.GetSceneObjectGroup("att"), Is.Not.Null); | 338 | Assert.That(scene.GetSceneObjectGroup("att"), Is.Not.Null); |
@@ -197,28 +342,66 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
197 | public void TestDetachAttachmentToInventory() | 342 | public void TestDetachAttachmentToInventory() |
198 | { | 343 | { |
199 | TestHelpers.InMethod(); | 344 | TestHelpers.InMethod(); |
200 | // log4net.Config.XmlConfigurator.Configure(); | ||
201 | 345 | ||
202 | AddPresence(); | 346 | Scene scene = CreateTestScene(); |
347 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); | ||
348 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID); | ||
203 | 349 | ||
204 | UUID attItemId = TestHelpers.ParseTail(0x2); | 350 | InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20); |
205 | UUID attAssetId = TestHelpers.ParseTail(0x3); | ||
206 | string attName = "att"; | ||
207 | |||
208 | UserInventoryHelpers.CreateInventoryItem( | ||
209 | scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); | ||
210 | 351 | ||
211 | m_attMod.RezSingleAttachmentFromInventory( | 352 | SceneObjectGroup so |
212 | m_presence, attItemId, (uint)AttachmentPoint.Chest); | 353 | = (SceneObjectGroup)scene.AttachmentsModule.RezSingleAttachmentFromInventory( |
213 | m_attMod.DetachSingleAttachmentToInv(m_presence, attItemId); | 354 | sp, attItem.ID, (uint)AttachmentPoint.Chest); |
355 | scene.AttachmentsModule.DetachSingleAttachmentToInv(sp, so); | ||
214 | 356 | ||
215 | // Check status on scene presence | 357 | // Check status on scene presence |
216 | Assert.That(m_presence.HasAttachments(), Is.False); | 358 | Assert.That(sp.HasAttachments(), Is.False); |
217 | List<SceneObjectGroup> attachments = m_presence.GetAttachments(); | 359 | List<SceneObjectGroup> attachments = sp.GetAttachments(); |
218 | Assert.That(attachments.Count, Is.EqualTo(0)); | 360 | Assert.That(attachments.Count, Is.EqualTo(0)); |
219 | 361 | ||
220 | // Check item status | 362 | // Check item status |
221 | Assert.That(m_presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo(0)); | 363 | Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo(0)); |
364 | |||
365 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(0)); | ||
366 | } | ||
367 | |||
368 | /// <summary> | ||
369 | /// Test specific conditions associated with detaching a scripted attachment from inventory. | ||
370 | /// </summary> | ||
371 | [Test] | ||
372 | public void TestDetachScriptedAttachmentToInventory() | ||
373 | { | ||
374 | TestHelpers.InMethod(); | ||
375 | // TestHelpers.EnableLogging(); | ||
376 | |||
377 | Scene scene = CreateScriptingEnabledTestScene(); | ||
378 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); | ||
379 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1); | ||
380 | |||
381 | SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, sp.UUID, "att-name", 0x10); | ||
382 | TaskInventoryHelpers.AddScript(scene, so.RootPart); | ||
383 | InventoryItemBase userItem = UserInventoryHelpers.AddInventoryItem(scene, so, 0x100, 0x1000); | ||
384 | |||
385 | // FIXME: Right now, we have to do a tricksy chat listen to make sure we know when the script is running. | ||
386 | // In the future, we need to be able to do this programatically more predicably. | ||
387 | scene.EventManager.OnChatFromWorld += OnChatFromWorld; | ||
388 | |||
389 | SceneObjectGroup soRezzed | ||
390 | = (SceneObjectGroup)scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest); | ||
391 | |||
392 | // Wait for chat to signal rezzed script has been started. | ||
393 | m_chatEvent.WaitOne(60000); | ||
394 | |||
395 | scene.AttachmentsModule.DetachSingleAttachmentToInv(sp, soRezzed); | ||
396 | |||
397 | InventoryItemBase userItemUpdated = scene.InventoryService.GetItem(userItem); | ||
398 | AssetBase asset = scene.AssetService.Get(userItemUpdated.AssetID.ToString()); | ||
399 | |||
400 | XmlDocument soXml = new XmlDocument(); | ||
401 | soXml.LoadXml(Encoding.UTF8.GetString(asset.Data)); | ||
402 | |||
403 | XmlNodeList scriptStateNodes = soXml.GetElementsByTagName("ScriptState"); | ||
404 | Assert.That(scriptStateNodes.Count, Is.EqualTo(1)); | ||
222 | } | 405 | } |
223 | 406 | ||
224 | /// <summary> | 407 | /// <summary> |
@@ -230,17 +413,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
230 | TestHelpers.InMethod(); | 413 | TestHelpers.InMethod(); |
231 | // log4net.Config.XmlConfigurator.Configure(); | 414 | // log4net.Config.XmlConfigurator.Configure(); |
232 | 415 | ||
233 | UUID userId = TestHelpers.ParseTail(0x1); | 416 | Scene scene = CreateTestScene(); |
234 | UUID attItemId = TestHelpers.ParseTail(0x2); | 417 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); |
235 | UUID attAssetId = TestHelpers.ParseTail(0x3); | 418 | InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20); |
236 | string attName = "att"; | ||
237 | |||
238 | UserAccountHelpers.CreateUserWithInventory(scene, userId); | ||
239 | InventoryItemBase attItem | ||
240 | = UserInventoryHelpers.CreateInventoryItem( | ||
241 | scene, attName, attItemId, attAssetId, userId, InventoryType.Object); | ||
242 | 419 | ||
243 | AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId); | 420 | AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID); |
244 | acd.Appearance = new AvatarAppearance(); | 421 | acd.Appearance = new AvatarAppearance(); |
245 | acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID); | 422 | acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID); |
246 | ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd); | 423 | ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd); |
@@ -259,17 +436,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
259 | TestHelpers.InMethod(); | 436 | TestHelpers.InMethod(); |
260 | // log4net.Config.XmlConfigurator.Configure(); | 437 | // log4net.Config.XmlConfigurator.Configure(); |
261 | 438 | ||
262 | UUID userId = TestHelpers.ParseTail(0x1); | 439 | Scene scene = CreateTestScene(); |
263 | UUID attItemId = TestHelpers.ParseTail(0x2); | 440 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); |
264 | UUID attAssetId = TestHelpers.ParseTail(0x3); | 441 | InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20); |
265 | string attName = "att"; | ||
266 | 442 | ||
267 | UserAccountHelpers.CreateUserWithInventory(scene, userId); | 443 | AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID); |
268 | InventoryItemBase attItem | ||
269 | = UserInventoryHelpers.CreateInventoryItem( | ||
270 | scene, attName, attItemId, attAssetId, userId, InventoryType.Object); | ||
271 | |||
272 | AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId); | ||
273 | acd.Appearance = new AvatarAppearance(); | 444 | acd.Appearance = new AvatarAppearance(); |
274 | acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID); | 445 | acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID); |
275 | ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd); | 446 | ScenePresence presence = SceneHelpers.AddScenePresence(scene, acd); |
@@ -279,7 +450,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
279 | 450 | ||
280 | Assert.That(attachments.Count, Is.EqualTo(1)); | 451 | Assert.That(attachments.Count, Is.EqualTo(1)); |
281 | SceneObjectGroup attSo = attachments[0]; | 452 | SceneObjectGroup attSo = attachments[0]; |
282 | Assert.That(attSo.Name, Is.EqualTo(attName)); | 453 | Assert.That(attSo.Name, Is.EqualTo(attItem.Name)); |
283 | Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest)); | 454 | Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest)); |
284 | Assert.That(attSo.IsAttachment); | 455 | Assert.That(attSo.IsAttachment); |
285 | Assert.That(attSo.UsesPhysics, Is.False); | 456 | Assert.That(attSo.UsesPhysics, Is.False); |
@@ -289,9 +460,125 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
289 | List<AvatarAttachment> retreivedAttachments = presence.Appearance.GetAttachments(); | 460 | List<AvatarAttachment> retreivedAttachments = presence.Appearance.GetAttachments(); |
290 | Assert.That(retreivedAttachments.Count, Is.EqualTo(1)); | 461 | Assert.That(retreivedAttachments.Count, Is.EqualTo(1)); |
291 | Assert.That(retreivedAttachments[0].AttachPoint, Is.EqualTo((int)AttachmentPoint.Chest)); | 462 | Assert.That(retreivedAttachments[0].AttachPoint, Is.EqualTo((int)AttachmentPoint.Chest)); |
292 | Assert.That(retreivedAttachments[0].ItemID, Is.EqualTo(attItemId)); | 463 | Assert.That(retreivedAttachments[0].ItemID, Is.EqualTo(attItem.ID)); |
293 | Assert.That(retreivedAttachments[0].AssetID, Is.EqualTo(attAssetId)); | 464 | Assert.That(retreivedAttachments[0].AssetID, Is.EqualTo(attItem.AssetID)); |
294 | Assert.That(presence.Appearance.GetAttachpoint(attItemId), Is.EqualTo((int)AttachmentPoint.Chest)); | 465 | Assert.That(presence.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); |
466 | |||
467 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); | ||
468 | } | ||
469 | |||
470 | [Test] | ||
471 | public void TestUpdateAttachmentPosition() | ||
472 | { | ||
473 | TestHelpers.InMethod(); | ||
474 | |||
475 | Scene scene = CreateTestScene(); | ||
476 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); | ||
477 | InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20); | ||
478 | |||
479 | AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID); | ||
480 | acd.Appearance = new AvatarAppearance(); | ||
481 | acd.Appearance.SetAttachment((int)AttachmentPoint.Chest, attItem.ID, attItem.AssetID); | ||
482 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, acd); | ||
483 | |||
484 | SceneObjectGroup attSo = sp.GetAttachments()[0]; | ||
485 | |||
486 | Vector3 newPosition = new Vector3(1, 2, 4); | ||
487 | |||
488 | scene.SceneGraph.UpdatePrimGroupPosition(attSo.LocalId, newPosition, sp.ControllingClient); | ||
489 | |||
490 | Assert.That(attSo.AbsolutePosition, Is.EqualTo(sp.AbsolutePosition)); | ||
491 | Assert.That(attSo.RootPart.AttachedPos, Is.EqualTo(newPosition)); | ||
492 | } | ||
493 | |||
494 | [Test] | ||
495 | public void TestSameSimulatorNeighbouringRegionsTeleport() | ||
496 | { | ||
497 | TestHelpers.InMethod(); | ||
498 | // TestHelpers.EnableLogging(); | ||
499 | |||
500 | AttachmentsModule attModA = new AttachmentsModule(); | ||
501 | AttachmentsModule attModB = new AttachmentsModule(); | ||
502 | EntityTransferModule etmA = new EntityTransferModule(); | ||
503 | EntityTransferModule etmB = new EntityTransferModule(); | ||
504 | LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule(); | ||
505 | |||
506 | IConfigSource config = new IniConfigSource(); | ||
507 | IConfig modulesConfig = config.AddConfig("Modules"); | ||
508 | modulesConfig.Set("EntityTransferModule", etmA.Name); | ||
509 | modulesConfig.Set("SimulationServices", lscm.Name); | ||
510 | IConfig entityTransferConfig = config.AddConfig("EntityTransfer"); | ||
511 | |||
512 | // In order to run a single threaded regression test we do not want the entity transfer module waiting | ||
513 | // for a callback from the destination scene before removing its avatar data. | ||
514 | entityTransferConfig.Set("wait_for_callback", false); | ||
515 | |||
516 | modulesConfig.Set("InventoryAccessModule", "BasicInventoryAccessModule"); | ||
517 | |||
518 | SceneHelpers sh = new SceneHelpers(); | ||
519 | TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000); | ||
520 | TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1001, 1000); | ||
521 | |||
522 | SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm); | ||
523 | SceneHelpers.SetupSceneModules( | ||
524 | sceneA, config, new CapabilitiesModule(), etmA, attModA, new BasicInventoryAccessModule()); | ||
525 | SceneHelpers.SetupSceneModules( | ||
526 | sceneB, config, new CapabilitiesModule(), etmB, attModB, new BasicInventoryAccessModule()); | ||
527 | |||
528 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(sceneA, 0x1); | ||
529 | ScenePresence beforeTeleportSp = SceneHelpers.AddScenePresence(sceneA, ua1.PrincipalID, sh.SceneManager); | ||
530 | beforeTeleportSp.AbsolutePosition = new Vector3(30, 31, 32); | ||
531 | |||
532 | InventoryItemBase attItem = CreateAttachmentItem(sceneA, ua1.PrincipalID, "att", 0x10, 0x20); | ||
533 | |||
534 | sceneA.AttachmentsModule.RezSingleAttachmentFromInventory( | ||
535 | beforeTeleportSp, attItem.ID, (uint)AttachmentPoint.Chest); | ||
536 | |||
537 | Vector3 teleportPosition = new Vector3(10, 11, 12); | ||
538 | Vector3 teleportLookAt = new Vector3(20, 21, 22); | ||
539 | |||
540 | sceneA.RequestTeleportLocation( | ||
541 | beforeTeleportSp.ControllingClient, | ||
542 | sceneB.RegionInfo.RegionHandle, | ||
543 | teleportPosition, | ||
544 | teleportLookAt, | ||
545 | (uint)TeleportFlags.ViaLocation); | ||
546 | |||
547 | ((TestClient)beforeTeleportSp.ControllingClient).CompleteTeleportClientSide(); | ||
548 | |||
549 | // Check attachments have made it into sceneB | ||
550 | ScenePresence afterTeleportSceneBSp = sceneB.GetScenePresence(ua1.PrincipalID); | ||
551 | |||
552 | // This is appearance data, as opposed to actually rezzed attachments | ||
553 | List<AvatarAttachment> sceneBAttachments = afterTeleportSceneBSp.Appearance.GetAttachments(); | ||
554 | Assert.That(sceneBAttachments.Count, Is.EqualTo(1)); | ||
555 | Assert.That(sceneBAttachments[0].AttachPoint, Is.EqualTo((int)AttachmentPoint.Chest)); | ||
556 | Assert.That(sceneBAttachments[0].ItemID, Is.EqualTo(attItem.ID)); | ||
557 | Assert.That(sceneBAttachments[0].AssetID, Is.EqualTo(attItem.AssetID)); | ||
558 | Assert.That(afterTeleportSceneBSp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); | ||
559 | |||
560 | // This is the actual attachment | ||
561 | List<SceneObjectGroup> actualSceneBAttachments = afterTeleportSceneBSp.GetAttachments(); | ||
562 | Assert.That(actualSceneBAttachments.Count, Is.EqualTo(1)); | ||
563 | SceneObjectGroup actualSceneBAtt = actualSceneBAttachments[0]; | ||
564 | Assert.That(actualSceneBAtt.Name, Is.EqualTo(attItem.Name)); | ||
565 | Assert.That(actualSceneBAtt.AttachmentPoint, Is.EqualTo((uint)AttachmentPoint.Chest)); | ||
566 | |||
567 | Assert.That(sceneB.GetSceneObjectGroups().Count, Is.EqualTo(1)); | ||
568 | |||
569 | // Check attachments have been removed from sceneA | ||
570 | ScenePresence afterTeleportSceneASp = sceneA.GetScenePresence(ua1.PrincipalID); | ||
571 | |||
572 | // Since this is appearance data, it is still present on the child avatar! | ||
573 | List<AvatarAttachment> sceneAAttachments = afterTeleportSceneASp.Appearance.GetAttachments(); | ||
574 | Assert.That(sceneAAttachments.Count, Is.EqualTo(1)); | ||
575 | Assert.That(afterTeleportSceneASp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); | ||
576 | |||
577 | // This is the actual attachment, which should no longer exist | ||
578 | List<SceneObjectGroup> actualSceneAAttachments = afterTeleportSceneASp.GetAttachments(); | ||
579 | Assert.That(actualSceneAAttachments.Count, Is.EqualTo(0)); | ||
580 | |||
581 | Assert.That(sceneA.GetSceneObjectGroups().Count, Is.EqualTo(0)); | ||
295 | } | 582 | } |
296 | 583 | ||
297 | // I'm commenting this test because scene setup NEEDS InventoryService to | 584 | // I'm commenting this test because scene setup NEEDS InventoryService to |
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 2bebd30..89cc4f6 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | |||
@@ -128,7 +128,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
128 | /// <param name="visualParam"></param> | 128 | /// <param name="visualParam"></param> |
129 | public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams) | 129 | public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams) |
130 | { | 130 | { |
131 | // m_log.InfoFormat("[AVFACTORY]: start SetAppearance for {0}", client.AgentId); | 131 | // m_log.DebugFormat( |
132 | // "[AVFACTORY]: start SetAppearance for {0}, te {1}, visualParams {2}", | ||
133 | // sp.Name, textureEntry, visualParams); | ||
132 | 134 | ||
133 | // TODO: This is probably not necessary any longer, just assume the | 135 | // TODO: This is probably not necessary any longer, just assume the |
134 | // textureEntry set implies that the appearance transaction is complete | 136 | // textureEntry set implies that the appearance transaction is complete |
@@ -158,7 +160,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
158 | // Process the baked texture array | 160 | // Process the baked texture array |
159 | if (textureEntry != null) | 161 | if (textureEntry != null) |
160 | { | 162 | { |
161 | m_log.InfoFormat("[AVFACTORY]: Received texture update for {0} {1}", sp.Name, sp.UUID); | 163 | // m_log.DebugFormat("[AVFACTORY]: Received texture update for {0} {1}", sp.Name, sp.UUID); |
162 | 164 | ||
163 | // WriteBakedTexturesReport(sp, m_log.DebugFormat); | 165 | // WriteBakedTexturesReport(sp, m_log.DebugFormat); |
164 | 166 | ||
@@ -208,7 +210,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
208 | ScenePresence sp = m_scene.GetScenePresence(agentId); | 210 | ScenePresence sp = m_scene.GetScenePresence(agentId); |
209 | if (sp == null) | 211 | if (sp == null) |
210 | { | 212 | { |
211 | m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentId); | 213 | // This is expected if the user has gone away. |
214 | // m_log.DebugFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentId); | ||
212 | return false; | 215 | return false; |
213 | } | 216 | } |
214 | 217 | ||
@@ -248,10 +251,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
248 | 251 | ||
249 | if (bakedTextureFace == null) | 252 | if (bakedTextureFace == null) |
250 | { | 253 | { |
251 | m_log.WarnFormat( | 254 | // This can happen legitimately, since some baked textures might not exist |
252 | "[AV FACTORY]: No texture ID set for {0} for {1} in {2} not found when trying to save permanently", | 255 | //m_log.WarnFormat( |
253 | bakeType, sp.Name, m_scene.RegionInfo.RegionName); | 256 | // "[AV FACTORY]: No texture ID set for {0} for {1} in {2} not found when trying to save permanently", |
254 | 257 | // bakeType, sp.Name, m_scene.RegionInfo.RegionName); | |
255 | continue; | 258 | continue; |
256 | } | 259 | } |
257 | 260 | ||
@@ -337,7 +340,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
337 | return false; | 340 | return false; |
338 | } | 341 | } |
339 | 342 | ||
340 | m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0} {1}", sp.Name, sp.UUID); | 343 | // m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0} {1}", sp.Name, sp.UUID); |
341 | 344 | ||
342 | // If we only found default textures, then the appearance is not cached | 345 | // If we only found default textures, then the appearance is not cached |
343 | return (defonly ? false : true); | 346 | return (defonly ? false : true); |
@@ -370,11 +373,21 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
370 | if (missingTexturesOnly) | 373 | if (missingTexturesOnly) |
371 | { | 374 | { |
372 | if (m_scene.AssetService.Get(face.TextureID.ToString()) != null) | 375 | if (m_scene.AssetService.Get(face.TextureID.ToString()) != null) |
376 | { | ||
373 | continue; | 377 | continue; |
378 | } | ||
374 | else | 379 | else |
380 | { | ||
381 | // On inter-simulator teleports, this occurs if baked textures are not being stored by the | ||
382 | // grid asset service (which means that they are not available to the new region and so have | ||
383 | // to be re-requested from the client). | ||
384 | // | ||
385 | // The only available core OpenSimulator behaviour right now | ||
386 | // is not to store these textures, temporarily or otherwise. | ||
375 | m_log.DebugFormat( | 387 | m_log.DebugFormat( |
376 | "[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.", | 388 | "[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.", |
377 | face.TextureID, idx, sp.Name); | 389 | face.TextureID, idx, sp.Name); |
390 | } | ||
378 | } | 391 | } |
379 | else | 392 | else |
380 | { | 393 | { |
@@ -417,7 +430,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
417 | // acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]); | 430 | // acd.AgentID, i, acd.Appearance.Texture.FaceTextures[i]); |
418 | 431 | ||
419 | int ftIndex = (int)AppearanceManager.BakeTypeToAgentTextureIndex(bakeType); | 432 | int ftIndex = (int)AppearanceManager.BakeTypeToAgentTextureIndex(bakeType); |
420 | bakedTextures[bakeType] = faceTextures[ftIndex]; | 433 | Primitive.TextureEntryFace texture = faceTextures[ftIndex]; // this will be null if there's no such baked texture |
434 | bakedTextures[bakeType] = texture; | ||
421 | } | 435 | } |
422 | 436 | ||
423 | return bakedTextures; | 437 | return bakedTextures; |
@@ -482,7 +496,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
482 | ScenePresence sp = m_scene.GetScenePresence(agentid); | 496 | ScenePresence sp = m_scene.GetScenePresence(agentid); |
483 | if (sp == null) | 497 | if (sp == null) |
484 | { | 498 | { |
485 | m_log.WarnFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid); | 499 | // This is expected if the user has gone away. |
500 | // m_log.DebugFormat("[AVFACTORY]: Agent {0} no longer in the scene", agentid); | ||
486 | return; | 501 | return; |
487 | } | 502 | } |
488 | 503 | ||
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs index 11a0a86..848b3bf 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/Tests/AvatarFactoryModuleTests.cs | |||
@@ -53,7 +53,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
53 | UUID userId = TestHelpers.ParseTail(0x1); | 53 | UUID userId = TestHelpers.ParseTail(0x1); |
54 | 54 | ||
55 | AvatarFactoryModule afm = new AvatarFactoryModule(); | 55 | AvatarFactoryModule afm = new AvatarFactoryModule(); |
56 | TestScene scene = SceneHelpers.SetupScene(); | 56 | TestScene scene = new SceneHelpers().SetupScene(); |
57 | SceneHelpers.SetupSceneModules(scene, afm); | 57 | SceneHelpers.SetupSceneModules(scene, afm); |
58 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, userId); | 58 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, userId); |
59 | 59 | ||
@@ -81,7 +81,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
81 | CoreAssetCache assetCache = new CoreAssetCache(); | 81 | CoreAssetCache assetCache = new CoreAssetCache(); |
82 | 82 | ||
83 | AvatarFactoryModule afm = new AvatarFactoryModule(); | 83 | AvatarFactoryModule afm = new AvatarFactoryModule(); |
84 | TestScene scene = SceneHelpers.SetupScene(assetCache); | 84 | TestScene scene = new SceneHelpers(assetCache).SetupScene(); |
85 | SceneHelpers.SetupSceneModules(scene, afm); | 85 | SceneHelpers.SetupSceneModules(scene, afm); |
86 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, userId); | 86 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, userId); |
87 | 87 | ||
diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs index 6215526..dbbb0ae 100644 --- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs | |||
@@ -266,7 +266,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat | |||
266 | receiverIDs.Add(presence.UUID); | 266 | receiverIDs.Add(presence.UUID); |
267 | } | 267 | } |
268 | } | 268 | } |
269 | |||
270 | } | 269 | } |
271 | ); | 270 | ); |
272 | } | 271 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs b/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs index 0babeb5..3a91465 100644 --- a/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs | |||
@@ -96,6 +96,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule | |||
96 | ScenePresence killingAvatar = null; | 96 | ScenePresence killingAvatar = null; |
97 | // string killingAvatarMessage; | 97 | // string killingAvatarMessage; |
98 | 98 | ||
99 | // check to see if it is an NPC and just remove it | ||
100 | INPCModule NPCmodule = deadAvatar.Scene.RequestModuleInterface<INPCModule>(); | ||
101 | if (NPCmodule != null && NPCmodule.DeleteNPC(deadAvatar.UUID, deadAvatar.Scene)) | ||
102 | { | ||
103 | return; | ||
104 | } | ||
105 | |||
99 | if (killerObjectLocalID == 0) | 106 | if (killerObjectLocalID == 0) |
100 | deadAvatarMessage = "You committed suicide!"; | 107 | deadAvatarMessage = "You committed suicide!"; |
101 | else | 108 | else |
@@ -145,7 +152,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule | |||
145 | catch (InvalidOperationException) | 152 | catch (InvalidOperationException) |
146 | { } | 153 | { } |
147 | 154 | ||
148 | deadAvatar.Health = 100; | 155 | deadAvatar.setHealthWithUpdate(100.0f); |
149 | deadAvatar.Scene.TeleportClientHome(deadAvatar.UUID, deadAvatar.ControllingClient); | 156 | deadAvatar.Scene.TeleportClientHome(deadAvatar.UUID, deadAvatar.ControllingClient); |
150 | } | 157 | } |
151 | 158 | ||
@@ -154,14 +161,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule | |||
154 | try | 161 | try |
155 | { | 162 | { |
156 | ILandObject obj = avatar.Scene.LandChannel.GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); | 163 | ILandObject obj = avatar.Scene.LandChannel.GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); |
157 | 164 | if ((obj.LandData.Flags & (uint)ParcelFlags.AllowDamage) != 0 | |
158 | if ((obj.LandData.Flags & (uint)ParcelFlags.AllowDamage) != 0) | 165 | || avatar.Scene.RegionInfo.RegionSettings.AllowDamage) |
159 | { | 166 | { |
160 | avatar.Invulnerable = false; | 167 | avatar.Invulnerable = false; |
161 | } | 168 | } |
162 | else | 169 | else |
163 | { | 170 | { |
164 | avatar.Invulnerable = true; | 171 | avatar.Invulnerable = true; |
172 | if (avatar.Health < 100.0f) | ||
173 | { | ||
174 | avatar.setHealthWithUpdate(100.0f); | ||
175 | } | ||
165 | } | 176 | } |
166 | } | 177 | } |
167 | catch (Exception) | 178 | catch (Exception) |
diff --git a/OpenSim/Region/CoreModules/Avatar/Commands/UserCommandsModule.cs b/OpenSim/Region/CoreModules/Avatar/Commands/UserCommandsModule.cs new file mode 100644 index 0000000..4bcd2ac --- /dev/null +++ b/OpenSim/Region/CoreModules/Avatar/Commands/UserCommandsModule.cs | |||
@@ -0,0 +1,189 @@ | |||
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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Reflection; | ||
31 | using System.Text; | ||
32 | using System.Text.RegularExpressions; | ||
33 | using log4net; | ||
34 | using Mono.Addins; | ||
35 | using NDesk.Options; | ||
36 | using Nini.Config; | ||
37 | using OpenMetaverse; | ||
38 | using OpenSim.Framework; | ||
39 | using OpenSim.Framework.Console; | ||
40 | using OpenSim.Framework.Statistics; | ||
41 | using OpenSim.Region.Framework.Interfaces; | ||
42 | using OpenSim.Region.Framework.Scenes; | ||
43 | |||
44 | namespace OpenSim.Region.CoreModules.Avatars.Commands | ||
45 | { | ||
46 | /// <summary> | ||
47 | /// A module that holds commands for manipulating objects in the scene. | ||
48 | /// </summary> | ||
49 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "UserCommandsModule")] | ||
50 | public class UserCommandsModule : ISharedRegionModule | ||
51 | { | ||
52 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
53 | |||
54 | public const string TeleportUserCommandSyntax = "teleport user <first-name> <last-name> <destination>"; | ||
55 | |||
56 | public static Regex InterRegionDestinationRegex | ||
57 | = new Regex(@"^(?<regionName>.+)/(?<x>\d+)/(?<y>\d+)/(?<z>\d+)$", RegexOptions.Compiled); | ||
58 | |||
59 | public static Regex WithinRegionDestinationRegex | ||
60 | = new Regex(@"^(?<x>\d+)/(?<y>\d+)/(?<z>\d+)$", RegexOptions.Compiled); | ||
61 | |||
62 | private Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>(); | ||
63 | |||
64 | public string Name { get { return "User Commands Module"; } } | ||
65 | |||
66 | public Type ReplaceableInterface { get { return null; } } | ||
67 | |||
68 | public void Initialise(IConfigSource source) | ||
69 | { | ||
70 | // m_log.DebugFormat("[USER COMMANDS MODULE]: INITIALIZED MODULE"); | ||
71 | } | ||
72 | |||
73 | public void PostInitialise() | ||
74 | { | ||
75 | // m_log.DebugFormat("[USER COMMANDS MODULE]: POST INITIALIZED MODULE"); | ||
76 | } | ||
77 | |||
78 | public void Close() | ||
79 | { | ||
80 | // m_log.DebugFormat("[USER COMMANDS MODULE]: CLOSED MODULE"); | ||
81 | } | ||
82 | |||
83 | public void AddRegion(Scene scene) | ||
84 | { | ||
85 | // m_log.DebugFormat("[USER COMMANDS MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName); | ||
86 | |||
87 | lock (m_scenes) | ||
88 | m_scenes[scene.RegionInfo.RegionID] = scene; | ||
89 | |||
90 | scene.AddCommand( | ||
91 | "Users", | ||
92 | this, | ||
93 | "teleport user", | ||
94 | TeleportUserCommandSyntax, | ||
95 | "Teleport a user in this simulator to the given destination", | ||
96 | "<destination> is in format [<region-name>]/<x>/<y>/<z>, e.g. regionone/20/30/40 or just 20/30/40 to teleport within same region." | ||
97 | + "\nIf the region contains a space then the whole destination must be in quotes, e.g. \"region one/20/30/40\"", | ||
98 | HandleTeleportUser); | ||
99 | } | ||
100 | |||
101 | public void RemoveRegion(Scene scene) | ||
102 | { | ||
103 | // m_log.DebugFormat("[USER COMMANDS MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName); | ||
104 | |||
105 | lock (m_scenes) | ||
106 | m_scenes.Remove(scene.RegionInfo.RegionID); | ||
107 | } | ||
108 | |||
109 | public void RegionLoaded(Scene scene) | ||
110 | { | ||
111 | // m_log.DebugFormat("[USER COMMANDS MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); | ||
112 | } | ||
113 | |||
114 | private ScenePresence GetUser(string firstName, string lastName) | ||
115 | { | ||
116 | ScenePresence userFound = null; | ||
117 | |||
118 | lock (m_scenes) | ||
119 | { | ||
120 | foreach (Scene scene in m_scenes.Values) | ||
121 | { | ||
122 | ScenePresence user = scene.GetScenePresence(firstName, lastName); | ||
123 | if (user != null && !user.IsChildAgent) | ||
124 | { | ||
125 | userFound = user; | ||
126 | break; | ||
127 | } | ||
128 | } | ||
129 | } | ||
130 | |||
131 | return userFound; | ||
132 | } | ||
133 | |||
134 | private void HandleTeleportUser(string module, string[] cmd) | ||
135 | { | ||
136 | if (cmd.Length < 5) | ||
137 | { | ||
138 | MainConsole.Instance.OutputFormat("Usage: " + TeleportUserCommandSyntax); | ||
139 | return; | ||
140 | } | ||
141 | |||
142 | string firstName = cmd[2]; | ||
143 | string lastName = cmd[3]; | ||
144 | string rawDestination = cmd[4]; | ||
145 | |||
146 | ScenePresence user = GetUser(firstName, lastName); | ||
147 | |||
148 | if (user == null) | ||
149 | { | ||
150 | MainConsole.Instance.OutputFormat("No user found with name {0} {1}", firstName, lastName); | ||
151 | return; | ||
152 | } | ||
153 | |||
154 | // MainConsole.Instance.OutputFormat("rawDestination [{0}]", rawDestination); | ||
155 | |||
156 | Match m = WithinRegionDestinationRegex.Match(rawDestination); | ||
157 | |||
158 | if (!m.Success) | ||
159 | { | ||
160 | m = InterRegionDestinationRegex.Match(rawDestination); | ||
161 | |||
162 | if (!m.Success) | ||
163 | { | ||
164 | MainConsole.Instance.OutputFormat("Invalid destination {0}", rawDestination); | ||
165 | return; | ||
166 | } | ||
167 | } | ||
168 | |||
169 | string regionName | ||
170 | = m.Groups["regionName"].Success ? m.Groups["regionName"].Value : user.Scene.RegionInfo.RegionName; | ||
171 | |||
172 | MainConsole.Instance.OutputFormat( | ||
173 | "Teleporting {0} to {1},{2},{3} in {4}", | ||
174 | user.Name, | ||
175 | m.Groups["x"], m.Groups["y"], m.Groups["z"], | ||
176 | regionName); | ||
177 | |||
178 | user.Scene.RequestTeleportLocation( | ||
179 | user.ControllingClient, | ||
180 | regionName, | ||
181 | new Vector3( | ||
182 | float.Parse(m.Groups["x"].Value), | ||
183 | float.Parse(m.Groups["y"].Value), | ||
184 | float.Parse(m.Groups["z"].Value)), | ||
185 | user.Lookat, | ||
186 | (uint)TeleportFlags.ViaLocation); | ||
187 | } | ||
188 | } | ||
189 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index f64c161..24ec435 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs | |||
@@ -162,7 +162,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
162 | } | 162 | } |
163 | } | 163 | } |
164 | 164 | ||
165 | protected void InitModule(IConfigSource config) | 165 | protected virtual void InitModule(IConfigSource config) |
166 | { | 166 | { |
167 | IConfig friendsConfig = config.Configs["Friends"]; | 167 | IConfig friendsConfig = config.Configs["Friends"]; |
168 | if (friendsConfig != null) | 168 | if (friendsConfig != null) |
@@ -449,29 +449,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
449 | /// </summary> | 449 | /// </summary> |
450 | public IClientAPI LocateClientObject(UUID agentID) | 450 | public IClientAPI LocateClientObject(UUID agentID) |
451 | { | 451 | { |
452 | Scene scene = GetClientScene(agentID); | ||
453 | if (scene != null) | ||
454 | { | ||
455 | ScenePresence presence = scene.GetScenePresence(agentID); | ||
456 | if (presence != null) | ||
457 | return presence.ControllingClient; | ||
458 | } | ||
459 | |||
460 | return null; | ||
461 | } | ||
462 | |||
463 | /// <summary> | ||
464 | /// Find the scene for an agent | ||
465 | /// </summary> | ||
466 | private Scene GetClientScene(UUID agentId) | ||
467 | { | ||
468 | lock (m_Scenes) | 452 | lock (m_Scenes) |
469 | { | 453 | { |
470 | foreach (Scene scene in m_Scenes) | 454 | foreach (Scene scene in m_Scenes) |
471 | { | 455 | { |
472 | ScenePresence presence = scene.GetScenePresence(agentId); | 456 | ScenePresence presence = scene.GetScenePresence(agentID); |
473 | if (presence != null && !presence.IsChildAgent) | 457 | if (presence != null && !presence.IsChildAgent) |
474 | return scene; | 458 | return presence.ControllingClient; |
475 | } | 459 | } |
476 | } | 460 | } |
477 | 461 | ||
@@ -498,7 +482,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
498 | Util.FireAndForget( | 482 | Util.FireAndForget( |
499 | delegate | 483 | delegate |
500 | { | 484 | { |
501 | m_log.DebugFormat("[FRIENDS MODULE]: Notifying {0} friends", friendList.Count); | 485 | m_log.DebugFormat( |
486 | "[FRIENDS MODULE]: Notifying {0} friends of {1} of online status {2}", | ||
487 | friendList.Count, agentID, online); | ||
488 | |||
502 | // Notify about this user status | 489 | // Notify about this user status |
503 | StatusNotify(friendList, agentID, online); | 490 | StatusNotify(friendList, agentID, online); |
504 | } | 491 | } |
@@ -515,7 +502,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
515 | { | 502 | { |
516 | // Try local | 503 | // Try local |
517 | if (LocalStatusNotification(userID, friendID, online)) | 504 | if (LocalStatusNotification(userID, friendID, online)) |
518 | return; | 505 | continue; |
519 | 506 | ||
520 | // The friend is not here [as root]. Let's forward. | 507 | // The friend is not here [as root]. Let's forward. |
521 | PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() }); | 508 | PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() }); |
@@ -523,11 +510,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
523 | { | 510 | { |
524 | PresenceInfo friendSession = null; | 511 | PresenceInfo friendSession = null; |
525 | foreach (PresenceInfo pinfo in friendSessions) | 512 | foreach (PresenceInfo pinfo in friendSessions) |
513 | { | ||
526 | if (pinfo.RegionID != UUID.Zero) // let's guard against sessions-gone-bad | 514 | if (pinfo.RegionID != UUID.Zero) // let's guard against sessions-gone-bad |
527 | { | 515 | { |
528 | friendSession = pinfo; | 516 | friendSession = pinfo; |
529 | break; | 517 | break; |
530 | } | 518 | } |
519 | } | ||
531 | 520 | ||
532 | if (friendSession != null) | 521 | if (friendSession != null) |
533 | { | 522 | { |
@@ -546,7 +535,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
546 | } | 535 | } |
547 | } | 536 | } |
548 | 537 | ||
549 | private void OnInstantMessage(IClientAPI client, GridInstantMessage im) | 538 | protected virtual void OnInstantMessage(IClientAPI client, GridInstantMessage im) |
550 | { | 539 | { |
551 | if ((InstantMessageDialog)im.dialog == InstantMessageDialog.FriendshipOffered) | 540 | if ((InstantMessageDialog)im.dialog == InstantMessageDialog.FriendshipOffered) |
552 | { | 541 | { |
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs index 9a6d277..06f27e2 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs | |||
@@ -50,6 +50,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
50 | { | 50 | { |
51 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 51 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
52 | 52 | ||
53 | private int m_levelHGFriends = 0; | ||
54 | |||
53 | IUserManagement m_uMan; | 55 | IUserManagement m_uMan; |
54 | public IUserManagement UserManagementModule | 56 | public IUserManagement UserManagementModule |
55 | { | 57 | { |
@@ -87,6 +89,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
87 | m_StatusNotifier = new HGStatusNotifier(this); | 89 | m_StatusNotifier = new HGStatusNotifier(this); |
88 | } | 90 | } |
89 | 91 | ||
92 | protected override void InitModule(IConfigSource config) | ||
93 | { | ||
94 | base.InitModule(config); | ||
95 | |||
96 | // Additionally to the base method | ||
97 | IConfig friendsConfig = config.Configs["HGFriendsModule"]; | ||
98 | if (friendsConfig != null) | ||
99 | { | ||
100 | m_levelHGFriends = friendsConfig.GetInt("LevelHGFriends", 0); | ||
101 | |||
102 | // TODO: read in all config variables pertaining to | ||
103 | // HG friendship permissions | ||
104 | } | ||
105 | } | ||
106 | |||
90 | #endregion | 107 | #endregion |
91 | 108 | ||
92 | #region IFriendsSimConnector | 109 | #region IFriendsSimConnector |
@@ -105,6 +122,35 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
105 | 122 | ||
106 | #endregion | 123 | #endregion |
107 | 124 | ||
125 | protected override void OnInstantMessage(IClientAPI client, GridInstantMessage im) | ||
126 | { | ||
127 | if ((InstantMessageDialog)im.dialog == InstantMessageDialog.FriendshipOffered) | ||
128 | { | ||
129 | // we got a friendship offer | ||
130 | UUID principalID = new UUID(im.fromAgentID); | ||
131 | UUID friendID = new UUID(im.toAgentID); | ||
132 | |||
133 | // Check if friendID is foreigner and if principalID has the permission | ||
134 | // to request friendships with foreigners. If not, return immediately. | ||
135 | if (!UserManagementModule.IsLocalGridUser(friendID)) | ||
136 | { | ||
137 | ScenePresence avatar = null; | ||
138 | ((Scene)client.Scene).TryGetScenePresence(principalID, out avatar); | ||
139 | |||
140 | if (avatar == null) | ||
141 | return; | ||
142 | |||
143 | if (avatar.UserLevel < m_levelHGFriends) | ||
144 | { | ||
145 | client.SendAgentAlertMessage("Unable to send friendship invitation to foreigner. Insufficient permissions.", false); | ||
146 | return; | ||
147 | } | ||
148 | } | ||
149 | } | ||
150 | |||
151 | base.OnInstantMessage(client, im); | ||
152 | } | ||
153 | |||
108 | protected override void OnApproveFriendRequest(IClientAPI client, UUID friendID, List<UUID> callingCardFolders) | 154 | protected override void OnApproveFriendRequest(IClientAPI client, UUID friendID, List<UUID> callingCardFolders) |
109 | { | 155 | { |
110 | // Update the local cache. Yes, we need to do it right here | 156 | // Update the local cache. Yes, we need to do it right here |
@@ -369,12 +415,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
369 | 415 | ||
370 | protected override void StoreBackwards(UUID friendID, UUID agentID) | 416 | protected override void StoreBackwards(UUID friendID, UUID agentID) |
371 | { | 417 | { |
372 | Boolean agentIsLocal = true; | 418 | bool agentIsLocal = true; |
373 | Boolean friendIsLocal = true; | 419 | // bool friendIsLocal = true; |
420 | |||
374 | if (UserManagementModule != null) | 421 | if (UserManagementModule != null) |
375 | { | 422 | { |
376 | agentIsLocal = UserManagementModule.IsLocalGridUser(agentID); | 423 | agentIsLocal = UserManagementModule.IsLocalGridUser(agentID); |
377 | friendIsLocal = UserManagementModule.IsLocalGridUser(friendID); | 424 | // friendIsLocal = UserManagementModule.IsLocalGridUser(friendID); |
378 | } | 425 | } |
379 | 426 | ||
380 | // Is the requester a local user? | 427 | // Is the requester a local user? |
@@ -461,7 +508,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
461 | { | 508 | { |
462 | friendUUI = finfo.Friend; | 509 | friendUUI = finfo.Friend; |
463 | theFriendUUID = friendUUI; | 510 | theFriendUUID = friendUUI; |
464 | UUID utmp = UUID.Zero; String url = String.Empty; String first = String.Empty, last = String.Empty, tmp = String.Empty; | 511 | UUID utmp = UUID.Zero; |
512 | string url = String.Empty; | ||
513 | string first = String.Empty; | ||
514 | string last = String.Empty; | ||
515 | |||
465 | // If it's confirming the friendship, we already have the full UUI with the secret | 516 | // If it's confirming the friendship, we already have the full UUI with the secret |
466 | if (Util.ParseUniversalUserIdentifier(theFriendUUID, out utmp, out url, out first, out last, out secret)) | 517 | if (Util.ParseUniversalUserIdentifier(theFriendUUID, out utmp, out url, out first, out last, out secret)) |
467 | { | 518 | { |
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs index 45b4264..7a197f7 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs | |||
@@ -78,7 +78,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests | |||
78 | config.AddConfig("FriendsService"); | 78 | config.AddConfig("FriendsService"); |
79 | config.Configs["FriendsService"].Set("StorageProvider", "OpenSim.Data.Null.dll"); | 79 | config.Configs["FriendsService"].Set("StorageProvider", "OpenSim.Data.Null.dll"); |
80 | 80 | ||
81 | m_scene = SceneHelpers.SetupScene(); | 81 | m_scene = new SceneHelpers().SetupScene(); |
82 | m_fm = new FriendsModule(); | 82 | m_fm = new FriendsModule(); |
83 | SceneHelpers.SetupSceneModules(m_scene, config, m_fm); | 83 | SceneHelpers.SetupSceneModules(m_scene, config, m_fm); |
84 | } | 84 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs index 8560c73..6587ead 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs | |||
@@ -39,6 +39,9 @@ using OpenSim.Framework.Serialization.External; | |||
39 | using OpenSim.Region.CoreModules.World.Archiver; | 39 | using OpenSim.Region.CoreModules.World.Archiver; |
40 | using OpenSim.Region.Framework.Scenes; | 40 | using OpenSim.Region.Framework.Scenes; |
41 | using OpenSim.Services.Interfaces; | 41 | using OpenSim.Services.Interfaces; |
42 | using Ionic.Zlib; | ||
43 | using GZipStream = Ionic.Zlib.GZipStream; | ||
44 | using CompressionMode = Ionic.Zlib.CompressionMode; | ||
42 | 45 | ||
43 | namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | 46 | namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver |
44 | { | 47 | { |
@@ -91,7 +94,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
91 | /// Constructor | 94 | /// Constructor |
92 | /// </summary> | 95 | /// </summary> |
93 | public InventoryArchiveWriteRequest( | 96 | public InventoryArchiveWriteRequest( |
94 | Guid id, InventoryArchiverModule module, Scene scene, | 97 | Guid id, InventoryArchiverModule module, Scene scene, |
95 | UserAccount userInfo, string invPath, string savePath) | 98 | UserAccount userInfo, string invPath, string savePath) |
96 | : this( | 99 | : this( |
97 | id, | 100 | id, |
@@ -99,7 +102,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
99 | scene, | 102 | scene, |
100 | userInfo, | 103 | userInfo, |
101 | invPath, | 104 | invPath, |
102 | new GZipStream(new FileStream(savePath, FileMode.Create), CompressionMode.Compress)) | 105 | new GZipStream(new FileStream(savePath, FileMode.Create), CompressionMode.Compress, CompressionLevel.BestCompression)) |
103 | { | 106 | { |
104 | } | 107 | } |
105 | 108 | ||
@@ -107,7 +110,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
107 | /// Constructor | 110 | /// Constructor |
108 | /// </summary> | 111 | /// </summary> |
109 | public InventoryArchiveWriteRequest( | 112 | public InventoryArchiveWriteRequest( |
110 | Guid id, InventoryArchiverModule module, Scene scene, | 113 | Guid id, InventoryArchiverModule module, Scene scene, |
111 | UserAccount userInfo, string invPath, Stream saveStream) | 114 | UserAccount userInfo, string invPath, Stream saveStream) |
112 | { | 115 | { |
113 | m_id = id; | 116 | m_id = id; |
@@ -125,7 +128,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
125 | { | 128 | { |
126 | Exception reportedException = null; | 129 | Exception reportedException = null; |
127 | bool succeeded = true; | 130 | bool succeeded = true; |
128 | 131 | ||
129 | try | 132 | try |
130 | { | 133 | { |
131 | m_archiveWriter.Close(); | 134 | m_archiveWriter.Close(); |
@@ -146,6 +149,21 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
146 | 149 | ||
147 | protected void SaveInvItem(InventoryItemBase inventoryItem, string path, Dictionary<string, object> options, IUserAccountService userAccountService) | 150 | protected void SaveInvItem(InventoryItemBase inventoryItem, string path, Dictionary<string, object> options, IUserAccountService userAccountService) |
148 | { | 151 | { |
152 | if (options.ContainsKey("exclude")) | ||
153 | { | ||
154 | if (((List<String>)options["exclude"]).Contains(inventoryItem.Name) || | ||
155 | ((List<String>)options["exclude"]).Contains(inventoryItem.ID.ToString())) | ||
156 | { | ||
157 | if (options.ContainsKey("verbose")) | ||
158 | { | ||
159 | m_log.InfoFormat( | ||
160 | "[INVENTORY ARCHIVER]: Skipping inventory item {0} {1} at {2}", | ||
161 | inventoryItem.Name, inventoryItem.ID, path); | ||
162 | } | ||
163 | return; | ||
164 | } | ||
165 | } | ||
166 | |||
149 | if (options.ContainsKey("verbose")) | 167 | if (options.ContainsKey("verbose")) |
150 | m_log.InfoFormat( | 168 | m_log.InfoFormat( |
151 | "[INVENTORY ARCHIVER]: Saving item {0} {1} with asset {2}", | 169 | "[INVENTORY ARCHIVER]: Saving item {0} {1} with asset {2}", |
@@ -175,9 +193,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
175 | /// <param name="options"></param> | 193 | /// <param name="options"></param> |
176 | /// <param name="userAccountService"></param> | 194 | /// <param name="userAccountService"></param> |
177 | protected void SaveInvFolder( | 195 | protected void SaveInvFolder( |
178 | InventoryFolderBase inventoryFolder, string path, bool saveThisFolderItself, | 196 | InventoryFolderBase inventoryFolder, string path, bool saveThisFolderItself, |
179 | Dictionary<string, object> options, IUserAccountService userAccountService) | 197 | Dictionary<string, object> options, IUserAccountService userAccountService) |
180 | { | 198 | { |
199 | if (options.ContainsKey("excludefolders")) | ||
200 | { | ||
201 | if (((List<String>)options["excludefolders"]).Contains(inventoryFolder.Name) || | ||
202 | ((List<String>)options["excludefolders"]).Contains(inventoryFolder.ID.ToString())) | ||
203 | { | ||
204 | if (options.ContainsKey("verbose")) | ||
205 | { | ||
206 | m_log.InfoFormat( | ||
207 | "[INVENTORY ARCHIVER]: Skipping folder {0} at {1}", | ||
208 | inventoryFolder.Name, path); | ||
209 | } | ||
210 | return; | ||
211 | } | ||
212 | } | ||
213 | |||
214 | if (options.ContainsKey("verbose")) | ||
215 | m_log.InfoFormat("[INVENTORY ARCHIVER]: Saving folder {0}", inventoryFolder.Name); | ||
216 | |||
181 | if (saveThisFolderItself) | 217 | if (saveThisFolderItself) |
182 | { | 218 | { |
183 | path += CreateArchiveFolderName(inventoryFolder); | 219 | path += CreateArchiveFolderName(inventoryFolder); |
@@ -186,7 +222,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
186 | m_archiveWriter.WriteDir(path); | 222 | m_archiveWriter.WriteDir(path); |
187 | } | 223 | } |
188 | 224 | ||
189 | InventoryCollection contents | 225 | InventoryCollection contents |
190 | = m_scene.InventoryService.GetFolderContent(inventoryFolder.Owner, inventoryFolder.ID); | 226 | = m_scene.InventoryService.GetFolderContent(inventoryFolder.Owner, inventoryFolder.ID); |
191 | 227 | ||
192 | foreach (InventoryFolderBase childFolder in contents.Folders) | 228 | foreach (InventoryFolderBase childFolder in contents.Folders) |
@@ -213,16 +249,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
213 | InventoryFolderBase inventoryFolder = null; | 249 | InventoryFolderBase inventoryFolder = null; |
214 | InventoryItemBase inventoryItem = null; | 250 | InventoryItemBase inventoryItem = null; |
215 | InventoryFolderBase rootFolder = m_scene.InventoryService.GetRootFolder(m_userInfo.PrincipalID); | 251 | InventoryFolderBase rootFolder = m_scene.InventoryService.GetRootFolder(m_userInfo.PrincipalID); |
216 | 252 | ||
217 | bool saveFolderContentsOnly = false; | 253 | bool saveFolderContentsOnly = false; |
218 | 254 | ||
219 | // Eliminate double slashes and any leading / on the path. | 255 | // Eliminate double slashes and any leading / on the path. |
220 | string[] components | 256 | string[] components |
221 | = m_invPath.Split( | 257 | = m_invPath.Split( |
222 | new string[] { InventoryFolderImpl.PATH_DELIMITER }, StringSplitOptions.RemoveEmptyEntries); | 258 | new string[] { InventoryFolderImpl.PATH_DELIMITER }, StringSplitOptions.RemoveEmptyEntries); |
223 | 259 | ||
224 | int maxComponentIndex = components.Length - 1; | 260 | int maxComponentIndex = components.Length - 1; |
225 | 261 | ||
226 | // If the path terminates with a STAR then later on we want to archive all nodes in the folder but not the | 262 | // If the path terminates with a STAR then later on we want to archive all nodes in the folder but not the |
227 | // folder itself. This may get more sophisicated later on | 263 | // folder itself. This may get more sophisicated later on |
228 | if (maxComponentIndex >= 0 && components[maxComponentIndex] == STAR_WILDCARD) | 264 | if (maxComponentIndex >= 0 && components[maxComponentIndex] == STAR_WILDCARD) |
@@ -230,13 +266,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
230 | saveFolderContentsOnly = true; | 266 | saveFolderContentsOnly = true; |
231 | maxComponentIndex--; | 267 | maxComponentIndex--; |
232 | } | 268 | } |
233 | 269 | ||
234 | m_invPath = String.Empty; | 270 | m_invPath = String.Empty; |
235 | for (int i = 0; i <= maxComponentIndex; i++) | 271 | for (int i = 0; i <= maxComponentIndex; i++) |
236 | { | 272 | { |
237 | m_invPath += components[i] + InventoryFolderImpl.PATH_DELIMITER; | 273 | m_invPath += components[i] + InventoryFolderImpl.PATH_DELIMITER; |
238 | } | 274 | } |
239 | 275 | ||
240 | // Annoyingly Split actually returns the original string if the input string consists only of delimiters | 276 | // Annoyingly Split actually returns the original string if the input string consists only of delimiters |
241 | // Therefore if we still start with a / after the split, then we need the root folder | 277 | // Therefore if we still start with a / after the split, then we need the root folder |
242 | if (m_invPath.Length == 0) | 278 | if (m_invPath.Length == 0) |
@@ -246,25 +282,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
246 | else | 282 | else |
247 | { | 283 | { |
248 | m_invPath = m_invPath.Remove(m_invPath.LastIndexOf(InventoryFolderImpl.PATH_DELIMITER)); | 284 | m_invPath = m_invPath.Remove(m_invPath.LastIndexOf(InventoryFolderImpl.PATH_DELIMITER)); |
249 | List<InventoryFolderBase> candidateFolders | 285 | List<InventoryFolderBase> candidateFolders |
250 | = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, rootFolder, m_invPath); | 286 | = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, rootFolder, m_invPath); |
251 | if (candidateFolders.Count > 0) | 287 | if (candidateFolders.Count > 0) |
252 | inventoryFolder = candidateFolders[0]; | 288 | inventoryFolder = candidateFolders[0]; |
253 | } | 289 | } |
254 | 290 | ||
255 | // The path may point to an item instead | 291 | // The path may point to an item instead |
256 | if (inventoryFolder == null) | 292 | if (inventoryFolder == null) |
257 | inventoryItem = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, rootFolder, m_invPath); | 293 | inventoryItem = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, rootFolder, m_invPath); |
258 | 294 | ||
259 | if (null == inventoryFolder && null == inventoryItem) | 295 | if (null == inventoryFolder && null == inventoryItem) |
260 | { | 296 | { |
261 | // We couldn't find the path indicated | 297 | // We couldn't find the path indicated |
262 | string errorMessage = string.Format("Aborted save. Could not find inventory path {0}", m_invPath); | 298 | string errorMessage = string.Format("Aborted save. Could not find inventory path {0}", m_invPath); |
263 | Exception e = new InventoryArchiverException(errorMessage); | 299 | Exception e = new InventoryArchiverException(errorMessage); |
264 | m_module.TriggerInventoryArchiveSaved(m_id, false, m_userInfo, m_invPath, m_saveStream, e); | 300 | m_module.TriggerInventoryArchiveSaved(m_id, false, m_userInfo, m_invPath, m_saveStream, e); |
265 | throw e; | 301 | throw e; |
266 | } | 302 | } |
267 | 303 | ||
268 | m_archiveWriter = new TarArchiveWriter(m_saveStream); | 304 | m_archiveWriter = new TarArchiveWriter(m_saveStream); |
269 | 305 | ||
270 | m_log.InfoFormat("[INVENTORY ARCHIVER]: Adding control file to archive."); | 306 | m_log.InfoFormat("[INVENTORY ARCHIVER]: Adding control file to archive."); |
@@ -278,10 +314,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
278 | { | 314 | { |
279 | m_log.DebugFormat( | 315 | m_log.DebugFormat( |
280 | "[INVENTORY ARCHIVER]: Found folder {0} {1} at {2}", | 316 | "[INVENTORY ARCHIVER]: Found folder {0} {1} at {2}", |
281 | inventoryFolder.Name, | 317 | inventoryFolder.Name, |
282 | inventoryFolder.ID, | 318 | inventoryFolder.ID, |
283 | m_invPath == String.Empty ? InventoryFolderImpl.PATH_DELIMITER : m_invPath); | 319 | m_invPath == String.Empty ? InventoryFolderImpl.PATH_DELIMITER : m_invPath); |
284 | 320 | ||
285 | //recurse through all dirs getting dirs and files | 321 | //recurse through all dirs getting dirs and files |
286 | SaveInvFolder(inventoryFolder, ArchiveConstants.INVENTORY_PATH, !saveFolderContentsOnly, options, userAccountService); | 322 | SaveInvFolder(inventoryFolder, ArchiveConstants.INVENTORY_PATH, !saveFolderContentsOnly, options, userAccountService); |
287 | } | 323 | } |
@@ -290,10 +326,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
290 | m_log.DebugFormat( | 326 | m_log.DebugFormat( |
291 | "[INVENTORY ARCHIVER]: Found item {0} {1} at {2}", | 327 | "[INVENTORY ARCHIVER]: Found item {0} {1} at {2}", |
292 | inventoryItem.Name, inventoryItem.ID, m_invPath); | 328 | inventoryItem.Name, inventoryItem.ID, m_invPath); |
293 | 329 | ||
294 | SaveInvItem(inventoryItem, ArchiveConstants.INVENTORY_PATH, options, userAccountService); | 330 | SaveInvItem(inventoryItem, ArchiveConstants.INVENTORY_PATH, options, userAccountService); |
295 | } | 331 | } |
296 | 332 | ||
297 | // Don't put all this profile information into the archive right now. | 333 | // Don't put all this profile information into the archive right now. |
298 | //SaveUsers(); | 334 | //SaveUsers(); |
299 | 335 | ||
@@ -352,7 +388,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
352 | /// | 388 | /// |
353 | /// These names are prepended with an inventory folder's UUID so that more than one folder can have the | 389 | /// These names are prepended with an inventory folder's UUID so that more than one folder can have the |
354 | /// same name | 390 | /// same name |
355 | /// | 391 | /// |
356 | /// <param name="folder"></param> | 392 | /// <param name="folder"></param> |
357 | /// <returns></returns> | 393 | /// <returns></returns> |
358 | public static string CreateArchiveFolderName(InventoryFolderBase folder) | 394 | public static string CreateArchiveFolderName(InventoryFolderBase folder) |
@@ -366,7 +402,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
366 | /// | 402 | /// |
367 | /// These names are prepended with an inventory item's UUID so that more than one item can have the | 403 | /// These names are prepended with an inventory item's UUID so that more than one item can have the |
368 | /// same name | 404 | /// same name |
369 | /// | 405 | /// |
370 | /// <param name="item"></param> | 406 | /// <param name="item"></param> |
371 | /// <returns></returns> | 407 | /// <returns></returns> |
372 | public static string CreateArchiveItemName(InventoryItemBase item) | 408 | public static string CreateArchiveItemName(InventoryItemBase item) |
@@ -412,7 +448,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
412 | public string CreateControlFile(Dictionary<string, object> options) | 448 | public string CreateControlFile(Dictionary<string, object> options) |
413 | { | 449 | { |
414 | int majorVersion, minorVersion; | 450 | int majorVersion, minorVersion; |
415 | 451 | ||
416 | if (options.ContainsKey("home")) | 452 | if (options.ContainsKey("home")) |
417 | { | 453 | { |
418 | majorVersion = 1; | 454 | majorVersion = 1; |
@@ -422,10 +458,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
422 | { | 458 | { |
423 | majorVersion = 0; | 459 | majorVersion = 0; |
424 | minorVersion = 3; | 460 | minorVersion = 3; |
425 | } | 461 | } |
426 | 462 | ||
427 | m_log.InfoFormat("[INVENTORY ARCHIVER]: Creating version {0}.{1} IAR", majorVersion, minorVersion); | 463 | m_log.InfoFormat("[INVENTORY ARCHIVER]: Creating version {0}.{1} IAR", majorVersion, minorVersion); |
428 | 464 | ||
429 | StringWriter sw = new StringWriter(); | 465 | StringWriter sw = new StringWriter(); |
430 | XmlTextWriter xtw = new XmlTextWriter(sw); | 466 | XmlTextWriter xtw = new XmlTextWriter(sw); |
431 | xtw.Formatting = Formatting.Indented; | 467 | xtw.Formatting = Formatting.Indented; |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs index ac22c3f..cf87010 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs | |||
@@ -47,18 +47,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
47 | public class InventoryArchiverModule : IRegionModule, IInventoryArchiverModule | 47 | public class InventoryArchiverModule : IRegionModule, IInventoryArchiverModule |
48 | { | 48 | { |
49 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 49 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
50 | 50 | ||
51 | public string Name { get { return "Inventory Archiver Module"; } } | 51 | public string Name { get { return "Inventory Archiver Module"; } } |
52 | 52 | ||
53 | public bool IsSharedModule { get { return true; } } | 53 | public bool IsSharedModule { get { return true; } } |
54 | 54 | ||
55 | /// <value> | 55 | /// <value> |
56 | /// Enable or disable checking whether the iar user is actually logged in | 56 | /// Enable or disable checking whether the iar user is actually logged in |
57 | /// </value> | 57 | /// </value> |
58 | // public bool DisablePresenceChecks { get; set; } | 58 | // public bool DisablePresenceChecks { get; set; } |
59 | 59 | ||
60 | public event InventoryArchiveSaved OnInventoryArchiveSaved; | 60 | public event InventoryArchiveSaved OnInventoryArchiveSaved; |
61 | 61 | ||
62 | /// <summary> | 62 | /// <summary> |
63 | /// The file to load and save inventory if no filename has been specified | 63 | /// The file to load and save inventory if no filename has been specified |
64 | /// </summary> | 64 | /// </summary> |
@@ -68,7 +68,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
68 | /// Pending save completions initiated from the console | 68 | /// Pending save completions initiated from the console |
69 | /// </value> | 69 | /// </value> |
70 | protected List<Guid> m_pendingConsoleSaves = new List<Guid>(); | 70 | protected List<Guid> m_pendingConsoleSaves = new List<Guid>(); |
71 | 71 | ||
72 | /// <value> | 72 | /// <value> |
73 | /// All scenes that this module knows about | 73 | /// All scenes that this module knows about |
74 | /// </value> | 74 | /// </value> |
@@ -106,7 +106,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
106 | { | 106 | { |
107 | scene.RegisterModuleInterface<IInventoryArchiverModule>(this); | 107 | scene.RegisterModuleInterface<IInventoryArchiverModule>(this); |
108 | OnInventoryArchiveSaved += SaveInvConsoleCommandCompleted; | 108 | OnInventoryArchiveSaved += SaveInvConsoleCommandCompleted; |
109 | 109 | ||
110 | scene.AddCommand( | 110 | scene.AddCommand( |
111 | "Archiving", this, "load iar", | 111 | "Archiving", this, "load iar", |
112 | "load iar [-m|--merge] <first> <last> <inventory path> <password> [<IAR path>]", | 112 | "load iar [-m|--merge] <first> <last> <inventory path> <password> [<IAR path>]", |
@@ -119,11 +119,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
119 | + "<IAR path> is the filesystem path or URI from which to load the IAR." | 119 | + "<IAR path> is the filesystem path or URI from which to load the IAR." |
120 | + string.Format(" If this is not given then the filename {0} in the current directory is used", DEFAULT_INV_BACKUP_FILENAME), | 120 | + string.Format(" If this is not given then the filename {0} in the current directory is used", DEFAULT_INV_BACKUP_FILENAME), |
121 | HandleLoadInvConsoleCommand); | 121 | HandleLoadInvConsoleCommand); |
122 | 122 | ||
123 | scene.AddCommand( | 123 | scene.AddCommand( |
124 | "Archiving", this, "save iar", | 124 | "Archiving", this, "save iar", |
125 | "save iar [-h|--home=<url>] [--noassets] <first> <last> <inventory path> <password> [<IAR path>] [-c|--creators] [-v|--verbose]", | 125 | "save iar [-h|--home=<url>] [--noassets] <first> <last> <inventory path> <password> [<IAR path>] [-c|--creators] [-e|--exclude=<name/uuid>] [-f|--excludefolder=<foldername/uuid>] [-v|--verbose]", |
126 | "Save user inventory archive (IAR).", | 126 | "Save user inventory archive (IAR).", |
127 | "<first> is the user's first name.\n" | 127 | "<first> is the user's first name.\n" |
128 | + "<last> is the user's last name.\n" | 128 | + "<last> is the user's last name.\n" |
129 | + "<inventory path> is the path inside the user's inventory for the folder/item to be saved.\n" | 129 | + "<inventory path> is the path inside the user's inventory for the folder/item to be saved.\n" |
@@ -131,32 +131,34 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
131 | + string.Format(" If this is not given then the filename {0} in the current directory is used.\n", DEFAULT_INV_BACKUP_FILENAME) | 131 | + string.Format(" If this is not given then the filename {0} in the current directory is used.\n", DEFAULT_INV_BACKUP_FILENAME) |
132 | + "-h|--home=<url> adds the url of the profile service to the saved user information.\n" | 132 | + "-h|--home=<url> adds the url of the profile service to the saved user information.\n" |
133 | + "-c|--creators preserves information about foreign creators.\n" | 133 | + "-c|--creators preserves information about foreign creators.\n" |
134 | + "-e|--exclude=<name/uuid> don't save the inventory item in archive" + Environment.NewLine | ||
135 | + "-f|--excludefolder=<folder/uuid> don't save contents of the folder in archive" + Environment.NewLine | ||
134 | + "-v|--verbose extra debug messages.\n" | 136 | + "-v|--verbose extra debug messages.\n" |
135 | + "--noassets stops assets being saved to the IAR.", | 137 | + "--noassets stops assets being saved to the IAR.", |
136 | HandleSaveInvConsoleCommand); | 138 | HandleSaveInvConsoleCommand); |
137 | 139 | ||
138 | m_aScene = scene; | 140 | m_aScene = scene; |
139 | } | 141 | } |
140 | 142 | ||
141 | m_scenes[scene.RegionInfo.RegionID] = scene; | 143 | m_scenes[scene.RegionInfo.RegionID] = scene; |
142 | } | 144 | } |
143 | 145 | ||
144 | public void PostInitialise() {} | 146 | public void PostInitialise() {} |
145 | 147 | ||
146 | public void Close() {} | 148 | public void Close() {} |
147 | 149 | ||
148 | /// <summary> | 150 | /// <summary> |
149 | /// Trigger the inventory archive saved event. | 151 | /// Trigger the inventory archive saved event. |
150 | /// </summary> | 152 | /// </summary> |
151 | protected internal void TriggerInventoryArchiveSaved( | 153 | protected internal void TriggerInventoryArchiveSaved( |
152 | Guid id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream, | 154 | Guid id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream, |
153 | Exception reportedException) | 155 | Exception reportedException) |
154 | { | 156 | { |
155 | InventoryArchiveSaved handlerInventoryArchiveSaved = OnInventoryArchiveSaved; | 157 | InventoryArchiveSaved handlerInventoryArchiveSaved = OnInventoryArchiveSaved; |
156 | if (handlerInventoryArchiveSaved != null) | 158 | if (handlerInventoryArchiveSaved != null) |
157 | handlerInventoryArchiveSaved(id, succeeded, userInfo, invPath, saveStream, reportedException); | 159 | handlerInventoryArchiveSaved(id, succeeded, userInfo, invPath, saveStream, reportedException); |
158 | } | 160 | } |
159 | 161 | ||
160 | public bool ArchiveInventory( | 162 | public bool ArchiveInventory( |
161 | Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream) | 163 | Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream) |
162 | { | 164 | { |
@@ -164,7 +166,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
164 | } | 166 | } |
165 | 167 | ||
166 | public bool ArchiveInventory( | 168 | public bool ArchiveInventory( |
167 | Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream, | 169 | Guid id, string firstName, string lastName, string invPath, string pass, Stream saveStream, |
168 | Dictionary<string, object> options) | 170 | Dictionary<string, object> options) |
169 | { | 171 | { |
170 | if (m_scenes.Count > 0) | 172 | if (m_scenes.Count > 0) |
@@ -188,7 +190,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
188 | 190 | ||
189 | return false; | 191 | return false; |
190 | } | 192 | } |
191 | 193 | ||
192 | return true; | 194 | return true; |
193 | // } | 195 | // } |
194 | // else | 196 | // else |
@@ -202,15 +204,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
202 | 204 | ||
203 | return false; | 205 | return false; |
204 | } | 206 | } |
205 | 207 | ||
206 | public bool ArchiveInventory( | 208 | public bool ArchiveInventory( |
207 | Guid id, string firstName, string lastName, string invPath, string pass, string savePath, | 209 | Guid id, string firstName, string lastName, string invPath, string pass, string savePath, |
208 | Dictionary<string, object> options) | 210 | Dictionary<string, object> options) |
209 | { | 211 | { |
210 | if (m_scenes.Count > 0) | 212 | if (m_scenes.Count > 0) |
211 | { | 213 | { |
212 | UserAccount userInfo = GetUserInfo(firstName, lastName, pass); | 214 | UserAccount userInfo = GetUserInfo(firstName, lastName, pass); |
213 | 215 | ||
214 | if (userInfo != null) | 216 | if (userInfo != null) |
215 | { | 217 | { |
216 | // if (CheckPresence(userInfo.PrincipalID)) | 218 | // if (CheckPresence(userInfo.PrincipalID)) |
@@ -228,7 +230,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
228 | 230 | ||
229 | return false; | 231 | return false; |
230 | } | 232 | } |
231 | 233 | ||
232 | return true; | 234 | return true; |
233 | // } | 235 | // } |
234 | // else | 236 | // else |
@@ -239,7 +241,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
239 | // } | 241 | // } |
240 | } | 242 | } |
241 | } | 243 | } |
242 | 244 | ||
243 | return false; | 245 | return false; |
244 | } | 246 | } |
245 | 247 | ||
@@ -247,9 +249,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
247 | { | 249 | { |
248 | return DearchiveInventory(firstName, lastName, invPath, pass, loadStream, new Dictionary<string, object>()); | 250 | return DearchiveInventory(firstName, lastName, invPath, pass, loadStream, new Dictionary<string, object>()); |
249 | } | 251 | } |
250 | 252 | ||
251 | public bool DearchiveInventory( | 253 | public bool DearchiveInventory( |
252 | string firstName, string lastName, string invPath, string pass, Stream loadStream, | 254 | string firstName, string lastName, string invPath, string pass, Stream loadStream, |
253 | Dictionary<string, object> options) | 255 | Dictionary<string, object> options) |
254 | { | 256 | { |
255 | if (m_scenes.Count > 0) | 257 | if (m_scenes.Count > 0) |
@@ -295,22 +297,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
295 | 297 | ||
296 | return false; | 298 | return false; |
297 | } | 299 | } |
298 | 300 | ||
299 | public bool DearchiveInventory( | 301 | public bool DearchiveInventory( |
300 | string firstName, string lastName, string invPath, string pass, string loadPath, | 302 | string firstName, string lastName, string invPath, string pass, string loadPath, |
301 | Dictionary<string, object> options) | 303 | Dictionary<string, object> options) |
302 | { | 304 | { |
303 | if (m_scenes.Count > 0) | 305 | if (m_scenes.Count > 0) |
304 | { | 306 | { |
305 | UserAccount userInfo = GetUserInfo(firstName, lastName, pass); | 307 | UserAccount userInfo = GetUserInfo(firstName, lastName, pass); |
306 | 308 | ||
307 | if (userInfo != null) | 309 | if (userInfo != null) |
308 | { | 310 | { |
309 | // if (CheckPresence(userInfo.PrincipalID)) | 311 | // if (CheckPresence(userInfo.PrincipalID)) |
310 | // { | 312 | // { |
311 | InventoryArchiveReadRequest request; | 313 | InventoryArchiveReadRequest request; |
312 | bool merge = (options.ContainsKey("merge") ? (bool)options["merge"] : false); | 314 | bool merge = (options.ContainsKey("merge") ? (bool)options["merge"] : false); |
313 | 315 | ||
314 | try | 316 | try |
315 | { | 317 | { |
316 | request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadPath, merge); | 318 | request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadPath, merge); |
@@ -324,7 +326,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
324 | 326 | ||
325 | return false; | 327 | return false; |
326 | } | 328 | } |
327 | 329 | ||
328 | UpdateClientWithLoadedNodes(userInfo, request.Execute()); | 330 | UpdateClientWithLoadedNodes(userInfo, request.Execute()); |
329 | 331 | ||
330 | return true; | 332 | return true; |
@@ -340,7 +342,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
340 | 342 | ||
341 | return false; | 343 | return false; |
342 | } | 344 | } |
343 | 345 | ||
344 | /// <summary> | 346 | /// <summary> |
345 | /// Load inventory from an inventory file archive | 347 | /// Load inventory from an inventory file archive |
346 | /// </summary> | 348 | /// </summary> |
@@ -351,26 +353,26 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
351 | { | 353 | { |
352 | Dictionary<string, object> options = new Dictionary<string, object>(); | 354 | Dictionary<string, object> options = new Dictionary<string, object>(); |
353 | OptionSet optionSet = new OptionSet().Add("m|merge", delegate (string v) { options["merge"] = v != null; }); | 355 | OptionSet optionSet = new OptionSet().Add("m|merge", delegate (string v) { options["merge"] = v != null; }); |
354 | 356 | ||
355 | List<string> mainParams = optionSet.Parse(cmdparams); | 357 | List<string> mainParams = optionSet.Parse(cmdparams); |
356 | 358 | ||
357 | if (mainParams.Count < 6) | 359 | if (mainParams.Count < 6) |
358 | { | 360 | { |
359 | m_log.Error( | 361 | m_log.Error( |
360 | "[INVENTORY ARCHIVER]: usage is load iar [-m|--merge] <first name> <last name> <inventory path> <user password> [<load file path>]"); | 362 | "[INVENTORY ARCHIVER]: usage is load iar [-m|--merge] <first name> <last name> <inventory path> <user password> [<load file path>]"); |
361 | return; | 363 | return; |
362 | } | 364 | } |
363 | 365 | ||
364 | string firstName = mainParams[2]; | 366 | string firstName = mainParams[2]; |
365 | string lastName = mainParams[3]; | 367 | string lastName = mainParams[3]; |
366 | string invPath = mainParams[4]; | 368 | string invPath = mainParams[4]; |
367 | string pass = mainParams[5]; | 369 | string pass = mainParams[5]; |
368 | string loadPath = (mainParams.Count > 6 ? mainParams[6] : DEFAULT_INV_BACKUP_FILENAME); | 370 | string loadPath = (mainParams.Count > 6 ? mainParams[6] : DEFAULT_INV_BACKUP_FILENAME); |
369 | 371 | ||
370 | m_log.InfoFormat( | 372 | m_log.InfoFormat( |
371 | "[INVENTORY ARCHIVER]: Loading archive {0} to inventory path {1} for {2} {3}", | 373 | "[INVENTORY ARCHIVER]: Loading archive {0} to inventory path {1} for {2} {3}", |
372 | loadPath, invPath, firstName, lastName); | 374 | loadPath, invPath, firstName, lastName); |
373 | 375 | ||
374 | if (DearchiveInventory(firstName, lastName, invPath, pass, loadPath, options)) | 376 | if (DearchiveInventory(firstName, lastName, invPath, pass, loadPath, options)) |
375 | m_log.InfoFormat( | 377 | m_log.InfoFormat( |
376 | "[INVENTORY ARCHIVER]: Loaded archive {0} for {1} {2}", | 378 | "[INVENTORY ARCHIVER]: Loaded archive {0} for {1} {2}", |
@@ -381,7 +383,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
381 | m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message); | 383 | m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message); |
382 | } | 384 | } |
383 | } | 385 | } |
384 | 386 | ||
385 | /// <summary> | 387 | /// <summary> |
386 | /// Save inventory to a file archive | 388 | /// Save inventory to a file archive |
387 | /// </summary> | 389 | /// </summary> |
@@ -398,6 +400,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
398 | ops.Add("v|verbose", delegate(string v) { options["verbose"] = v; }); | 400 | ops.Add("v|verbose", delegate(string v) { options["verbose"] = v; }); |
399 | ops.Add("c|creators", delegate(string v) { options["creators"] = v; }); | 401 | ops.Add("c|creators", delegate(string v) { options["creators"] = v; }); |
400 | ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; }); | 402 | ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; }); |
403 | ops.Add("e|exclude=", delegate(string v) | ||
404 | { | ||
405 | if (!options.ContainsKey("exclude")) | ||
406 | options["exclude"] = new List<String>(); | ||
407 | ((List<String>)options["exclude"]).Add(v); | ||
408 | }); | ||
409 | ops.Add("f|excludefolder=", delegate(string v) | ||
410 | { | ||
411 | if (!options.ContainsKey("excludefolders")) | ||
412 | options["excludefolders"] = new List<String>(); | ||
413 | ((List<String>)options["excludefolders"]).Add(v); | ||
414 | }); | ||
401 | 415 | ||
402 | List<string> mainParams = ops.Parse(cmdparams); | 416 | List<string> mainParams = ops.Parse(cmdparams); |
403 | 417 | ||
@@ -406,10 +420,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
406 | if (mainParams.Count < 6) | 420 | if (mainParams.Count < 6) |
407 | { | 421 | { |
408 | m_log.Error( | 422 | m_log.Error( |
409 | "[INVENTORY ARCHIVER]: usage is save iar [-h|--home=<url>] [--noassets] <first name> <last name> <inventory path> <user password> [<save file path>] [-c|--creators] [-v|--verbose]"); | 423 | "[INVENTORY ARCHIVER]: save iar [-h|--home=<url>] [--noassets] <first> <last> <inventory path> <password> [<IAR path>] [-c|--creators] [-e|--exclude=<name/uuid>] [-f|--excludefolder=<foldername/uuid>] [-v|--verbose]"); |
410 | return; | 424 | return; |
411 | } | 425 | } |
412 | 426 | ||
413 | if (options.ContainsKey("home")) | 427 | if (options.ContainsKey("home")) |
414 | m_log.WarnFormat("[INVENTORY ARCHIVER]: Please be aware that inventory archives with creator information are not compatible with OpenSim 0.7.0.2 and earlier. Do not use the -home option if you want to produce a compatible IAR"); | 428 | m_log.WarnFormat("[INVENTORY ARCHIVER]: Please be aware that inventory archives with creator information are not compatible with OpenSim 0.7.0.2 and earlier. Do not use the -home option if you want to produce a compatible IAR"); |
415 | 429 | ||
@@ -418,7 +432,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
418 | string invPath = mainParams[4]; | 432 | string invPath = mainParams[4]; |
419 | string pass = mainParams[5]; | 433 | string pass = mainParams[5]; |
420 | string savePath = (mainParams.Count > 6 ? mainParams[6] : DEFAULT_INV_BACKUP_FILENAME); | 434 | string savePath = (mainParams.Count > 6 ? mainParams[6] : DEFAULT_INV_BACKUP_FILENAME); |
421 | 435 | ||
422 | m_log.InfoFormat( | 436 | m_log.InfoFormat( |
423 | "[INVENTORY ARCHIVER]: Saving archive {0} using inventory path {1} for {2} {3}", | 437 | "[INVENTORY ARCHIVER]: Saving archive {0} using inventory path {1} for {2} {3}", |
424 | savePath, invPath, firstName, lastName); | 438 | savePath, invPath, firstName, lastName); |
@@ -433,9 +447,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
433 | m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message); | 447 | m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", e.Message); |
434 | } | 448 | } |
435 | } | 449 | } |
436 | 450 | ||
437 | private void SaveInvConsoleCommandCompleted( | 451 | private void SaveInvConsoleCommandCompleted( |
438 | Guid id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream, | 452 | Guid id, bool succeeded, UserAccount userInfo, string invPath, Stream saveStream, |
439 | Exception reportedException) | 453 | Exception reportedException) |
440 | { | 454 | { |
441 | lock (m_pendingConsoleSaves) | 455 | lock (m_pendingConsoleSaves) |
@@ -445,7 +459,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
445 | else | 459 | else |
446 | return; | 460 | return; |
447 | } | 461 | } |
448 | 462 | ||
449 | if (succeeded) | 463 | if (succeeded) |
450 | { | 464 | { |
451 | m_log.InfoFormat("[INVENTORY ARCHIVER]: Saved archive for {0} {1}", userInfo.FirstName, userInfo.LastName); | 465 | m_log.InfoFormat("[INVENTORY ARCHIVER]: Saved archive for {0} {1}", userInfo.FirstName, userInfo.LastName); |
@@ -453,11 +467,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
453 | else | 467 | else |
454 | { | 468 | { |
455 | m_log.ErrorFormat( | 469 | m_log.ErrorFormat( |
456 | "[INVENTORY ARCHIVER]: Archive save for {0} {1} failed - {2}", | 470 | "[INVENTORY ARCHIVER]: Archive save for {0} {1} failed - {2}", |
457 | userInfo.FirstName, userInfo.LastName, reportedException.Message); | 471 | userInfo.FirstName, userInfo.LastName, reportedException.Message); |
458 | } | 472 | } |
459 | } | 473 | } |
460 | 474 | ||
461 | /// <summary> | 475 | /// <summary> |
462 | /// Get user information for the given name. | 476 | /// Get user information for the given name. |
463 | /// </summary> | 477 | /// </summary> |
@@ -467,13 +481,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
467 | /// <returns></returns> | 481 | /// <returns></returns> |
468 | protected UserAccount GetUserInfo(string firstName, string lastName, string pass) | 482 | protected UserAccount GetUserInfo(string firstName, string lastName, string pass) |
469 | { | 483 | { |
470 | UserAccount account | 484 | UserAccount account |
471 | = m_aScene.UserAccountService.GetUserAccount(m_aScene.RegionInfo.ScopeID, firstName, lastName); | 485 | = m_aScene.UserAccountService.GetUserAccount(m_aScene.RegionInfo.ScopeID, firstName, lastName); |
472 | 486 | ||
473 | if (null == account) | 487 | if (null == account) |
474 | { | 488 | { |
475 | m_log.ErrorFormat( | 489 | m_log.ErrorFormat( |
476 | "[INVENTORY ARCHIVER]: Failed to find user info for {0} {1}", | 490 | "[INVENTORY ARCHIVER]: Failed to find user info for {0} {1}", |
477 | firstName, lastName); | 491 | firstName, lastName); |
478 | return null; | 492 | return null; |
479 | } | 493 | } |
@@ -488,7 +502,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
488 | else | 502 | else |
489 | { | 503 | { |
490 | m_log.ErrorFormat( | 504 | m_log.ErrorFormat( |
491 | "[INVENTORY ARCHIVER]: Password for user {0} {1} incorrect. Please try again.", | 505 | "[INVENTORY ARCHIVER]: Password for user {0} {1} incorrect. Please try again.", |
492 | firstName, lastName); | 506 | firstName, lastName); |
493 | return null; | 507 | return null; |
494 | } | 508 | } |
@@ -499,7 +513,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
499 | return null; | 513 | return null; |
500 | } | 514 | } |
501 | } | 515 | } |
502 | 516 | ||
503 | /// <summary> | 517 | /// <summary> |
504 | /// Notify the client of loaded nodes if they are logged in | 518 | /// Notify the client of loaded nodes if they are logged in |
505 | /// </summary> | 519 | /// </summary> |
@@ -508,22 +522,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
508 | { | 522 | { |
509 | if (loadedNodes.Count == 0) | 523 | if (loadedNodes.Count == 0) |
510 | return; | 524 | return; |
511 | 525 | ||
512 | foreach (Scene scene in m_scenes.Values) | 526 | foreach (Scene scene in m_scenes.Values) |
513 | { | 527 | { |
514 | ScenePresence user = scene.GetScenePresence(userInfo.PrincipalID); | 528 | ScenePresence user = scene.GetScenePresence(userInfo.PrincipalID); |
515 | 529 | ||
516 | if (user != null && !user.IsChildAgent) | 530 | if (user != null && !user.IsChildAgent) |
517 | { | 531 | { |
518 | foreach (InventoryNodeBase node in loadedNodes) | 532 | foreach (InventoryNodeBase node in loadedNodes) |
519 | { | 533 | { |
520 | // m_log.DebugFormat( | 534 | // m_log.DebugFormat( |
521 | // "[INVENTORY ARCHIVER]: Notifying {0} of loaded inventory node {1}", | 535 | // "[INVENTORY ARCHIVER]: Notifying {0} of loaded inventory node {1}", |
522 | // user.Name, node.Name); | 536 | // user.Name, node.Name); |
523 | 537 | ||
524 | user.ControllingClient.SendBulkUpdateInventory(node); | 538 | user.ControllingClient.SendBulkUpdateInventory(node); |
525 | } | 539 | } |
526 | 540 | ||
527 | break; | 541 | break; |
528 | } | 542 | } |
529 | } | 543 | } |
@@ -538,7 +552,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
538 | // { | 552 | // { |
539 | // if (DisablePresenceChecks) | 553 | // if (DisablePresenceChecks) |
540 | // return true; | 554 | // return true; |
541 | // | 555 | // |
542 | // foreach (Scene scene in m_scenes.Values) | 556 | // foreach (Scene scene in m_scenes.Values) |
543 | // { | 557 | // { |
544 | // ScenePresence p; | 558 | // ScenePresence p; |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs index 19ef571..1056865 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs | |||
@@ -48,7 +48,7 @@ using OpenSim.Tests.Common.Mock; | |||
48 | namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | 48 | namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests |
49 | { | 49 | { |
50 | [TestFixture] | 50 | [TestFixture] |
51 | public class InventoryArchiveTestCase | 51 | public class InventoryArchiveTestCase : OpenSimTestCase |
52 | { | 52 | { |
53 | protected ManualResetEvent mre = new ManualResetEvent(false); | 53 | protected ManualResetEvent mre = new ManualResetEvent(false); |
54 | 54 | ||
@@ -84,8 +84,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
84 | protected string m_coaItemName = "Coalesced Item"; | 84 | protected string m_coaItemName = "Coalesced Item"; |
85 | 85 | ||
86 | [SetUp] | 86 | [SetUp] |
87 | public virtual void SetUp() | 87 | public override void SetUp() |
88 | { | 88 | { |
89 | base.SetUp(); | ||
89 | m_iarStream = new MemoryStream(m_iarStreamBytes); | 90 | m_iarStream = new MemoryStream(m_iarStreamBytes); |
90 | } | 91 | } |
91 | 92 | ||
@@ -100,7 +101,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
100 | // log4net.Config.XmlConfigurator.Configure(); | 101 | // log4net.Config.XmlConfigurator.Configure(); |
101 | 102 | ||
102 | InventoryArchiverModule archiverModule = new InventoryArchiverModule(); | 103 | InventoryArchiverModule archiverModule = new InventoryArchiverModule(); |
103 | Scene scene = SceneHelpers.SetupScene(); | 104 | Scene scene = new SceneHelpers().SetupScene(); |
104 | SceneHelpers.SetupSceneModules(scene, archiverModule); | 105 | SceneHelpers.SetupSceneModules(scene, archiverModule); |
105 | 106 | ||
106 | UserAccountHelpers.CreateUserWithInventory(scene, m_uaLL1, "hampshire"); | 107 | UserAccountHelpers.CreateUserWithInventory(scene, m_uaLL1, "hampshire"); |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs index e409c8e..b112b6d 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs | |||
@@ -61,7 +61,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
61 | SerialiserModule serialiserModule = new SerialiserModule(); | 61 | SerialiserModule serialiserModule = new SerialiserModule(); |
62 | m_archiverModule = new InventoryArchiverModule(); | 62 | m_archiverModule = new InventoryArchiverModule(); |
63 | 63 | ||
64 | m_scene = SceneHelpers.SetupScene(); | 64 | m_scene = new SceneHelpers().SetupScene(); |
65 | SceneHelpers.SetupSceneModules(m_scene, serialiserModule, m_archiverModule); | 65 | SceneHelpers.SetupSceneModules(m_scene, serialiserModule, m_archiverModule); |
66 | } | 66 | } |
67 | 67 | ||
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs index 417c20c..6eb3605 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs | |||
@@ -62,7 +62,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
62 | 62 | ||
63 | InventoryArchiverModule archiverModule = new InventoryArchiverModule(); | 63 | InventoryArchiverModule archiverModule = new InventoryArchiverModule(); |
64 | 64 | ||
65 | Scene scene = SceneHelpers.SetupScene(); | 65 | Scene scene = new SceneHelpers().SetupScene(); |
66 | SceneHelpers.SetupSceneModules(scene, archiverModule); | 66 | SceneHelpers.SetupSceneModules(scene, archiverModule); |
67 | 67 | ||
68 | // Create user | 68 | // Create user |
@@ -179,7 +179,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
179 | InventoryArchiverModule archiverModule = new InventoryArchiverModule(); | 179 | InventoryArchiverModule archiverModule = new InventoryArchiverModule(); |
180 | 180 | ||
181 | // Annoyingly, we have to set up a scene even though inventory loading has nothing to do with a scene | 181 | // Annoyingly, we have to set up a scene even though inventory loading has nothing to do with a scene |
182 | Scene scene = SceneHelpers.SetupScene(); | 182 | Scene scene = new SceneHelpers().SetupScene(); |
183 | 183 | ||
184 | SceneHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); | 184 | SceneHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); |
185 | 185 | ||
@@ -222,7 +222,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
222 | 222 | ||
223 | SerialiserModule serialiserModule = new SerialiserModule(); | 223 | SerialiserModule serialiserModule = new SerialiserModule(); |
224 | InventoryArchiverModule archiverModule = new InventoryArchiverModule(); | 224 | InventoryArchiverModule archiverModule = new InventoryArchiverModule(); |
225 | Scene scene = SceneHelpers.SetupScene(); | 225 | Scene scene = new SceneHelpers().SetupScene(); |
226 | SceneHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); | 226 | SceneHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); |
227 | 227 | ||
228 | UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "password"); | 228 | UserAccountHelpers.CreateUserWithInventory(scene, m_uaMT, "password"); |
@@ -247,7 +247,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
247 | 247 | ||
248 | InventoryArchiverModule archiverModule = new InventoryArchiverModule(); | 248 | InventoryArchiverModule archiverModule = new InventoryArchiverModule(); |
249 | 249 | ||
250 | Scene scene = SceneHelpers.SetupScene(); | 250 | Scene scene = new SceneHelpers().SetupScene(); |
251 | SceneHelpers.SetupSceneModules(scene, archiverModule); | 251 | SceneHelpers.SetupSceneModules(scene, archiverModule); |
252 | 252 | ||
253 | // Create user | 253 | // Create user |
@@ -326,7 +326,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
326 | TestHelpers.InMethod(); | 326 | TestHelpers.InMethod(); |
327 | // log4net.Config.XmlConfigurator.Configure(); | 327 | // log4net.Config.XmlConfigurator.Configure(); |
328 | 328 | ||
329 | Scene scene = SceneHelpers.SetupScene(); | 329 | Scene scene = new SceneHelpers().SetupScene(); |
330 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene); | 330 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene); |
331 | 331 | ||
332 | Dictionary <string, InventoryFolderBase> foldersCreated = new Dictionary<string, InventoryFolderBase>(); | 332 | Dictionary <string, InventoryFolderBase> foldersCreated = new Dictionary<string, InventoryFolderBase>(); |
@@ -393,7 +393,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
393 | TestHelpers.InMethod(); | 393 | TestHelpers.InMethod(); |
394 | //log4net.Config.XmlConfigurator.Configure(); | 394 | //log4net.Config.XmlConfigurator.Configure(); |
395 | 395 | ||
396 | Scene scene = SceneHelpers.SetupScene(); | 396 | Scene scene = new SceneHelpers().SetupScene(); |
397 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene); | 397 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene); |
398 | 398 | ||
399 | string folder1ExistingName = "a"; | 399 | string folder1ExistingName = "a"; |
@@ -444,7 +444,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
444 | TestHelpers.InMethod(); | 444 | TestHelpers.InMethod(); |
445 | // log4net.Config.XmlConfigurator.Configure(); | 445 | // log4net.Config.XmlConfigurator.Configure(); |
446 | 446 | ||
447 | Scene scene = SceneHelpers.SetupScene(); | 447 | Scene scene = new SceneHelpers().SetupScene(); |
448 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene); | 448 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene); |
449 | 449 | ||
450 | string folder1ExistingName = "a"; | 450 | string folder1ExistingName = "a"; |
diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs index bc5c1ff..92cf9d1 100644 --- a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs | |||
@@ -240,13 +240,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure | |||
240 | { | 240 | { |
241 | ScenePresence sp = scene.GetScenePresence(client.AgentId); | 241 | ScenePresence sp = scene.GetScenePresence(client.AgentId); |
242 | IEntityTransferModule transferMod = scene.RequestModuleInterface<IEntityTransferModule>(); | 242 | IEntityTransferModule transferMod = scene.RequestModuleInterface<IEntityTransferModule>(); |
243 | IEventQueue eq = sp.Scene.RequestModuleInterface<IEventQueue>(); | 243 | |
244 | if (transferMod != null && sp != null && eq != null) | 244 | if (transferMod != null && sp != null) |
245 | transferMod.DoTeleport(sp, gatekeeper, finalDestination, im.Position + new Vector3(0.5f, 0.5f, 0f), Vector3.UnitX, teleportflags, eq); | 245 | transferMod.DoTeleport( |
246 | sp, gatekeeper, finalDestination, im.Position + new Vector3(0.5f, 0.5f, 0f), | ||
247 | Vector3.UnitX, teleportflags); | ||
246 | } | 248 | } |
247 | } | 249 | } |
248 | } | 250 | } |
249 | } | 251 | } |
250 | } | 252 | } |
251 | } | 253 | } |
252 | } | 254 | } \ No newline at end of file |
diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs index dcfdf8f..a889984 100644 --- a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs | |||
@@ -151,6 +151,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure | |||
151 | Scene scene = (Scene)(client.Scene); | 151 | Scene scene = (Scene)(client.Scene); |
152 | ScenePresence presence = scene.GetScenePresence(client.AgentId); | 152 | ScenePresence presence = scene.GetScenePresence(client.AgentId); |
153 | 153 | ||
154 | // Round up Z co-ordinate rather than round-down by casting. This stops tall avatars from being given | ||
155 | // a teleport Z co-ordinate by short avatars that drops them through or embeds them in thin floors on | ||
156 | // arrival. | ||
157 | // | ||
158 | // Ideally we would give the exact float position adjusting for the relative height of the two avatars | ||
159 | // but it looks like a float component isn't possible with a parcel ID. | ||
154 | UUID dest = Util.BuildFakeParcelID( | 160 | UUID dest = Util.BuildFakeParcelID( |
155 | scene.RegionInfo.RegionHandle, | 161 | scene.RegionInfo.RegionHandle, |
156 | (uint)presence.AbsolutePosition.X, | 162 | (uint)presence.AbsolutePosition.X, |
diff --git a/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs index 8101ca2..87ca327 100644 --- a/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs | |||
@@ -57,14 +57,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Profile | |||
57 | 57 | ||
58 | public void Initialise(IConfigSource config) | 58 | public void Initialise(IConfigSource config) |
59 | { | 59 | { |
60 | // This can be reduced later as the loader will determine | ||
61 | // whether we are needed | ||
62 | if (config.Configs["Profile"] != null) | ||
63 | { | ||
64 | if (config.Configs["Profile"].GetString("Module", string.Empty) != "BasicProfileModule") | ||
65 | return; | ||
66 | } | ||
67 | |||
68 | m_log.DebugFormat("[PROFILE MODULE]: Basic Profile Module enabled"); | 60 | m_log.DebugFormat("[PROFILE MODULE]: Basic Profile Module enabled"); |
69 | m_Enabled = true; | 61 | m_Enabled = true; |
70 | } | 62 | } |
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 2b790f4..560f807 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | |||
@@ -30,7 +30,6 @@ using System.Collections.Generic; | |||
30 | using System.Net; | 30 | using System.Net; |
31 | using System.Reflection; | 31 | using System.Reflection; |
32 | using System.Threading; | 32 | using System.Threading; |
33 | |||
34 | using OpenSim.Framework; | 33 | using OpenSim.Framework; |
35 | using OpenSim.Framework.Capabilities; | 34 | using OpenSim.Framework.Capabilities; |
36 | using OpenSim.Framework.Client; | 35 | using OpenSim.Framework.Client; |
@@ -47,29 +46,39 @@ using Nini.Config; | |||
47 | 46 | ||
48 | namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | 47 | namespace OpenSim.Region.CoreModules.Framework.EntityTransfer |
49 | { | 48 | { |
50 | public class EntityTransferModule : ISharedRegionModule, IEntityTransferModule | 49 | public class EntityTransferModule : INonSharedRegionModule, IEntityTransferModule |
51 | { | 50 | { |
52 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 51 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
53 | 52 | ||
53 | public const int DefaultMaxTransferDistance = 4095; | ||
54 | public const bool WaitForAgentArrivedAtDestinationDefault = true; | ||
55 | |||
54 | /// <summary> | 56 | /// <summary> |
55 | /// The maximum distance, in standard region units (256m) that an agent is allowed to transfer. | 57 | /// The maximum distance, in standard region units (256m) that an agent is allowed to transfer. |
56 | /// </summary> | 58 | /// </summary> |
57 | private int m_MaxTransferDistance = 4095; | 59 | public int MaxTransferDistance { get; set; } |
58 | public int MaxTransferDistance | ||
59 | { | ||
60 | get { return m_MaxTransferDistance; } | ||
61 | set { m_MaxTransferDistance = value; } | ||
62 | } | ||
63 | 60 | ||
64 | private int m_levelHGTeleport = 0; | 61 | /// <summary> |
62 | /// If true then on a teleport, the source region waits for a callback from the destination region. If | ||
63 | /// a callback fails to arrive within a set time then the user is pulled back into the source region. | ||
64 | /// </summary> | ||
65 | public bool WaitForAgentArrivedAtDestination { get; set; } | ||
65 | 66 | ||
66 | protected bool m_Enabled = false; | 67 | protected bool m_Enabled = false; |
67 | protected Scene m_aScene; | 68 | |
68 | protected List<Scene> m_Scenes = new List<Scene>(); | 69 | public Scene Scene { get; private set; } |
69 | protected List<UUID> m_agentsInTransit; | 70 | |
71 | /// <summary> | ||
72 | /// Handles recording and manipulation of state for entities that are in transfer within or between regions | ||
73 | /// (cross or teleport). | ||
74 | /// </summary> | ||
75 | private EntityTransferStateMachine m_entityTransferStateMachine; | ||
76 | |||
70 | private ExpiringCache<UUID, ExpiringCache<ulong, DateTime>> m_bannedRegions = | 77 | private ExpiringCache<UUID, ExpiringCache<ulong, DateTime>> m_bannedRegions = |
71 | new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>(); | 78 | new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>(); |
72 | 79 | ||
80 | private IEventQueue m_eqModule; | ||
81 | |||
73 | #region ISharedRegionModule | 82 | #region ISharedRegionModule |
74 | 83 | ||
75 | public Type ReplaceableInterface | 84 | public Type ReplaceableInterface |
@@ -105,11 +114,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
105 | IConfig transferConfig = source.Configs["EntityTransfer"]; | 114 | IConfig transferConfig = source.Configs["EntityTransfer"]; |
106 | if (transferConfig != null) | 115 | if (transferConfig != null) |
107 | { | 116 | { |
108 | MaxTransferDistance = transferConfig.GetInt("max_distance", 4095); | 117 | WaitForAgentArrivedAtDestination |
109 | m_levelHGTeleport = transferConfig.GetInt("LevelHGTeleport", 0); | 118 | = transferConfig.GetBoolean("wait_for_callback", WaitForAgentArrivedAtDestinationDefault); |
119 | |||
120 | MaxTransferDistance = transferConfig.GetInt("max_distance", DefaultMaxTransferDistance); | ||
121 | } | ||
122 | else | ||
123 | { | ||
124 | MaxTransferDistance = DefaultMaxTransferDistance; | ||
110 | } | 125 | } |
111 | 126 | ||
112 | m_agentsInTransit = new List<UUID>(); | 127 | m_entityTransferStateMachine = new EntityTransferStateMachine(this); |
128 | |||
113 | m_Enabled = true; | 129 | m_Enabled = true; |
114 | } | 130 | } |
115 | 131 | ||
@@ -122,10 +138,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
122 | if (!m_Enabled) | 138 | if (!m_Enabled) |
123 | return; | 139 | return; |
124 | 140 | ||
125 | if (m_aScene == null) | 141 | Scene = scene; |
126 | m_aScene = scene; | ||
127 | 142 | ||
128 | m_Scenes.Add(scene); | ||
129 | scene.RegisterModuleInterface<IEntityTransferModule>(this); | 143 | scene.RegisterModuleInterface<IEntityTransferModule>(this); |
130 | scene.EventManager.OnNewClient += OnNewClient; | 144 | scene.EventManager.OnNewClient += OnNewClient; |
131 | } | 145 | } |
@@ -136,26 +150,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
136 | client.OnTeleportLandmarkRequest += RequestTeleportLandmark; | 150 | client.OnTeleportLandmarkRequest += RequestTeleportLandmark; |
137 | } | 151 | } |
138 | 152 | ||
139 | public virtual void Close() | 153 | public virtual void Close() {} |
140 | { | ||
141 | if (!m_Enabled) | ||
142 | return; | ||
143 | } | ||
144 | 154 | ||
145 | public virtual void RemoveRegion(Scene scene) | 155 | public virtual void RemoveRegion(Scene scene) {} |
146 | { | ||
147 | if (!m_Enabled) | ||
148 | return; | ||
149 | if (scene == m_aScene) | ||
150 | m_aScene = null; | ||
151 | |||
152 | m_Scenes.Remove(scene); | ||
153 | } | ||
154 | 156 | ||
155 | public virtual void RegionLoaded(Scene scene) | 157 | public virtual void RegionLoaded(Scene scene) |
156 | { | 158 | { |
157 | if (!m_Enabled) | 159 | if (!m_Enabled) |
158 | return; | 160 | return; |
161 | |||
162 | m_eqModule = Scene.RequestModuleInterface<IEventQueue>(); | ||
159 | } | 163 | } |
160 | 164 | ||
161 | #endregion | 165 | #endregion |
@@ -164,170 +168,257 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
164 | 168 | ||
165 | public void Teleport(ScenePresence sp, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags) | 169 | public void Teleport(ScenePresence sp, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags) |
166 | { | 170 | { |
171 | if (sp.Scene.Permissions.IsGridGod(sp.UUID)) | ||
172 | { | ||
173 | // This user will be a God in the destination scene, too | ||
174 | teleportFlags |= (uint)TeleportFlags.Godlike; | ||
175 | } | ||
176 | |||
167 | if (!sp.Scene.Permissions.CanTeleport(sp.UUID)) | 177 | if (!sp.Scene.Permissions.CanTeleport(sp.UUID)) |
168 | return; | 178 | return; |
169 | 179 | ||
170 | IEventQueue eq = sp.Scene.RequestModuleInterface<IEventQueue>(); | ||
171 | |||
172 | // Reset animations; the viewer does that in teleports. | 180 | // Reset animations; the viewer does that in teleports. |
173 | sp.Animator.ResetAnimations(); | 181 | sp.Animator.ResetAnimations(); |
174 | 182 | ||
183 | string destinationRegionName = "(not found)"; | ||
184 | |||
175 | try | 185 | try |
176 | { | 186 | { |
177 | if (regionHandle == sp.Scene.RegionInfo.RegionHandle) | 187 | if (regionHandle == sp.Scene.RegionInfo.RegionHandle) |
178 | { | 188 | { |
179 | m_log.DebugFormat( | 189 | destinationRegionName = sp.Scene.RegionInfo.RegionName; |
180 | "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation {0} within {1}", | ||
181 | position, sp.Scene.RegionInfo.RegionName); | ||
182 | 190 | ||
183 | // Teleport within the same region | 191 | TeleportAgentWithinRegion(sp, position, lookAt, teleportFlags); |
184 | if (IsOutsideRegion(sp.Scene, position) || position.Z < 0) | 192 | } |
185 | { | 193 | else // Another region possibly in another simulator |
186 | Vector3 emergencyPos = new Vector3(128, 128, 128); | 194 | { |
195 | GridRegion finalDestination; | ||
196 | TeleportAgentToDifferentRegion( | ||
197 | sp, regionHandle, position, lookAt, teleportFlags, out finalDestination); | ||
187 | 198 | ||
188 | m_log.WarnFormat( | 199 | if (finalDestination != null) |
189 | "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", | 200 | destinationRegionName = finalDestination.RegionName; |
190 | position, sp.Name, sp.UUID, emergencyPos); | 201 | } |
191 | position = emergencyPos; | 202 | } |
192 | } | 203 | catch (Exception e) |
204 | { | ||
205 | m_log.ErrorFormat( | ||
206 | "[ENTITY TRANSFER MODULE]: Exception on teleport of {0} from {1}@{2} to {3}@{4}: {5}{6}", | ||
207 | sp.Name, sp.AbsolutePosition, sp.Scene.RegionInfo.RegionName, position, destinationRegionName, | ||
208 | e.Message, e.StackTrace); | ||
193 | 209 | ||
194 | // TODO: Get proper AVG Height | 210 | // Make sure that we clear the in-transit flag so that future teleport attempts don't always fail. |
195 | float localAVHeight = 1.56f; | 211 | m_entityTransferStateMachine.ResetFromTransit(sp.UUID); |
196 | float posZLimit = 22; | ||
197 | 212 | ||
198 | // TODO: Check other Scene HeightField | 213 | sp.ControllingClient.SendTeleportFailed("Internal error"); |
199 | if (position.X > 0 && position.X <= (int)Constants.RegionSize && position.Y > 0 && position.Y <= (int)Constants.RegionSize) | 214 | } |
200 | { | 215 | } |
201 | posZLimit = (float)sp.Scene.Heightmap[(int)position.X, (int)position.Y]; | ||
202 | } | ||
203 | 216 | ||
204 | float newPosZ = posZLimit + localAVHeight; | 217 | /// <summary> |
205 | if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) | 218 | /// Teleports the agent within its current region. |
206 | { | 219 | /// </summary> |
207 | position.Z = newPosZ; | 220 | /// <param name="sp"></param> |
208 | } | 221 | /// <param name="position"></param> |
222 | /// <param name="lookAt"></param> | ||
223 | /// <param name="teleportFlags"></param | ||
224 | private void TeleportAgentWithinRegion(ScenePresence sp, Vector3 position, Vector3 lookAt, uint teleportFlags) | ||
225 | { | ||
226 | m_log.DebugFormat( | ||
227 | "[ENTITY TRANSFER MODULE]: Teleport for {0} to {1} within {2}", | ||
228 | sp.Name, position, sp.Scene.RegionInfo.RegionName); | ||
209 | 229 | ||
210 | sp.ControllingClient.SendTeleportStart(teleportFlags); | 230 | if (!m_entityTransferStateMachine.SetInTransit(sp.UUID)) |
231 | { | ||
232 | m_log.DebugFormat( | ||
233 | "[ENTITY TRANSFER MODULE]: Ignoring within region teleport request of {0} {1} to {2} - agent is already in transit.", | ||
234 | sp.Name, sp.UUID, position); | ||
211 | 235 | ||
212 | sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); | 236 | return; |
213 | sp.TeleportFlags = (Constants.TeleportFlags)teleportFlags; | 237 | } |
214 | sp.Teleport(position); | ||
215 | 238 | ||
216 | foreach (SceneObjectGroup grp in sp.GetAttachments()) | 239 | // Teleport within the same region |
217 | { | 240 | if (IsOutsideRegion(sp.Scene, position) || position.Z < 0) |
218 | sp.Scene.EventManager.TriggerOnScriptChangedEvent(grp.LocalId, (uint)Changed.TELEPORT); | 241 | { |
219 | } | 242 | Vector3 emergencyPos = new Vector3(128, 128, 128); |
243 | |||
244 | m_log.WarnFormat( | ||
245 | "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", | ||
246 | position, sp.Name, sp.UUID, emergencyPos); | ||
247 | |||
248 | position = emergencyPos; | ||
249 | } | ||
250 | |||
251 | // TODO: Get proper AVG Height | ||
252 | float localAVHeight = 1.56f; | ||
253 | float posZLimit = 22; | ||
254 | |||
255 | // TODO: Check other Scene HeightField | ||
256 | if (position.X > 0 && position.X <= (int)Constants.RegionSize && position.Y > 0 && position.Y <= (int)Constants.RegionSize) | ||
257 | { | ||
258 | posZLimit = (float)sp.Scene.Heightmap[(int)position.X, (int)position.Y]; | ||
259 | } | ||
260 | |||
261 | float newPosZ = posZLimit + localAVHeight; | ||
262 | if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) | ||
263 | { | ||
264 | position.Z = newPosZ; | ||
265 | } | ||
266 | |||
267 | m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); | ||
268 | |||
269 | sp.ControllingClient.SendTeleportStart(teleportFlags); | ||
270 | |||
271 | sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); | ||
272 | sp.TeleportFlags = (Constants.TeleportFlags)teleportFlags; | ||
273 | sp.Velocity = Vector3.Zero; | ||
274 | sp.Teleport(position); | ||
275 | |||
276 | m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.ReceivedAtDestination); | ||
277 | |||
278 | foreach (SceneObjectGroup grp in sp.GetAttachments()) | ||
279 | { | ||
280 | sp.Scene.EventManager.TriggerOnScriptChangedEvent(grp.LocalId, (uint)Changed.TELEPORT); | ||
281 | } | ||
282 | |||
283 | m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); | ||
284 | m_entityTransferStateMachine.ResetFromTransit(sp.UUID); | ||
285 | } | ||
286 | |||
287 | /// <summary> | ||
288 | /// Teleports the agent to a different region. | ||
289 | /// </summary> | ||
290 | /// <param name='sp'></param> | ||
291 | /// <param name='regionHandle'>/param> | ||
292 | /// <param name='position'></param> | ||
293 | /// <param name='lookAt'></param> | ||
294 | /// <param name='teleportFlags'></param> | ||
295 | /// <param name='finalDestination'></param> | ||
296 | private void TeleportAgentToDifferentRegion( | ||
297 | ScenePresence sp, ulong regionHandle, Vector3 position, | ||
298 | Vector3 lookAt, uint teleportFlags, out GridRegion finalDestination) | ||
299 | { | ||
300 | uint x = 0, y = 0; | ||
301 | Utils.LongToUInts(regionHandle, out x, out y); | ||
302 | GridRegion reg = Scene.GridService.GetRegionByPosition(sp.Scene.RegionInfo.ScopeID, (int)x, (int)y); | ||
303 | |||
304 | if (reg != null) | ||
305 | { | ||
306 | finalDestination = GetFinalDestination(reg); | ||
307 | |||
308 | if (finalDestination == null) | ||
309 | { | ||
310 | m_log.WarnFormat( | ||
311 | "[ENTITY TRANSFER MODULE]: Final destination is having problems. Unable to teleport {0} {1}", | ||
312 | sp.Name, sp.UUID); | ||
313 | |||
314 | sp.ControllingClient.SendTeleportFailed("Problem at destination"); | ||
315 | return; | ||
220 | } | 316 | } |
221 | else // Another region possibly in another simulator | 317 | |
318 | // Check that these are not the same coordinates | ||
319 | if (finalDestination.RegionLocX == sp.Scene.RegionInfo.RegionLocX && | ||
320 | finalDestination.RegionLocY == sp.Scene.RegionInfo.RegionLocY) | ||
222 | { | 321 | { |
223 | uint x = 0, y = 0; | 322 | // Can't do. Viewer crashes |
224 | Utils.LongToUInts(regionHandle, out x, out y); | 323 | sp.ControllingClient.SendTeleportFailed("Space warp! You would crash. Move to a different region and try again."); |
225 | GridRegion reg = m_aScene.GridService.GetRegionByPosition(sp.Scene.RegionInfo.ScopeID, (int)x, (int)y); | 324 | return; |
325 | } | ||
226 | 326 | ||
227 | if (reg != null) | 327 | // |
228 | { | 328 | // This is it |
229 | GridRegion finalDestination = GetFinalDestination(reg); | 329 | // |
230 | if (finalDestination == null) | 330 | DoTeleport(sp, reg, finalDestination, position, lookAt, teleportFlags); |
231 | { | 331 | // |
232 | m_log.WarnFormat("[ENTITY TRANSFER MODULE]: Final destination is having problems. Unable to teleport agent."); | 332 | // |
233 | sp.ControllingClient.SendTeleportFailed("Problem at destination"); | 333 | // |
234 | return; | 334 | } |
235 | } | 335 | else |
336 | { | ||
337 | finalDestination = null; | ||
236 | 338 | ||
237 | // check if HyperGrid teleport is allowed, based on user level | 339 | // TP to a place that doesn't exist (anymore) |
238 | int flags = m_aScene.GridService.GetRegionFlags(sp.Scene.RegionInfo.ScopeID, reg.RegionID); | 340 | // Inform the viewer about that |
341 | sp.ControllingClient.SendTeleportFailed("The region you tried to teleport to doesn't exist anymore"); | ||
239 | 342 | ||
240 | if (((flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) && (sp.UserLevel < m_levelHGTeleport)) | 343 | // and set the map-tile to '(Offline)' |
241 | { | 344 | uint regX, regY; |
242 | m_log.WarnFormat("[ENTITY TRANSFER MODULE]: Final destination link is non permitted hypergrid region. Unable to teleport agent."); | 345 | Utils.LongToUInts(regionHandle, out regX, out regY); |
243 | sp.ControllingClient.SendTeleportFailed("HyperGrid teleport not permitted"); | ||
244 | return; | ||
245 | } | ||
246 | 346 | ||
247 | uint curX = 0, curY = 0; | 347 | MapBlockData block = new MapBlockData(); |
248 | Utils.LongToUInts(sp.Scene.RegionInfo.RegionHandle, out curX, out curY); | 348 | block.X = (ushort)(regX / Constants.RegionSize); |
249 | int curCellX = (int)(curX / Constants.RegionSize); | 349 | block.Y = (ushort)(regY / Constants.RegionSize); |
250 | int curCellY = (int)(curY / Constants.RegionSize); | 350 | block.Access = 254; // == not there |
251 | int destCellX = (int)(finalDestination.RegionLocX / Constants.RegionSize); | ||
252 | int destCellY = (int)(finalDestination.RegionLocY / Constants.RegionSize); | ||
253 | 351 | ||
352 | List<MapBlockData> blocks = new List<MapBlockData>(); | ||
353 | blocks.Add(block); | ||
354 | sp.ControllingClient.SendMapBlock(blocks, 0); | ||
355 | } | ||
356 | } | ||
357 | |||
358 | /// <summary> | ||
359 | /// Determines whether this instance is within the max transfer distance. | ||
360 | /// </summary> | ||
361 | /// <param name="sourceRegion"></param> | ||
362 | /// <param name="destRegion"></param> | ||
363 | /// <returns> | ||
364 | /// <c>true</c> if this instance is within max transfer distance; otherwise, <c>false</c>. | ||
365 | /// </returns> | ||
366 | private bool IsWithinMaxTeleportDistance(RegionInfo sourceRegion, GridRegion destRegion) | ||
367 | { | ||
254 | // m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Source co-ords are x={0} y={1}", curRegionX, curRegionY); | 368 | // m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Source co-ords are x={0} y={1}", curRegionX, curRegionY); |
255 | // | 369 | // |
256 | // m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Final dest is x={0} y={1} {2}@{3}", | 370 | // m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Final dest is x={0} y={1} {2}@{3}", |
257 | // destRegionX, destRegionY, finalDestination.RegionID, finalDestination.ServerURI); | 371 | // destRegionX, destRegionY, finalDestination.RegionID, finalDestination.ServerURI); |
258 | 372 | ||
259 | // Check that these are not the same coordinates | 373 | // Insanely, RegionLoc on RegionInfo is the 256m map co-ord whilst GridRegion.RegionLoc is the raw meters position. |
260 | if (finalDestination.RegionLocX == sp.Scene.RegionInfo.RegionLocX && | 374 | return Math.Abs(sourceRegion.RegionLocX - destRegion.RegionCoordX) <= MaxTransferDistance |
261 | finalDestination.RegionLocY == sp.Scene.RegionInfo.RegionLocY) | 375 | && Math.Abs(sourceRegion.RegionLocY - destRegion.RegionCoordY) <= MaxTransferDistance; |
262 | { | 376 | } |
263 | // Can't do. Viewer crashes | ||
264 | sp.ControllingClient.SendTeleportFailed("Space warp! You would crash. Move to a different region and try again."); | ||
265 | return; | ||
266 | } | ||
267 | |||
268 | if (Math.Abs(curCellX - destCellX) > MaxTransferDistance || Math.Abs(curCellY - destCellY) > MaxTransferDistance) | ||
269 | { | ||
270 | sp.ControllingClient.SendTeleportFailed( | ||
271 | string.Format( | ||
272 | "Can't teleport to {0} ({1},{2}) from {3} ({4},{5}), destination is more than {6} regions way", | ||
273 | finalDestination.RegionName, destCellX, destCellY, | ||
274 | sp.Scene.RegionInfo.RegionName, curCellX, curCellY, | ||
275 | MaxTransferDistance)); | ||
276 | |||
277 | return; | ||
278 | } | ||
279 | 377 | ||
280 | // | 378 | public void DoTeleport( |
281 | // This is it | 379 | ScenePresence sp, GridRegion reg, GridRegion finalDestination, |
282 | // | 380 | Vector3 position, Vector3 lookAt, uint teleportFlags) |
283 | DoTeleport(sp, reg, finalDestination, position, lookAt, teleportFlags, eq); | 381 | { |
284 | // | 382 | // Record that this agent is in transit so that we can prevent simultaneous requests and do later detection |
285 | // | 383 | // of whether the destination region completes the teleport. |
286 | // | 384 | if (!m_entityTransferStateMachine.SetInTransit(sp.UUID)) |
287 | } | ||
288 | else | ||
289 | { | ||
290 | // TP to a place that doesn't exist (anymore) | ||
291 | // Inform the viewer about that | ||
292 | sp.ControllingClient.SendTeleportFailed("The region you tried to teleport to doesn't exist anymore"); | ||
293 | |||
294 | // and set the map-tile to '(Offline)' | ||
295 | uint regX, regY; | ||
296 | Utils.LongToUInts(regionHandle, out regX, out regY); | ||
297 | |||
298 | MapBlockData block = new MapBlockData(); | ||
299 | block.X = (ushort)(regX / Constants.RegionSize); | ||
300 | block.Y = (ushort)(regY / Constants.RegionSize); | ||
301 | block.Access = 254; // == not there | ||
302 | |||
303 | List<MapBlockData> blocks = new List<MapBlockData>(); | ||
304 | blocks.Add(block); | ||
305 | sp.ControllingClient.SendMapBlock(blocks, 0); | ||
306 | } | ||
307 | } | ||
308 | } | ||
309 | catch (Exception e) | ||
310 | { | 385 | { |
311 | m_log.WarnFormat("[ENTITY TRANSFER MODULE]: Exception on teleport: {0} {1}", e.Message, e.StackTrace); | 386 | m_log.DebugFormat( |
312 | sp.ControllingClient.SendTeleportFailed("Internal error"); | 387 | "[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2} ({3}) {4}/{5} - agent is already in transit.", |
388 | sp.Name, sp.UUID, reg.ServerURI, finalDestination.ServerURI, finalDestination.RegionName, position); | ||
389 | |||
390 | return; | ||
313 | } | 391 | } |
314 | } | ||
315 | 392 | ||
316 | public void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags, IEventQueue eq) | ||
317 | { | ||
318 | if (reg == null || finalDestination == null) | 393 | if (reg == null || finalDestination == null) |
319 | { | 394 | { |
320 | sp.ControllingClient.SendTeleportFailed("Unable to locate destination"); | 395 | sp.ControllingClient.SendTeleportFailed("Unable to locate destination"); |
321 | return; | 396 | m_entityTransferStateMachine.ResetFromTransit(sp.UUID); |
322 | } | ||
323 | 397 | ||
324 | if (IsInTransit(sp.UUID)) // Avie is already on the way. Caller shouldn't do this. | ||
325 | return; | 398 | return; |
399 | } | ||
326 | 400 | ||
327 | m_log.DebugFormat( | 401 | m_log.DebugFormat( |
328 | "[ENTITY TRANSFER MODULE]: Request Teleport to {0} ({1}) {2}/{3}", | 402 | "[ENTITY TRANSFER MODULE]: Teleporting {0} {1} from {2} to {3} ({4}) {5}/{6}", |
403 | sp.Name, sp.UUID, sp.Scene.RegionInfo.RegionName, | ||
329 | reg.ServerURI, finalDestination.ServerURI, finalDestination.RegionName, position); | 404 | reg.ServerURI, finalDestination.ServerURI, finalDestination.RegionName, position); |
330 | 405 | ||
406 | RegionInfo sourceRegion = sp.Scene.RegionInfo; | ||
407 | |||
408 | if (!IsWithinMaxTeleportDistance(sourceRegion, finalDestination)) | ||
409 | { | ||
410 | sp.ControllingClient.SendTeleportFailed( | ||
411 | string.Format( | ||
412 | "Can't teleport to {0} ({1},{2}) from {3} ({4},{5}), destination is more than {6} regions way", | ||
413 | finalDestination.RegionName, finalDestination.RegionCoordX, finalDestination.RegionCoordY, | ||
414 | sourceRegion.RegionName, sourceRegion.RegionLocX, sourceRegion.RegionLocY, | ||
415 | MaxTransferDistance)); | ||
416 | |||
417 | m_entityTransferStateMachine.ResetFromTransit(sp.UUID); | ||
418 | |||
419 | return; | ||
420 | } | ||
421 | |||
331 | uint newRegionX = (uint)(reg.RegionHandle >> 40); | 422 | uint newRegionX = (uint)(reg.RegionHandle >> 40); |
332 | uint newRegionY = (((uint)(reg.RegionHandle)) >> 8); | 423 | uint newRegionY = (((uint)(reg.RegionHandle)) >> 8); |
333 | uint oldRegionX = (uint)(sp.Scene.RegionInfo.RegionHandle >> 40); | 424 | uint oldRegionX = (uint)(sp.Scene.RegionInfo.RegionHandle >> 40); |
@@ -339,17 +430,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
339 | // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, | 430 | // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, |
340 | // it's actually doing a lot of work. | 431 | // it's actually doing a lot of work. |
341 | IPEndPoint endPoint = finalDestination.ExternalEndPoint; | 432 | IPEndPoint endPoint = finalDestination.ExternalEndPoint; |
342 | if (endPoint != null && endPoint.Address != null) | 433 | if (endPoint == null || endPoint.Address == null) |
343 | { | 434 | { |
344 | // Fixing a bug where teleporting while sitting results in the avatar ending up removed from | 435 | sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); |
345 | // both regions | 436 | m_entityTransferStateMachine.ResetFromTransit(sp.UUID); |
346 | if (sp.ParentID != (uint)0) | ||
347 | sp.StandUp(); | ||
348 | 437 | ||
349 | if (!sp.ValidateAttachments()) | 438 | return; |
350 | m_log.DebugFormat( | 439 | } |
351 | "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.", | 440 | |
352 | sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName); | 441 | if (!sp.ValidateAttachments()) |
442 | m_log.DebugFormat( | ||
443 | "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.", | ||
444 | sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName); | ||
353 | 445 | ||
354 | // if (!sp.ValidateAttachments()) | 446 | // if (!sp.ValidateAttachments()) |
355 | // { | 447 | // { |
@@ -357,218 +449,245 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
357 | // return; | 449 | // return; |
358 | // } | 450 | // } |
359 | 451 | ||
360 | string reason; | 452 | string reason; |
361 | string version; | 453 | string version; |
362 | if (!m_aScene.SimulationService.QueryAccess(finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out version, out reason)) | 454 | if (!Scene.SimulationService.QueryAccess( |
363 | { | 455 | finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out version, out reason)) |
364 | sp.ControllingClient.SendTeleportFailed("Teleport failed: " + reason); | 456 | { |
365 | return; | 457 | sp.ControllingClient.SendTeleportFailed(reason); |
366 | } | 458 | m_entityTransferStateMachine.ResetFromTransit(sp.UUID); |
367 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version); | ||
368 | |||
369 | sp.ControllingClient.SendTeleportStart(teleportFlags); | ||
370 | |||
371 | // the avatar.Close below will clear the child region list. We need this below for (possibly) | ||
372 | // closing the child agents, so save it here (we need a copy as it is Clear()-ed). | ||
373 | //List<ulong> childRegions = avatar.KnownRegionHandles; | ||
374 | // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport | ||
375 | // failure at this point (unlike a border crossing failure). So perhaps this can never fail | ||
376 | // once we reach here... | ||
377 | //avatar.Scene.RemoveCapsHandler(avatar.UUID); | ||
378 | |||
379 | string capsPath = String.Empty; | ||
380 | |||
381 | AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); | ||
382 | AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo(); | ||
383 | agentCircuit.startpos = position; | ||
384 | agentCircuit.child = true; | ||
385 | agentCircuit.Appearance = sp.Appearance; | ||
386 | if (currentAgentCircuit != null) | ||
387 | { | ||
388 | agentCircuit.ServiceURLs = currentAgentCircuit.ServiceURLs; | ||
389 | agentCircuit.IPAddress = currentAgentCircuit.IPAddress; | ||
390 | agentCircuit.Viewer = currentAgentCircuit.Viewer; | ||
391 | agentCircuit.Channel = currentAgentCircuit.Channel; | ||
392 | agentCircuit.Mac = currentAgentCircuit.Mac; | ||
393 | agentCircuit.Id0 = currentAgentCircuit.Id0; | ||
394 | } | ||
395 | 459 | ||
396 | if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) | 460 | m_log.DebugFormat( |
397 | { | 461 | "[ENTITY TRANSFER MODULE]: {0} was stopped from teleporting from {1} to {2} because {3}", |
398 | // brand new agent, let's create a new caps seed | 462 | sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason); |
399 | agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); | ||
400 | } | ||
401 | 463 | ||
402 | // Let's create an agent there if one doesn't exist yet. | 464 | return; |
403 | bool logout = false; | 465 | } |
404 | if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout)) | ||
405 | { | ||
406 | sp.ControllingClient.SendTeleportFailed(String.Format("Destination refused: {0}", | ||
407 | reason)); | ||
408 | return; | ||
409 | } | ||
410 | 466 | ||
411 | // OK, it got this agent. Let's close some child agents | 467 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version); |
412 | sp.CloseChildAgents(newRegionX, newRegionY); | ||
413 | IClientIPEndpoint ipepClient; | ||
414 | if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) | ||
415 | { | ||
416 | //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent..."); | ||
417 | #region IP Translation for NAT | ||
418 | // Uses ipepClient above | ||
419 | if (sp.ClientView.TryGet(out ipepClient)) | ||
420 | { | ||
421 | endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); | ||
422 | } | ||
423 | #endregion | ||
424 | capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); | ||
425 | 468 | ||
426 | if (eq != null) | 469 | // Fixing a bug where teleporting while sitting results in the avatar ending up removed from |
427 | { | 470 | // both regions |
428 | eq.EnableSimulator(destinationHandle, endPoint, sp.UUID); | 471 | if (sp.ParentID != (uint)0) |
472 | sp.StandUp(); | ||
429 | 473 | ||
430 | // ES makes the client send a UseCircuitCode message to the destination, | 474 | sp.ControllingClient.SendTeleportStart(teleportFlags); |
431 | // which triggers a bunch of things there. | ||
432 | // So let's wait | ||
433 | Thread.Sleep(200); | ||
434 | 475 | ||
435 | eq.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); | 476 | // the avatar.Close below will clear the child region list. We need this below for (possibly) |
477 | // closing the child agents, so save it here (we need a copy as it is Clear()-ed). | ||
478 | //List<ulong> childRegions = avatar.KnownRegionHandles; | ||
479 | // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport | ||
480 | // failure at this point (unlike a border crossing failure). So perhaps this can never fail | ||
481 | // once we reach here... | ||
482 | //avatar.Scene.RemoveCapsHandler(avatar.UUID); | ||
436 | 483 | ||
437 | } | 484 | string capsPath = String.Empty; |
438 | else | ||
439 | { | ||
440 | sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint); | ||
441 | } | ||
442 | } | ||
443 | else | ||
444 | { | ||
445 | agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle); | ||
446 | capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); | ||
447 | } | ||
448 | 485 | ||
486 | AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); | ||
487 | AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo(); | ||
488 | agentCircuit.startpos = position; | ||
489 | agentCircuit.child = true; | ||
490 | agentCircuit.Appearance = sp.Appearance; | ||
491 | if (currentAgentCircuit != null) | ||
492 | { | ||
493 | agentCircuit.ServiceURLs = currentAgentCircuit.ServiceURLs; | ||
494 | agentCircuit.IPAddress = currentAgentCircuit.IPAddress; | ||
495 | agentCircuit.Viewer = currentAgentCircuit.Viewer; | ||
496 | agentCircuit.Channel = currentAgentCircuit.Channel; | ||
497 | agentCircuit.Mac = currentAgentCircuit.Mac; | ||
498 | agentCircuit.Id0 = currentAgentCircuit.Id0; | ||
499 | } | ||
449 | 500 | ||
450 | SetInTransit(sp.UUID); | 501 | if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) |
502 | { | ||
503 | // brand new agent, let's create a new caps seed | ||
504 | agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); | ||
505 | } | ||
451 | 506 | ||
452 | // Let's send a full update of the agent. This is a synchronous call. | 507 | // Let's create an agent there if one doesn't exist yet. |
453 | AgentData agent = new AgentData(); | 508 | bool logout = false; |
454 | sp.CopyTo(agent); | 509 | if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout)) |
455 | agent.Position = position; | 510 | { |
456 | SetCallbackURL(agent, sp.Scene.RegionInfo); | 511 | sp.ControllingClient.SendTeleportFailed(String.Format("Teleport refused: {0}", reason)); |
512 | m_entityTransferStateMachine.ResetFromTransit(sp.UUID); | ||
457 | 513 | ||
458 | //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent..."); | 514 | m_log.DebugFormat( |
515 | "[ENTITY TRANSFER MODULE]: Teleport of {0} from {1} to {2} was refused because {3}", | ||
516 | sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason); | ||
459 | 517 | ||
460 | if (!UpdateAgent(reg, finalDestination, agent)) | 518 | return; |
519 | } | ||
520 | |||
521 | // Past this point we have to attempt clean up if the teleport fails, so update transfer state. | ||
522 | m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); | ||
523 | |||
524 | // OK, it got this agent. Let's close some child agents | ||
525 | sp.CloseChildAgents(newRegionX, newRegionY); | ||
526 | |||
527 | IClientIPEndpoint ipepClient; | ||
528 | if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) | ||
529 | { | ||
530 | //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent..."); | ||
531 | #region IP Translation for NAT | ||
532 | // Uses ipepClient above | ||
533 | if (sp.ClientView.TryGet(out ipepClient)) | ||
461 | { | 534 | { |
462 | // Region doesn't take it | 535 | endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); |
463 | m_log.WarnFormat( | ||
464 | "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1}. Returning avatar to source region.", | ||
465 | sp.Name, finalDestination.RegionName); | ||
466 | |||
467 | Fail(sp, finalDestination, logout); | ||
468 | return; | ||
469 | } | 536 | } |
537 | #endregion | ||
538 | capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); | ||
470 | 539 | ||
471 | sp.ControllingClient.SendTeleportProgress(teleportFlags | (uint)TeleportFlags.DisableCancel, "sending_dest"); | 540 | if (m_eqModule != null) |
541 | { | ||
542 | m_eqModule.EnableSimulator(destinationHandle, endPoint, sp.UUID); | ||
472 | 543 | ||
473 | m_log.DebugFormat( | 544 | // ES makes the client send a UseCircuitCode message to the destination, |
474 | "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, sp.UUID); | 545 | // which triggers a bunch of things there. |
546 | // So let's wait | ||
547 | Thread.Sleep(200); | ||
548 | |||
549 | m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); | ||
475 | 550 | ||
476 | if (eq != null) | ||
477 | { | ||
478 | eq.TeleportFinishEvent(destinationHandle, 13, endPoint, | ||
479 | 0, teleportFlags, capsPath, sp.UUID); | ||
480 | } | 551 | } |
481 | else | 552 | else |
482 | { | 553 | { |
483 | sp.ControllingClient.SendRegionTeleport(destinationHandle, 13, endPoint, 4, | 554 | sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint); |
484 | teleportFlags, capsPath); | ||
485 | } | 555 | } |
556 | } | ||
557 | else | ||
558 | { | ||
559 | agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle); | ||
560 | capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); | ||
561 | } | ||
486 | 562 | ||
487 | // Let's set this to true tentatively. This does not trigger OnChildAgent | 563 | // Let's send a full update of the agent. This is a synchronous call. |
488 | sp.IsChildAgent = true; | 564 | AgentData agent = new AgentData(); |
565 | sp.CopyTo(agent); | ||
566 | agent.Position = position; | ||
567 | SetCallbackURL(agent, sp.Scene.RegionInfo); | ||
489 | 568 | ||
490 | // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which | 569 | //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent..."); |
491 | // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation | ||
492 | // that the client contacted the destination before we close things here. | ||
493 | if (!WaitForCallback(sp.UUID)) | ||
494 | { | ||
495 | m_log.WarnFormat( | ||
496 | "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} failed due to no callback from destination region. Returning avatar to source region.", | ||
497 | sp.Name, finalDestination.RegionName); | ||
498 | |||
499 | Fail(sp, finalDestination, logout); | ||
500 | return; | ||
501 | } | ||
502 | 570 | ||
503 | // For backwards compatibility | 571 | if (!UpdateAgent(reg, finalDestination, agent)) |
504 | if (version == "Unknown" || version == string.Empty) | 572 | { |
505 | { | 573 | // Region doesn't take it |
506 | // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it | 574 | m_log.WarnFormat( |
507 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Old simulator, sending attachments one by one..."); | 575 | "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Returning avatar to source region.", |
508 | CrossAttachmentsIntoNewRegion(finalDestination, sp, true); | 576 | sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); |
509 | } | 577 | |
578 | Fail(sp, finalDestination, logout); | ||
579 | return; | ||
580 | } | ||
510 | 581 | ||
511 | // May need to logout or other cleanup | 582 | sp.ControllingClient.SendTeleportProgress(teleportFlags | (uint)TeleportFlags.DisableCancel, "sending_dest"); |
512 | AgentHasMovedAway(sp, logout); | ||
513 | 583 | ||
514 | // Well, this is it. The agent is over there. | 584 | m_log.DebugFormat( |
515 | KillEntity(sp.Scene, sp.LocalId); | 585 | "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} from {1} to {2}", |
586 | capsPath, sp.Scene.RegionInfo.RegionName, sp.Name); | ||
516 | 587 | ||
517 | // Now let's make it officially a child agent | 588 | if (m_eqModule != null) |
518 | sp.MakeChildAgent(); | 589 | { |
590 | m_eqModule.TeleportFinishEvent(destinationHandle, 13, endPoint, 0, teleportFlags, capsPath, sp.UUID); | ||
591 | } | ||
592 | else | ||
593 | { | ||
594 | sp.ControllingClient.SendRegionTeleport(destinationHandle, 13, endPoint, 4, | ||
595 | teleportFlags, capsPath); | ||
596 | } | ||
519 | 597 | ||
520 | // sp.Scene.CleanDroppedAttachments(); | 598 | // Let's set this to true tentatively. This does not trigger OnChildAgent |
599 | sp.IsChildAgent = true; | ||
600 | |||
601 | // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which | ||
602 | // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation | ||
603 | // that the client contacted the destination before we close things here. | ||
604 | if (!m_entityTransferStateMachine.WaitForAgentArrivedAtDestination(sp.UUID)) | ||
605 | { | ||
606 | m_log.WarnFormat( | ||
607 | "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.", | ||
608 | sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); | ||
609 | |||
610 | Fail(sp, finalDestination, logout); | ||
611 | return; | ||
612 | } | ||
521 | 613 | ||
522 | // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone | 614 | m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); |
523 | 615 | ||
524 | if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) | 616 | // For backwards compatibility |
525 | { | 617 | if (version == "Unknown" || version == string.Empty) |
526 | Thread.Sleep(5000); | 618 | { |
527 | sp.Close(); | 619 | // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it |
528 | sp.Scene.IncomingCloseAgent(sp.UUID); | 620 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Old simulator, sending attachments one by one..."); |
529 | } | 621 | CrossAttachmentsIntoNewRegion(finalDestination, sp, true); |
530 | else | 622 | } |
531 | { | ||
532 | // now we have a child agent in this region. | ||
533 | sp.Reset(); | ||
534 | } | ||
535 | 623 | ||
536 | // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! | 624 | // May need to logout or other cleanup |
537 | if (sp.Scene.NeedSceneCacheClear(sp.UUID)) | 625 | AgentHasMovedAway(sp, logout); |
538 | { | 626 | |
539 | m_log.DebugFormat( | 627 | // Well, this is it. The agent is over there. |
540 | "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed", | 628 | KillEntity(sp.Scene, sp.LocalId); |
541 | sp.UUID); | 629 | |
542 | } | 630 | // Now let's make it officially a child agent |
631 | sp.MakeChildAgent(); | ||
632 | |||
633 | // sp.Scene.CleanDroppedAttachments(); | ||
634 | |||
635 | // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone | ||
636 | |||
637 | if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) | ||
638 | { | ||
639 | // We need to delay here because Imprudence viewers, unlike v1 or v3, have a short (<200ms, <500ms) delay before | ||
640 | // they regard the new region as the current region after receiving the AgentMovementComplete | ||
641 | // response. If close is sent before then, it will cause the viewer to quit instead. | ||
642 | // | ||
643 | // This sleep can be increased if necessary. However, whilst it's active, | ||
644 | // an agent cannot teleport back to this region if it has teleported away. | ||
645 | Thread.Sleep(2000); | ||
646 | |||
647 | sp.Scene.IncomingCloseAgent(sp.UUID); | ||
543 | } | 648 | } |
544 | else | 649 | else |
545 | { | 650 | { |
546 | sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); | 651 | // now we have a child agent in this region. |
652 | sp.Reset(); | ||
547 | } | 653 | } |
654 | |||
655 | // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! | ||
656 | if (sp.Scene.NeedSceneCacheClear(sp.UUID)) | ||
657 | { | ||
658 | m_log.DebugFormat( | ||
659 | "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed", | ||
660 | sp.UUID); | ||
661 | } | ||
662 | |||
663 | m_entityTransferStateMachine.ResetFromTransit(sp.UUID); | ||
548 | } | 664 | } |
549 | 665 | ||
550 | protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout) | 666 | protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout) |
551 | { | 667 | { |
668 | m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); | ||
669 | |||
552 | // Client never contacted destination. Let's restore everything back | 670 | // Client never contacted destination. Let's restore everything back |
553 | sp.ControllingClient.SendTeleportFailed("Problems connecting to destination."); | 671 | sp.ControllingClient.SendTeleportFailed("Problems connecting to destination."); |
554 | 672 | ||
555 | // Fail. Reset it back | 673 | // Fail. Reset it back |
556 | sp.IsChildAgent = false; | 674 | sp.IsChildAgent = false; |
557 | ReInstantiateScripts(sp); | 675 | ReInstantiateScripts(sp); |
558 | ResetFromTransit(sp.UUID); | ||
559 | 676 | ||
560 | EnableChildAgents(sp); | 677 | EnableChildAgents(sp); |
561 | 678 | ||
562 | // Finally, kill the agent we just created at the destination. | 679 | // Finally, kill the agent we just created at the destination. |
563 | m_aScene.SimulationService.CloseAgent(finalDestination, sp.UUID); | 680 | Scene.SimulationService.CloseAgent(finalDestination, sp.UUID); |
564 | 681 | ||
565 | sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout); | 682 | sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout); |
683 | |||
684 | m_entityTransferStateMachine.ResetFromTransit(sp.UUID); | ||
566 | } | 685 | } |
567 | 686 | ||
568 | protected virtual bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout) | 687 | protected virtual bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout) |
569 | { | 688 | { |
570 | logout = false; | 689 | logout = false; |
571 | bool success = m_aScene.SimulationService.CreateAgent(finalDestination, agentCircuit, teleportFlags, out reason); | 690 | bool success = Scene.SimulationService.CreateAgent(finalDestination, agentCircuit, teleportFlags, out reason); |
572 | 691 | ||
573 | if (success) | 692 | if (success) |
574 | sp.Scene.EventManager.TriggerTeleportStart(sp.ControllingClient, reg, finalDestination, teleportFlags, logout); | 693 | sp.Scene.EventManager.TriggerTeleportStart(sp.ControllingClient, reg, finalDestination, teleportFlags, logout); |
@@ -578,19 +697,27 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
578 | 697 | ||
579 | protected virtual bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agent) | 698 | protected virtual bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agent) |
580 | { | 699 | { |
581 | return m_aScene.SimulationService.UpdateAgent(finalDestination, agent); | 700 | return Scene.SimulationService.UpdateAgent(finalDestination, agent); |
582 | } | 701 | } |
583 | 702 | ||
584 | protected virtual void SetCallbackURL(AgentData agent, RegionInfo region) | 703 | protected virtual void SetCallbackURL(AgentData agent, RegionInfo region) |
585 | { | 704 | { |
586 | agent.CallbackURI = region.ServerURI + "agent/" + agent.AgentID.ToString() + "/" + region.RegionID.ToString() + "/release/"; | 705 | agent.CallbackURI = region.ServerURI + "agent/" + agent.AgentID.ToString() + "/" + region.RegionID.ToString() + "/release/"; |
587 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Set callback URL to {0}", agent.CallbackURI); | ||
588 | 706 | ||
707 | m_log.DebugFormat( | ||
708 | "[ENTITY TRANSFER MODULE]: Set release callback URL to {0} in {1}", | ||
709 | agent.CallbackURI, region.RegionName); | ||
589 | } | 710 | } |
590 | 711 | ||
712 | /// <summary> | ||
713 | /// Clean up operations once an agent has moved away through cross or teleport. | ||
714 | /// </summary> | ||
715 | /// <param name='sp'></param> | ||
716 | /// <param name='logout'></param> | ||
591 | protected virtual void AgentHasMovedAway(ScenePresence sp, bool logout) | 717 | protected virtual void AgentHasMovedAway(ScenePresence sp, bool logout) |
592 | { | 718 | { |
593 | sp.Scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, true); | 719 | if (sp.Scene.AttachmentsModule != null) |
720 | sp.Scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, true); | ||
594 | } | 721 | } |
595 | 722 | ||
596 | protected void KillEntity(Scene scene, uint localID) | 723 | protected void KillEntity(Scene scene, uint localID) |
@@ -615,7 +742,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
615 | 742 | ||
616 | protected virtual bool IsOutsideRegion(Scene s, Vector3 pos) | 743 | protected virtual bool IsOutsideRegion(Scene s, Vector3 pos) |
617 | { | 744 | { |
618 | |||
619 | if (s.TestBorderCross(pos, Cardinals.N)) | 745 | if (s.TestBorderCross(pos, Cardinals.N)) |
620 | return true; | 746 | return true; |
621 | if (s.TestBorderCross(pos, Cardinals.S)) | 747 | if (s.TestBorderCross(pos, Cardinals.S)) |
@@ -628,7 +754,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
628 | return false; | 754 | return false; |
629 | } | 755 | } |
630 | 756 | ||
631 | |||
632 | #endregion | 757 | #endregion |
633 | 758 | ||
634 | #region Landmark Teleport | 759 | #region Landmark Teleport |
@@ -640,7 +765,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
640 | /// <param name="position"></param> | 765 | /// <param name="position"></param> |
641 | public virtual void RequestTeleportLandmark(IClientAPI remoteClient, AssetLandmark lm) | 766 | public virtual void RequestTeleportLandmark(IClientAPI remoteClient, AssetLandmark lm) |
642 | { | 767 | { |
643 | GridRegion info = m_aScene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID); | 768 | GridRegion info = Scene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID); |
644 | 769 | ||
645 | if (info == null) | 770 | if (info == null) |
646 | { | 771 | { |
@@ -663,10 +788,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
663 | 788 | ||
664 | public virtual bool TeleportHome(UUID id, IClientAPI client) | 789 | public virtual bool TeleportHome(UUID id, IClientAPI client) |
665 | { | 790 | { |
666 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.FirstName, client.LastName); | 791 | m_log.DebugFormat( |
792 | "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId); | ||
667 | 793 | ||
668 | //OpenSim.Services.Interfaces.PresenceInfo pinfo = m_aScene.PresenceService.GetAgent(client.SessionId); | 794 | //OpenSim.Services.Interfaces.PresenceInfo pinfo = Scene.PresenceService.GetAgent(client.SessionId); |
669 | GridUserInfo uinfo = m_aScene.GridUserService.GetGridUserInfo(client.AgentId.ToString()); | 795 | GridUserInfo uinfo = Scene.GridUserService.GetGridUserInfo(client.AgentId.ToString()); |
670 | 796 | ||
671 | if (uinfo != null) | 797 | if (uinfo != null) |
672 | { | 798 | { |
@@ -676,7 +802,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
676 | client.SendTeleportFailed("You don't have a home position set."); | 802 | client.SendTeleportFailed("You don't have a home position set."); |
677 | return false; | 803 | return false; |
678 | } | 804 | } |
679 | GridRegion regionInfo = m_aScene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID); | 805 | GridRegion regionInfo = Scene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID); |
680 | if (regionInfo == null) | 806 | if (regionInfo == null) |
681 | { | 807 | { |
682 | // can't find the Home region: Tell viewer and abort | 808 | // can't find the Home region: Tell viewer and abort |
@@ -684,8 +810,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
684 | return false; | 810 | return false; |
685 | } | 811 | } |
686 | 812 | ||
687 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: User's home region is {0} {1} ({2}-{3})", | 813 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Home region of {0} is {1} ({2}-{3})", |
688 | regionInfo.RegionName, regionInfo.RegionID, regionInfo.RegionLocX / Constants.RegionSize, regionInfo.RegionLocY / Constants.RegionSize); | 814 | client.Name, regionInfo.RegionName, regionInfo.RegionCoordX, regionInfo.RegionCoordY); |
689 | 815 | ||
690 | // a little eekie that this goes back to Scene and with a forced cast, will fix that at some point... | 816 | // a little eekie that this goes back to Scene and with a forced cast, will fix that at some point... |
691 | ((Scene)(client.Scene)).RequestTeleportLocation( | 817 | ((Scene)(client.Scene)).RequestTeleportLocation( |
@@ -736,7 +862,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
736 | 862 | ||
737 | neighbourx--; | 863 | neighbourx--; |
738 | newpos.X = Constants.RegionSize - enterDistance; | 864 | newpos.X = Constants.RegionSize - enterDistance; |
739 | |||
740 | } | 865 | } |
741 | else if (scene.TestBorderCross(pos + eastCross, Cardinals.E)) | 866 | else if (scene.TestBorderCross(pos + eastCross, Cardinals.E)) |
742 | { | 867 | { |
@@ -922,107 +1047,123 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
922 | ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, | 1047 | ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, |
923 | bool isFlying, string version) | 1048 | bool isFlying, string version) |
924 | { | 1049 | { |
1050 | if (neighbourRegion == null) | ||
1051 | return agent; | ||
1052 | |||
925 | try | 1053 | try |
926 | { | 1054 | { |
1055 | m_entityTransferStateMachine.SetInTransit(agent.UUID); | ||
1056 | |||
927 | ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); | 1057 | ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); |
928 | 1058 | ||
929 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3} running version {4}", agent.Firstname, agent.Lastname, neighbourx, neighboury, version); | 1059 | m_log.DebugFormat( |
1060 | "[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3} running version {4}", | ||
1061 | agent.Firstname, agent.Lastname, neighbourx, neighboury, version); | ||
930 | 1062 | ||
931 | Scene m_scene = agent.Scene; | 1063 | Scene m_scene = agent.Scene; |
932 | 1064 | ||
933 | if (neighbourRegion != null) | 1065 | if (!agent.ValidateAttachments()) |
1066 | m_log.DebugFormat( | ||
1067 | "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for region crossing of {0} from {1} to {2}. Continuing.", | ||
1068 | agent.Name, agent.Scene.RegionInfo.RegionName, neighbourRegion.RegionName); | ||
1069 | |||
1070 | pos = pos + agent.Velocity; | ||
1071 | Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0); | ||
1072 | |||
1073 | agent.RemoveFromPhysicalScene(); | ||
1074 | |||
1075 | AgentData cAgent = new AgentData(); | ||
1076 | agent.CopyTo(cAgent); | ||
1077 | cAgent.Position = pos; | ||
1078 | if (isFlying) | ||
1079 | cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; | ||
1080 | |||
1081 | // We don't need the callback anymnore | ||
1082 | cAgent.CallbackURI = String.Empty; | ||
1083 | |||
1084 | // Beyond this point, extra cleanup is needed beyond removing transit state | ||
1085 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring); | ||
1086 | |||
1087 | if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) | ||
934 | { | 1088 | { |
935 | if (!agent.ValidateAttachments()) | 1089 | // region doesn't take it |
936 | m_log.DebugFormat( | 1090 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); |
937 | "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for region crossing of {0} from {1} to {2}. Continuing.", | ||
938 | agent.Name, agent.Scene.RegionInfo.RegionName, neighbourRegion.RegionName); | ||
939 | 1091 | ||
940 | pos = pos + agent.Velocity; | 1092 | ReInstantiateScripts(agent); |
941 | Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0); | 1093 | agent.AddToPhysicalScene(isFlying); |
1094 | m_entityTransferStateMachine.ResetFromTransit(agent.UUID); | ||
942 | 1095 | ||
943 | agent.RemoveFromPhysicalScene(); | 1096 | return agent; |
944 | SetInTransit(agent.UUID); | 1097 | } |
945 | 1098 | ||
946 | AgentData cAgent = new AgentData(); | 1099 | //AgentCircuitData circuitdata = m_controllingClient.RequestClientInfo(); |
947 | agent.CopyTo(cAgent); | 1100 | agent.ControllingClient.RequestClientInfo(); |
948 | cAgent.Position = pos; | ||
949 | if (isFlying) | ||
950 | cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; | ||
951 | 1101 | ||
952 | // We don't need the callback anymnore | 1102 | //m_log.Debug("BEFORE CROSS"); |
953 | cAgent.CallbackURI = String.Empty; | 1103 | //Scene.DumpChildrenSeeds(UUID); |
1104 | //DumpKnownRegions(); | ||
1105 | string agentcaps; | ||
1106 | if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps)) | ||
1107 | { | ||
1108 | m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.", | ||
1109 | neighbourRegion.RegionHandle); | ||
1110 | return agent; | ||
1111 | } | ||
1112 | // No turning back | ||
1113 | agent.IsChildAgent = true; | ||
954 | 1114 | ||
955 | if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) | 1115 | string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); |
956 | { | ||
957 | // region doesn't take it | ||
958 | ReInstantiateScripts(agent); | ||
959 | agent.AddToPhysicalScene(isFlying); | ||
960 | ResetFromTransit(agent.UUID); | ||
961 | return agent; | ||
962 | } | ||
963 | |||
964 | //AgentCircuitData circuitdata = m_controllingClient.RequestClientInfo(); | ||
965 | agent.ControllingClient.RequestClientInfo(); | ||
966 | |||
967 | //m_log.Debug("BEFORE CROSS"); | ||
968 | //Scene.DumpChildrenSeeds(UUID); | ||
969 | //DumpKnownRegions(); | ||
970 | string agentcaps; | ||
971 | if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps)) | ||
972 | { | ||
973 | m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.", | ||
974 | neighbourRegion.RegionHandle); | ||
975 | return agent; | ||
976 | } | ||
977 | // No turning back | ||
978 | agent.IsChildAgent = true; | ||
979 | 1116 | ||
980 | string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); | 1117 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); |
981 | |||
982 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); | ||
983 | 1118 | ||
984 | IEventQueue eq = agent.Scene.RequestModuleInterface<IEventQueue>(); | 1119 | if (m_eqModule != null) |
985 | if (eq != null) | 1120 | { |
986 | { | 1121 | m_eqModule.CrossRegion( |
987 | eq.CrossRegion(neighbourHandle, pos, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint, | 1122 | neighbourHandle, pos, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint, |
988 | capsPath, agent.UUID, agent.ControllingClient.SessionId); | 1123 | capsPath, agent.UUID, agent.ControllingClient.SessionId); |
989 | } | 1124 | } |
990 | else | 1125 | else |
991 | { | 1126 | { |
992 | agent.ControllingClient.CrossRegion(neighbourHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint, | 1127 | agent.ControllingClient.CrossRegion(neighbourHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint, |
993 | capsPath); | 1128 | capsPath); |
994 | } | 1129 | } |
995 | 1130 | ||
996 | // SUCCESS! | 1131 | // SUCCESS! |
997 | agent.MakeChildAgent(); | 1132 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination); |
998 | ResetFromTransit(agent.UUID); | ||
999 | 1133 | ||
1000 | // now we have a child agent in this region. Request all interesting data about other (root) agents | 1134 | // Unlike a teleport, here we do not wait for the destination region to confirm the receipt. |
1001 | agent.SendOtherAgentsAvatarDataToMe(); | 1135 | m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); |
1002 | agent.SendOtherAgentsAppearanceToMe(); | ||
1003 | 1136 | ||
1004 | // Backwards compatibility. Best effort | 1137 | agent.MakeChildAgent(); |
1005 | if (version == "Unknown" || version == string.Empty) | ||
1006 | { | ||
1007 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one..."); | ||
1008 | Thread.Sleep(3000); // wait a little now that we're not waiting for the callback | ||
1009 | CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); | ||
1010 | } | ||
1011 | 1138 | ||
1139 | // FIXME: Possibly this should occur lower down after other commands to close other agents, | ||
1140 | // but not sure yet what the side effects would be. | ||
1141 | m_entityTransferStateMachine.ResetFromTransit(agent.UUID); | ||
1012 | 1142 | ||
1013 | // Next, let's close the child agent connections that are too far away. | 1143 | // now we have a child agent in this region. Request all interesting data about other (root) agents |
1014 | agent.CloseChildAgents(neighbourx, neighboury); | 1144 | agent.SendOtherAgentsAvatarDataToMe(); |
1015 | 1145 | agent.SendOtherAgentsAppearanceToMe(); | |
1016 | AgentHasMovedAway(agent, false); | 1146 | |
1017 | 1147 | // Backwards compatibility. Best effort | |
1018 | // the user may change their profile information in other region, | 1148 | if (version == "Unknown" || version == string.Empty) |
1019 | // so the userinfo in UserProfileCache is not reliable any more, delete it | 1149 | { |
1020 | // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! | 1150 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one..."); |
1021 | if (agent.Scene.NeedSceneCacheClear(agent.UUID)) | 1151 | Thread.Sleep(3000); // wait a little now that we're not waiting for the callback |
1022 | { | 1152 | CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); |
1023 | m_log.DebugFormat( | 1153 | } |
1024 | "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID); | 1154 | |
1025 | } | 1155 | // Next, let's close the child agent connections that are too far away. |
1156 | agent.CloseChildAgents(neighbourx, neighboury); | ||
1157 | |||
1158 | AgentHasMovedAway(agent, false); | ||
1159 | |||
1160 | // the user may change their profile information in other region, | ||
1161 | // so the userinfo in UserProfileCache is not reliable any more, delete it | ||
1162 | // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! | ||
1163 | if (agent.Scene.NeedSceneCacheClear(agent.UUID)) | ||
1164 | { | ||
1165 | m_log.DebugFormat( | ||
1166 | "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID); | ||
1026 | } | 1167 | } |
1027 | 1168 | ||
1028 | //m_log.Debug("AFTER CROSS"); | 1169 | //m_log.Debug("AFTER CROSS"); |
@@ -1034,11 +1175,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1034 | m_log.ErrorFormat( | 1175 | m_log.ErrorFormat( |
1035 | "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}", | 1176 | "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}", |
1036 | agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace); | 1177 | agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace); |
1178 | |||
1179 | // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc. | ||
1037 | } | 1180 | } |
1038 | 1181 | ||
1039 | return agent; | 1182 | return agent; |
1040 | } | 1183 | } |
1041 | 1184 | ||
1042 | private void CrossAgentToNewRegionCompleted(IAsyncResult iar) | 1185 | private void CrossAgentToNewRegionCompleted(IAsyncResult iar) |
1043 | { | 1186 | { |
1044 | CrossAgentToNewRegionDelegate icon = (CrossAgentToNewRegionDelegate)iar.AsyncState; | 1187 | CrossAgentToNewRegionDelegate icon = (CrossAgentToNewRegionDelegate)iar.AsyncState; |
@@ -1186,7 +1329,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1186 | { | 1329 | { |
1187 | if (neighbour.RegionHandle != sp.Scene.RegionInfo.RegionHandle) | 1330 | if (neighbour.RegionHandle != sp.Scene.RegionInfo.RegionHandle) |
1188 | { | 1331 | { |
1189 | |||
1190 | AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); | 1332 | AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); |
1191 | AgentCircuitData agent = sp.ControllingClient.RequestClientInfo(); | 1333 | AgentCircuitData agent = sp.ControllingClient.RequestClientInfo(); |
1192 | agent.BaseFolder = UUID.Zero; | 1334 | agent.BaseFolder = UUID.Zero; |
@@ -1211,7 +1353,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1211 | seeds.Add(neighbour.RegionHandle, agent.CapsPath); | 1353 | seeds.Add(neighbour.RegionHandle, agent.CapsPath); |
1212 | } | 1354 | } |
1213 | else | 1355 | else |
1356 | { | ||
1214 | agent.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, neighbour.RegionHandle); | 1357 | agent.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, neighbour.RegionHandle); |
1358 | } | ||
1215 | 1359 | ||
1216 | cagents.Add(agent); | 1360 | cagents.Add(agent); |
1217 | } | 1361 | } |
@@ -1322,24 +1466,21 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1322 | // after a cross here | 1466 | // after a cross here |
1323 | Thread.Sleep(500); | 1467 | Thread.Sleep(500); |
1324 | 1468 | ||
1325 | Scene m_scene = sp.Scene; | 1469 | Scene scene = sp.Scene; |
1326 | 1470 | ||
1327 | uint x, y; | 1471 | m_log.DebugFormat( |
1328 | Utils.LongToUInts(reg.RegionHandle, out x, out y); | 1472 | "[ENTITY TRANSFER MODULE]: Informing {0} {1} about neighbour {2} {3} at ({4},{5})", |
1329 | x = x / Constants.RegionSize; | 1473 | sp.Name, sp.UUID, reg.RegionName, endPoint, reg.RegionCoordX, reg.RegionCoordY); |
1330 | y = y / Constants.RegionSize; | ||
1331 | m_log.Debug("[ENTITY TRANSFER MODULE]: Starting to inform client about neighbour " + x + ", " + y + "(" + endPoint + ")"); | ||
1332 | 1474 | ||
1333 | string capsPath = reg.ServerURI + CapsUtil.GetCapsSeedPath(a.CapsPath); | 1475 | string capsPath = reg.ServerURI + CapsUtil.GetCapsSeedPath(a.CapsPath); |
1334 | 1476 | ||
1335 | string reason = String.Empty; | 1477 | string reason = String.Empty; |
1336 | 1478 | ||
1337 | bool regionAccepted = m_scene.SimulationService.CreateAgent(reg, a, (uint)TeleportFlags.Default, out reason); | 1479 | bool regionAccepted = scene.SimulationService.CreateAgent(reg, a, (uint)TeleportFlags.Default, out reason); |
1338 | 1480 | ||
1339 | if (regionAccepted && newAgent) | 1481 | if (regionAccepted && newAgent) |
1340 | { | 1482 | { |
1341 | IEventQueue eq = sp.Scene.RequestModuleInterface<IEventQueue>(); | 1483 | if (m_eqModule != null) |
1342 | if (eq != null) | ||
1343 | { | 1484 | { |
1344 | #region IP Translation for NAT | 1485 | #region IP Translation for NAT |
1345 | IClientIPEndpoint ipepClient; | 1486 | IClientIPEndpoint ipepClient; |
@@ -1351,10 +1492,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1351 | 1492 | ||
1352 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: {0} is sending {1} EnableSimulator for neighbour region {2} @ {3} " + | 1493 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: {0} is sending {1} EnableSimulator for neighbour region {2} @ {3} " + |
1353 | "and EstablishAgentCommunication with seed cap {4}", | 1494 | "and EstablishAgentCommunication with seed cap {4}", |
1354 | m_scene.RegionInfo.RegionName, sp.Name, reg.RegionName, reg.RegionHandle, capsPath); | 1495 | scene.RegionInfo.RegionName, sp.Name, reg.RegionName, reg.RegionHandle, capsPath); |
1355 | 1496 | ||
1356 | eq.EnableSimulator(reg.RegionHandle, endPoint, sp.UUID); | 1497 | m_eqModule.EnableSimulator(reg.RegionHandle, endPoint, sp.UUID); |
1357 | eq.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); | 1498 | m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); |
1358 | } | 1499 | } |
1359 | else | 1500 | else |
1360 | { | 1501 | { |
@@ -1362,8 +1503,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1362 | // TODO: make Event Queue disablable! | 1503 | // TODO: make Event Queue disablable! |
1363 | } | 1504 | } |
1364 | 1505 | ||
1365 | m_log.Debug("[ENTITY TRANSFER MODULE]: Completed inform client about neighbour " + endPoint.ToString()); | 1506 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Completed inform {0} {1} about neighbour {2}", sp.Name, sp.UUID, endPoint); |
1366 | } | 1507 | } |
1508 | |||
1509 | if (!regionAccepted) | ||
1510 | m_log.WarnFormat( | ||
1511 | "[ENTITY TRANSFER MODULE]: Region {0} did not accept {1} {2}: {3}", | ||
1512 | reg.RegionName, sp.Name, sp.UUID, reason); | ||
1367 | } | 1513 | } |
1368 | 1514 | ||
1369 | /// <summary> | 1515 | /// <summary> |
@@ -1471,17 +1617,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1471 | 1617 | ||
1472 | #endregion | 1618 | #endregion |
1473 | 1619 | ||
1474 | |||
1475 | #region Agent Arrived | 1620 | #region Agent Arrived |
1621 | |||
1476 | public void AgentArrivedAtDestination(UUID id) | 1622 | public void AgentArrivedAtDestination(UUID id) |
1477 | { | 1623 | { |
1478 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Agent {0} released", id); | 1624 | m_entityTransferStateMachine.SetAgentArrivedAtDestination(id); |
1479 | ResetFromTransit(id); | ||
1480 | } | 1625 | } |
1481 | 1626 | ||
1482 | #endregion | 1627 | #endregion |
1483 | 1628 | ||
1484 | #region Object Transfers | 1629 | #region Object Transfers |
1630 | |||
1485 | /// <summary> | 1631 | /// <summary> |
1486 | /// Move the given scene object into a new region depending on which region its absolute position has moved | 1632 | /// Move the given scene object into a new region depending on which region its absolute position has moved |
1487 | /// into. | 1633 | /// into. |
@@ -1747,8 +1893,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1747 | //// And the new channel... | 1893 | //// And the new channel... |
1748 | //if (m_interregionCommsOut != null) | 1894 | //if (m_interregionCommsOut != null) |
1749 | // successYN = m_interregionCommsOut.SendCreateObject(newRegionHandle, grp, true); | 1895 | // successYN = m_interregionCommsOut.SendCreateObject(newRegionHandle, grp, true); |
1750 | if (m_aScene.SimulationService != null) | 1896 | if (Scene.SimulationService != null) |
1751 | successYN = m_aScene.SimulationService.CreateObject(destination, newPosition, grp, true); | 1897 | successYN = Scene.SimulationService.CreateObject(destination, newPosition, grp, true); |
1752 | 1898 | ||
1753 | if (successYN) | 1899 | if (successYN) |
1754 | { | 1900 | { |
@@ -1792,86 +1938,52 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1792 | return successYN; | 1938 | return successYN; |
1793 | } | 1939 | } |
1794 | 1940 | ||
1795 | protected bool CrossAttachmentsIntoNewRegion(GridRegion destination, ScenePresence sp, bool silent) | 1941 | /// <summary> |
1942 | /// Cross the attachments for an avatar into the destination region. | ||
1943 | /// </summary> | ||
1944 | /// <remarks> | ||
1945 | /// This is only invoked for simulators released prior to April 2011. Versions of OpenSimulator since then | ||
1946 | /// transfer attachments in one go as part of the ChildAgentDataUpdate data passed in the update agent call. | ||
1947 | /// </remarks> | ||
1948 | /// <param name='destination'></param> | ||
1949 | /// <param name='sp'></param> | ||
1950 | /// <param name='silent'></param> | ||
1951 | protected void CrossAttachmentsIntoNewRegion(GridRegion destination, ScenePresence sp, bool silent) | ||
1796 | { | 1952 | { |
1797 | List<SceneObjectGroup> m_attachments = sp.GetAttachments(); | 1953 | List<SceneObjectGroup> attachments = sp.GetAttachments(); |
1798 | 1954 | ||
1799 | // Validate | 1955 | // m_log.DebugFormat( |
1800 | // foreach (SceneObjectGroup gobj in m_attachments) | 1956 | // "[ENTITY TRANSFER MODULE]: Crossing {0} attachments into {1} for {2}", |
1801 | // { | 1957 | // m_attachments.Count, destination.RegionName, sp.Name); |
1802 | // if (gobj == null || gobj.IsDeleted) | ||
1803 | // return false; | ||
1804 | // } | ||
1805 | 1958 | ||
1806 | foreach (SceneObjectGroup gobj in m_attachments) | 1959 | foreach (SceneObjectGroup gobj in attachments) |
1807 | { | 1960 | { |
1808 | // If the prim group is null then something must have happened to it! | 1961 | // If the prim group is null then something must have happened to it! |
1809 | if (gobj != null && !gobj.IsDeleted) | 1962 | if (gobj != null && !gobj.IsDeleted) |
1810 | { | 1963 | { |
1811 | // Set the parent localID to 0 so it transfers over properly. | 1964 | SceneObjectGroup clone = (SceneObjectGroup)gobj.CloneForNewScene(); |
1812 | gobj.RootPart.SetParentLocalId(0); | 1965 | clone.RootPart.GroupPosition = gobj.RootPart.AttachedPos; |
1813 | gobj.AbsolutePosition = gobj.RootPart.AttachedPos; | 1966 | clone.IsAttachment = false; |
1814 | gobj.IsAttachment = false; | 1967 | |
1815 | //gobj.RootPart.LastOwnerID = gobj.GetFromAssetID(); | 1968 | //gobj.RootPart.LastOwnerID = gobj.GetFromAssetID(); |
1816 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending attachment {0} to region {1}", gobj.UUID, destination.RegionName); | 1969 | m_log.DebugFormat( |
1817 | CrossPrimGroupIntoNewRegion(destination, Vector3.Zero, gobj, silent); | 1970 | "[ENTITY TRANSFER MODULE]: Sending attachment {0} to region {1}", |
1971 | clone.UUID, destination.RegionName); | ||
1972 | |||
1973 | CrossPrimGroupIntoNewRegion(destination, Vector3.Zero, clone, silent); | ||
1818 | } | 1974 | } |
1819 | } | 1975 | } |
1820 | 1976 | ||
1821 | sp.ClearAttachments(); | 1977 | sp.ClearAttachments(); |
1822 | |||
1823 | return true; | ||
1824 | } | 1978 | } |
1825 | 1979 | ||
1826 | #endregion | 1980 | #endregion |
1827 | 1981 | ||
1828 | #region Misc | 1982 | #region Misc |
1829 | 1983 | ||
1830 | protected bool WaitForCallback(UUID id) | 1984 | public bool IsInTransit(UUID id) |
1831 | { | ||
1832 | int count = 200; | ||
1833 | while (m_agentsInTransit.Contains(id) && count-- > 0) | ||
1834 | { | ||
1835 | //m_log.Debug(" >>> Waiting... " + count); | ||
1836 | Thread.Sleep(100); | ||
1837 | } | ||
1838 | |||
1839 | if (count > 0) | ||
1840 | return true; | ||
1841 | else | ||
1842 | return false; | ||
1843 | } | ||
1844 | |||
1845 | protected void SetInTransit(UUID id) | ||
1846 | { | ||
1847 | lock (m_agentsInTransit) | ||
1848 | { | ||
1849 | if (!m_agentsInTransit.Contains(id)) | ||
1850 | m_agentsInTransit.Add(id); | ||
1851 | } | ||
1852 | } | ||
1853 | |||
1854 | protected bool IsInTransit(UUID id) | ||
1855 | { | 1985 | { |
1856 | lock (m_agentsInTransit) | 1986 | return m_entityTransferStateMachine.IsInTransit(id); |
1857 | { | ||
1858 | if (m_agentsInTransit.Contains(id)) | ||
1859 | return true; | ||
1860 | } | ||
1861 | return false; | ||
1862 | } | ||
1863 | |||
1864 | protected bool ResetFromTransit(UUID id) | ||
1865 | { | ||
1866 | lock (m_agentsInTransit) | ||
1867 | { | ||
1868 | if (m_agentsInTransit.Contains(id)) | ||
1869 | { | ||
1870 | m_agentsInTransit.Remove(id); | ||
1871 | return true; | ||
1872 | } | ||
1873 | } | ||
1874 | return false; | ||
1875 | } | 1987 | } |
1876 | 1988 | ||
1877 | protected void ReInstantiateScripts(ScenePresence sp) | 1989 | protected void ReInstantiateScripts(ScenePresence sp) |
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs new file mode 100644 index 0000000..d0cab49 --- /dev/null +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs | |||
@@ -0,0 +1,269 @@ | |||
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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Net; | ||
31 | using System.Reflection; | ||
32 | using System.Threading; | ||
33 | using OpenMetaverse; | ||
34 | using log4net; | ||
35 | using Nini.Config; | ||
36 | using OpenSim.Framework; | ||
37 | using OpenSim.Framework.Capabilities; | ||
38 | using OpenSim.Framework.Client; | ||
39 | using OpenSim.Region.Framework.Interfaces; | ||
40 | using OpenSim.Region.Framework.Scenes; | ||
41 | using OpenSim.Region.Physics.Manager; | ||
42 | using OpenSim.Services.Interfaces; | ||
43 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; | ||
44 | |||
45 | namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | ||
46 | { | ||
47 | /// <summary> | ||
48 | /// The possible states that an agent can be in when its being transferred between regions. | ||
49 | /// </summary> | ||
50 | /// <remarks> | ||
51 | /// This is a state machine. | ||
52 | /// | ||
53 | /// [Entry] => Preparing | ||
54 | /// Preparing => { Transferring || CleaningUp || [Exit] } | ||
55 | /// Transferring => { ReceivedAtDestination || CleaningUp } | ||
56 | /// ReceivedAtDestination => CleaningUp | ||
57 | /// CleaningUp => [Exit] | ||
58 | /// | ||
59 | /// In other words, agents normally travel throwing Preparing => Transferring => ReceivedAtDestination => CleaningUp | ||
60 | /// However, any state can transition to CleaningUp if the teleport has failed. | ||
61 | /// </remarks> | ||
62 | enum AgentTransferState | ||
63 | { | ||
64 | Preparing, // The agent is being prepared for transfer | ||
65 | 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 | ||
67 | CleaningUp // The agent is being changed to child/removed after a transfer | ||
68 | } | ||
69 | |||
70 | /// <summary> | ||
71 | /// Records the state of entities when they are in transfer within or between regions (cross or teleport). | ||
72 | /// </summary> | ||
73 | public class EntityTransferStateMachine | ||
74 | { | ||
75 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
76 | |||
77 | /// <summary> | ||
78 | /// If true then on a teleport, the source region waits for a callback from the destination region. If | ||
79 | /// a callback fails to arrive within a set time then the user is pulled back into the source region. | ||
80 | /// </summary> | ||
81 | public bool EnableWaitForAgentArrivedAtDestination { get; set; } | ||
82 | |||
83 | private EntityTransferModule m_mod; | ||
84 | |||
85 | private Dictionary<UUID, AgentTransferState> m_agentsInTransit = new Dictionary<UUID, AgentTransferState>(); | ||
86 | |||
87 | public EntityTransferStateMachine(EntityTransferModule module) | ||
88 | { | ||
89 | m_mod = module; | ||
90 | } | ||
91 | |||
92 | /// <summary> | ||
93 | /// Set that an agent is in transit. | ||
94 | /// </summary> | ||
95 | /// <param name='id'>The ID of the agent being teleported</param> | ||
96 | /// <returns>true if the agent was not already in transit, false if it was</returns> | ||
97 | internal bool SetInTransit(UUID id) | ||
98 | { | ||
99 | lock (m_agentsInTransit) | ||
100 | { | ||
101 | if (!m_agentsInTransit.ContainsKey(id)) | ||
102 | { | ||
103 | m_agentsInTransit[id] = AgentTransferState.Preparing; | ||
104 | return true; | ||
105 | } | ||
106 | } | ||
107 | |||
108 | return false; | ||
109 | } | ||
110 | |||
111 | /// <summary> | ||
112 | /// Updates the state of an agent that is already in transit. | ||
113 | /// </summary> | ||
114 | /// <param name='id'></param> | ||
115 | /// <param name='newState'></param> | ||
116 | /// <returns></returns> | ||
117 | /// <exception cref='Exception'>Illegal transitions will throw an Exception</exception> | ||
118 | internal void UpdateInTransit(UUID id, AgentTransferState newState) | ||
119 | { | ||
120 | lock (m_agentsInTransit) | ||
121 | { | ||
122 | // Illegal to try and update an agent that's not actually in transit. | ||
123 | if (!m_agentsInTransit.ContainsKey(id)) | ||
124 | throw new Exception( | ||
125 | string.Format( | ||
126 | "Agent with ID {0} is not registered as in transit in {1}", | ||
127 | id, m_mod.Scene.RegionInfo.RegionName)); | ||
128 | |||
129 | AgentTransferState oldState = m_agentsInTransit[id]; | ||
130 | |||
131 | bool transitionOkay = false; | ||
132 | |||
133 | if (newState == AgentTransferState.CleaningUp && oldState != AgentTransferState.CleaningUp) | ||
134 | transitionOkay = true; | ||
135 | else if (newState == AgentTransferState.Transferring && oldState == AgentTransferState.Preparing) | ||
136 | transitionOkay = true; | ||
137 | else if (newState == AgentTransferState.ReceivedAtDestination && oldState == AgentTransferState.Transferring) | ||
138 | transitionOkay = true; | ||
139 | |||
140 | if (transitionOkay) | ||
141 | m_agentsInTransit[id] = newState; | ||
142 | else | ||
143 | throw new Exception( | ||
144 | string.Format( | ||
145 | "Agent with ID {0} is not allowed to move from old transit state {1} to new state {2} in {3}", | ||
146 | id, oldState, newState, m_mod.Scene.RegionInfo.RegionName)); | ||
147 | } | ||
148 | } | ||
149 | |||
150 | internal bool IsInTransit(UUID id) | ||
151 | { | ||
152 | lock (m_agentsInTransit) | ||
153 | return m_agentsInTransit.ContainsKey(id); | ||
154 | } | ||
155 | |||
156 | /// <summary> | ||
157 | /// Removes an agent from the transit state machine. | ||
158 | /// </summary> | ||
159 | /// <param name='id'></param> | ||
160 | /// <returns>true if the agent was flagged as being teleported when this method was called, false otherwise</returns> | ||
161 | internal bool ResetFromTransit(UUID id) | ||
162 | { | ||
163 | lock (m_agentsInTransit) | ||
164 | { | ||
165 | if (m_agentsInTransit.ContainsKey(id)) | ||
166 | { | ||
167 | AgentTransferState state = m_agentsInTransit[id]; | ||
168 | |||
169 | if (state == AgentTransferState.Transferring || state == AgentTransferState.ReceivedAtDestination) | ||
170 | { | ||
171 | // FIXME: For now, we allow exit from any state since a thrown exception in teleport is now guranteed | ||
172 | // to be handled properly - ResetFromTransit() could be invoked at any step along the process | ||
173 | m_log.WarnFormat( | ||
174 | "[ENTITY TRANSFER STATE MACHINE]: Agent with ID {0} should not exit directly from state {1}, should go to {2} state first in {3}", | ||
175 | id, state, AgentTransferState.CleaningUp, m_mod.Scene.RegionInfo.RegionName); | ||
176 | |||
177 | // throw new Exception( | ||
178 | // "Agent with ID {0} cannot exit directly from state {1}, it must go to {2} state first", | ||
179 | // state, AgentTransferState.CleaningUp); | ||
180 | } | ||
181 | |||
182 | m_agentsInTransit.Remove(id); | ||
183 | |||
184 | m_log.DebugFormat( | ||
185 | "[ENTITY TRANSFER STATE MACHINE]: Agent {0} cleared from transit in {1}", | ||
186 | id, m_mod.Scene.RegionInfo.RegionName); | ||
187 | |||
188 | return true; | ||
189 | } | ||
190 | } | ||
191 | |||
192 | m_log.WarnFormat( | ||
193 | "[ENTITY TRANSFER STATE MACHINE]: Agent {0} requested to clear from transit in {1} but was already cleared", | ||
194 | id, m_mod.Scene.RegionInfo.RegionName); | ||
195 | |||
196 | return false; | ||
197 | } | ||
198 | |||
199 | internal bool WaitForAgentArrivedAtDestination(UUID id) | ||
200 | { | ||
201 | if (!m_mod.WaitForAgentArrivedAtDestination) | ||
202 | return true; | ||
203 | |||
204 | lock (m_agentsInTransit) | ||
205 | { | ||
206 | if (!IsInTransit(id)) | ||
207 | throw new Exception( | ||
208 | string.Format( | ||
209 | "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)); | ||
211 | |||
212 | AgentTransferState currentState = m_agentsInTransit[id]; | ||
213 | |||
214 | if (currentState != AgentTransferState.Transferring && currentState != AgentTransferState.ReceivedAtDestination) | ||
215 | throw new Exception( | ||
216 | string.Format( | ||
217 | "Asked to wait for destination callback for agent with ID {0} in {1} but agent is in state {2}", | ||
218 | id, m_mod.Scene.RegionInfo.RegionName, currentState)); | ||
219 | } | ||
220 | |||
221 | int count = 200; | ||
222 | |||
223 | // 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. | ||
225 | while (m_agentsInTransit[id] != AgentTransferState.ReceivedAtDestination && count-- > 0) | ||
226 | { | ||
227 | // m_log.Debug(" >>> Waiting... " + count); | ||
228 | Thread.Sleep(100); | ||
229 | } | ||
230 | |||
231 | return count > 0; | ||
232 | } | ||
233 | |||
234 | internal void SetAgentArrivedAtDestination(UUID id) | ||
235 | { | ||
236 | lock (m_agentsInTransit) | ||
237 | { | ||
238 | if (!m_agentsInTransit.ContainsKey(id)) | ||
239 | { | ||
240 | m_log.WarnFormat( | ||
241 | "[ENTITY TRANSFER STATE MACHINE]: Region {0} received notification of arrival in destination of agent {1} but no teleport request is active", | ||
242 | m_mod.Scene.RegionInfo.RegionName, id); | ||
243 | |||
244 | return; | ||
245 | } | ||
246 | |||
247 | AgentTransferState currentState = m_agentsInTransit[id]; | ||
248 | |||
249 | if (currentState == AgentTransferState.ReceivedAtDestination) | ||
250 | { | ||
251 | // An anomoly but don't make this an outright failure - destination region could be overzealous in sending notification. | ||
252 | m_log.WarnFormat( | ||
253 | "[ENTITY TRANSFER STATE MACHINE]: Region {0} received notification of arrival in destination of agent {1} but notification has already previously been received", | ||
254 | m_mod.Scene.RegionInfo.RegionName, id); | ||
255 | } | ||
256 | else if (currentState != AgentTransferState.Transferring) | ||
257 | { | ||
258 | m_log.ErrorFormat( | ||
259 | "[ENTITY TRANSFER STATE MACHINE]: Region {0} received notification of arrival in destination of agent {1} but agent is in state {2}", | ||
260 | m_mod.Scene.RegionInfo.RegionName, id, currentState); | ||
261 | |||
262 | return; | ||
263 | } | ||
264 | |||
265 | m_agentsInTransit[id] = AgentTransferState.ReceivedAtDestination; | ||
266 | } | ||
267 | } | ||
268 | } | ||
269 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index 8b5ad23..3010b59 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs | |||
@@ -45,11 +45,12 @@ using Nini.Config; | |||
45 | 45 | ||
46 | namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | 46 | namespace OpenSim.Region.CoreModules.Framework.EntityTransfer |
47 | { | 47 | { |
48 | public class HGEntityTransferModule : EntityTransferModule, ISharedRegionModule, IEntityTransferModule, IUserAgentVerificationModule | 48 | public class HGEntityTransferModule |
49 | : EntityTransferModule, INonSharedRegionModule, IEntityTransferModule, IUserAgentVerificationModule | ||
49 | { | 50 | { |
50 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 51 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
51 | 52 | ||
52 | private bool m_Initialized = false; | 53 | private int m_levelHGTeleport = 0; |
53 | 54 | ||
54 | private GatekeeperServiceConnector m_GatekeeperConnector; | 55 | private GatekeeperServiceConnector m_GatekeeperConnector; |
55 | 56 | ||
@@ -63,11 +64,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
63 | public override void Initialise(IConfigSource source) | 64 | public override void Initialise(IConfigSource source) |
64 | { | 65 | { |
65 | IConfig moduleConfig = source.Configs["Modules"]; | 66 | IConfig moduleConfig = source.Configs["Modules"]; |
67 | |||
66 | if (moduleConfig != null) | 68 | if (moduleConfig != null) |
67 | { | 69 | { |
68 | string name = moduleConfig.GetString("EntityTransferModule", ""); | 70 | string name = moduleConfig.GetString("EntityTransferModule", ""); |
69 | if (name == Name) | 71 | if (name == Name) |
70 | { | 72 | { |
73 | IConfig transferConfig = source.Configs["EntityTransfer"]; | ||
74 | if (transferConfig != null) | ||
75 | m_levelHGTeleport = transferConfig.GetInt("LevelHGTeleport", 0); | ||
76 | |||
71 | InitialiseCommon(source); | 77 | InitialiseCommon(source); |
72 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: {0} enabled.", Name); | 78 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: {0} enabled.", Name); |
73 | } | 79 | } |
@@ -77,10 +83,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
77 | public override void AddRegion(Scene scene) | 83 | public override void AddRegion(Scene scene) |
78 | { | 84 | { |
79 | base.AddRegion(scene); | 85 | base.AddRegion(scene); |
86 | |||
80 | if (m_Enabled) | 87 | if (m_Enabled) |
81 | { | ||
82 | scene.RegisterModuleInterface<IUserAgentVerificationModule>(this); | 88 | scene.RegisterModuleInterface<IUserAgentVerificationModule>(this); |
83 | } | ||
84 | } | 89 | } |
85 | 90 | ||
86 | protected override void OnNewClient(IClientAPI client) | 91 | protected override void OnNewClient(IClientAPI client) |
@@ -93,33 +98,28 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
93 | public override void RegionLoaded(Scene scene) | 98 | public override void RegionLoaded(Scene scene) |
94 | { | 99 | { |
95 | base.RegionLoaded(scene); | 100 | base.RegionLoaded(scene); |
96 | if (m_Enabled) | ||
97 | if (!m_Initialized) | ||
98 | { | ||
99 | m_GatekeeperConnector = new GatekeeperServiceConnector(scene.AssetService); | ||
100 | m_Initialized = true; | ||
101 | |||
102 | } | ||
103 | 101 | ||
102 | if (m_Enabled) | ||
103 | m_GatekeeperConnector = new GatekeeperServiceConnector(scene.AssetService); | ||
104 | } | 104 | } |
105 | |||
105 | public override void RemoveRegion(Scene scene) | 106 | public override void RemoveRegion(Scene scene) |
106 | { | 107 | { |
107 | base.AddRegion(scene); | 108 | base.AddRegion(scene); |
109 | |||
108 | if (m_Enabled) | 110 | if (m_Enabled) |
109 | { | ||
110 | scene.UnregisterModuleInterface<IUserAgentVerificationModule>(this); | 111 | scene.UnregisterModuleInterface<IUserAgentVerificationModule>(this); |
111 | } | ||
112 | } | 112 | } |
113 | 113 | ||
114 | |||
115 | #endregion | 114 | #endregion |
116 | 115 | ||
117 | #region HG overrides of IEntiryTransferModule | 116 | #region HG overrides of IEntiryTransferModule |
118 | 117 | ||
119 | protected override GridRegion GetFinalDestination(GridRegion region) | 118 | protected override GridRegion GetFinalDestination(GridRegion region) |
120 | { | 119 | { |
121 | int flags = m_aScene.GridService.GetRegionFlags(m_aScene.RegionInfo.ScopeID, region.RegionID); | 120 | int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, region.RegionID); |
122 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: region {0} flags: {1}", region.RegionID, flags); | 121 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: region {0} flags: {1}", region.RegionID, flags); |
122 | |||
123 | if ((flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) | 123 | if ((flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) |
124 | { | 124 | { |
125 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Destination region {0} is hyperlink", region.RegionID); | 125 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Destination region {0} is hyperlink", region.RegionID); |
@@ -130,6 +130,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
130 | m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: GetHyperlinkRegion to Gatekeeper {0} failed", region.ServerURI); | 130 | m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: GetHyperlinkRegion to Gatekeeper {0} failed", region.ServerURI); |
131 | return real_destination; | 131 | return real_destination; |
132 | } | 132 | } |
133 | |||
133 | return region; | 134 | return region; |
134 | } | 135 | } |
135 | 136 | ||
@@ -138,7 +139,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
138 | if (base.NeedsClosing(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) | 139 | if (base.NeedsClosing(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) |
139 | return true; | 140 | return true; |
140 | 141 | ||
141 | int flags = m_aScene.GridService.GetRegionFlags(m_aScene.RegionInfo.ScopeID, reg.RegionID); | 142 | int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, reg.RegionID); |
142 | if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) | 143 | if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) |
143 | return true; | 144 | return true; |
144 | 145 | ||
@@ -151,7 +152,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
151 | if (logout) | 152 | if (logout) |
152 | { | 153 | { |
153 | // Log them out of this grid | 154 | // Log them out of this grid |
154 | m_aScene.PresenceService.LogoutAgent(sp.ControllingClient.SessionId); | 155 | Scene.PresenceService.LogoutAgent(sp.ControllingClient.SessionId); |
155 | } | 156 | } |
156 | } | 157 | } |
157 | 158 | ||
@@ -160,10 +161,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
160 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: CreateAgent {0} {1}", reg.ServerURI, finalDestination.ServerURI); | 161 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: CreateAgent {0} {1}", reg.ServerURI, finalDestination.ServerURI); |
161 | reason = string.Empty; | 162 | reason = string.Empty; |
162 | logout = false; | 163 | logout = false; |
163 | int flags = m_aScene.GridService.GetRegionFlags(m_aScene.RegionInfo.ScopeID, reg.RegionID); | 164 | int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, reg.RegionID); |
164 | if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) | 165 | if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) |
165 | { | 166 | { |
166 | // this user is going to another grid | 167 | // this user is going to another grid |
168 | // check if HyperGrid teleport is allowed, based on user level | ||
169 | if (sp.UserLevel < m_levelHGTeleport) | ||
170 | { | ||
171 | m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: Unable to HG teleport agent due to insufficient UserLevel."); | ||
172 | reason = "Hypergrid teleport not allowed"; | ||
173 | return false; | ||
174 | } | ||
175 | |||
167 | if (agentCircuit.ServiceURLs.ContainsKey("HomeURI")) | 176 | if (agentCircuit.ServiceURLs.ContainsKey("HomeURI")) |
168 | { | 177 | { |
169 | string userAgentDriver = agentCircuit.ServiceURLs["HomeURI"].ToString(); | 178 | string userAgentDriver = agentCircuit.ServiceURLs["HomeURI"].ToString(); |
@@ -193,10 +202,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
193 | 202 | ||
194 | public override bool TeleportHome(UUID id, IClientAPI client) | 203 | public override bool TeleportHome(UUID id, IClientAPI client) |
195 | { | 204 | { |
196 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.FirstName, client.LastName); | 205 | m_log.DebugFormat( |
206 | "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId); | ||
197 | 207 | ||
198 | // Let's find out if this is a foreign user or a local user | 208 | // Let's find out if this is a foreign user or a local user |
199 | IUserManagement uMan = m_aScene.RequestModuleInterface<IUserManagement>(); | 209 | IUserManagement uMan = Scene.RequestModuleInterface<IUserManagement>(); |
200 | if (uMan != null && uMan.IsLocalGridUser(id)) | 210 | if (uMan != null && uMan.IsLocalGridUser(id)) |
201 | { | 211 | { |
202 | // local grid user | 212 | // local grid user |
@@ -232,13 +242,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
232 | return false; | 242 | return false; |
233 | } | 243 | } |
234 | 244 | ||
235 | IEventQueue eq = sp.Scene.RequestModuleInterface<IEventQueue>(); | ||
236 | GridRegion homeGatekeeper = MakeRegion(aCircuit); | 245 | GridRegion homeGatekeeper = MakeRegion(aCircuit); |
237 | 246 | ||
238 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: teleporting user {0} {1} home to {2} via {3}:{4}", | 247 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: teleporting user {0} {1} home to {2} via {3}:{4}", |
239 | aCircuit.firstname, aCircuit.lastname, finalDestination.RegionName, homeGatekeeper.ServerURI, homeGatekeeper.RegionName); | 248 | aCircuit.firstname, aCircuit.lastname, finalDestination.RegionName, homeGatekeeper.ServerURI, homeGatekeeper.RegionName); |
240 | 249 | ||
241 | DoTeleport(sp, homeGatekeeper, finalDestination, position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome), eq); | 250 | DoTeleport(sp, homeGatekeeper, finalDestination, position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome)); |
242 | return true; | 251 | return true; |
243 | } | 252 | } |
244 | 253 | ||
@@ -252,19 +261,21 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
252 | { | 261 | { |
253 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Teleporting agent via landmark to {0} region {1} position {2}", | 262 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Teleporting agent via landmark to {0} region {1} position {2}", |
254 | (lm.Gatekeeper == string.Empty) ? "local" : lm.Gatekeeper, lm.RegionID, lm.Position); | 263 | (lm.Gatekeeper == string.Empty) ? "local" : lm.Gatekeeper, lm.RegionID, lm.Position); |
264 | |||
255 | if (lm.Gatekeeper == string.Empty) | 265 | if (lm.Gatekeeper == string.Empty) |
256 | { | 266 | { |
257 | base.RequestTeleportLandmark(remoteClient, lm); | 267 | base.RequestTeleportLandmark(remoteClient, lm); |
258 | return; | 268 | return; |
259 | } | 269 | } |
260 | 270 | ||
261 | GridRegion info = m_aScene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID); | 271 | GridRegion info = Scene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID); |
262 | 272 | ||
263 | // Local region? | 273 | // Local region? |
264 | if (info != null) | 274 | if (info != null) |
265 | { | 275 | { |
266 | ((Scene)(remoteClient.Scene)).RequestTeleportLocation(remoteClient, info.RegionHandle, lm.Position, | 276 | ((Scene)(remoteClient.Scene)).RequestTeleportLocation(remoteClient, info.RegionHandle, lm.Position, |
267 | Vector3.Zero, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark)); | 277 | Vector3.Zero, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark)); |
278 | |||
268 | return; | 279 | return; |
269 | } | 280 | } |
270 | else | 281 | else |
@@ -275,21 +286,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
275 | GridRegion gatekeeper = new GridRegion(); | 286 | GridRegion gatekeeper = new GridRegion(); |
276 | gatekeeper.ServerURI = lm.Gatekeeper; | 287 | gatekeeper.ServerURI = lm.Gatekeeper; |
277 | GridRegion finalDestination = gConn.GetHyperlinkRegion(gatekeeper, new UUID(lm.RegionID)); | 288 | GridRegion finalDestination = gConn.GetHyperlinkRegion(gatekeeper, new UUID(lm.RegionID)); |
289 | |||
278 | if (finalDestination != null) | 290 | if (finalDestination != null) |
279 | { | 291 | { |
280 | ScenePresence sp = scene.GetScenePresence(remoteClient.AgentId); | 292 | ScenePresence sp = scene.GetScenePresence(remoteClient.AgentId); |
281 | IEntityTransferModule transferMod = scene.RequestModuleInterface<IEntityTransferModule>(); | 293 | IEntityTransferModule transferMod = scene.RequestModuleInterface<IEntityTransferModule>(); |
282 | IEventQueue eq = sp.Scene.RequestModuleInterface<IEventQueue>(); | 294 | |
283 | if (transferMod != null && sp != null && eq != null) | 295 | if (transferMod != null && sp != null) |
284 | transferMod.DoTeleport(sp, gatekeeper, finalDestination, lm.Position, | 296 | transferMod.DoTeleport( |
285 | Vector3.UnitX, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark), eq); | 297 | sp, gatekeeper, finalDestination, lm.Position, Vector3.UnitX, |
298 | (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark)); | ||
286 | } | 299 | } |
287 | 300 | ||
288 | } | 301 | } |
289 | 302 | ||
290 | // can't find the region: Tell viewer and abort | 303 | // can't find the region: Tell viewer and abort |
291 | remoteClient.SendTeleportFailed("The teleport destination could not be found."); | 304 | remoteClient.SendTeleportFailed("The teleport destination could not be found."); |
292 | |||
293 | } | 305 | } |
294 | 306 | ||
295 | #endregion | 307 | #endregion |
@@ -304,49 +316,48 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
304 | IUserAgentService security = new UserAgentServiceConnector(url); | 316 | IUserAgentService security = new UserAgentServiceConnector(url); |
305 | return security.VerifyClient(aCircuit.SessionID, token); | 317 | return security.VerifyClient(aCircuit.SessionID, token); |
306 | } | 318 | } |
307 | else | 319 | else |
308 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent {0} {1} does not have a HomeURI OH NO!", aCircuit.firstname, aCircuit.lastname); | 320 | { |
321 | m_log.DebugFormat( | ||
322 | "[HG ENTITY TRANSFER MODULE]: Agent {0} {1} does not have a HomeURI OH NO!", | ||
323 | aCircuit.firstname, aCircuit.lastname); | ||
324 | } | ||
309 | 325 | ||
310 | return false; | 326 | return false; |
311 | } | 327 | } |
312 | 328 | ||
313 | void OnConnectionClosed(IClientAPI obj) | 329 | void OnConnectionClosed(IClientAPI obj) |
314 | { | 330 | { |
315 | if (obj.IsLoggingOut) | 331 | if (obj.SceneAgent.IsChildAgent) |
316 | { | 332 | return; |
317 | object sp = null; | ||
318 | if (obj.Scene.TryGetScenePresence(obj.AgentId, out sp)) | ||
319 | { | ||
320 | if (((ScenePresence)sp).IsChildAgent) | ||
321 | return; | ||
322 | } | ||
323 | 333 | ||
324 | // Let's find out if this is a foreign user or a local user | 334 | // Let's find out if this is a foreign user or a local user |
325 | IUserManagement uMan = m_aScene.RequestModuleInterface<IUserManagement>(); | 335 | IUserManagement uMan = Scene.RequestModuleInterface<IUserManagement>(); |
326 | UserAccount account = m_aScene.UserAccountService.GetUserAccount(m_aScene.RegionInfo.ScopeID, obj.AgentId); | 336 | // UserAccount account = Scene.UserAccountService.GetUserAccount(Scene.RegionInfo.ScopeID, obj.AgentId); |
327 | if (uMan != null && uMan.IsLocalGridUser(obj.AgentId)) | 337 | |
328 | { | 338 | if (uMan != null && uMan.IsLocalGridUser(obj.AgentId)) |
329 | // local grid user | 339 | { |
330 | return; | 340 | // local grid user |
331 | } | 341 | return; |
342 | } | ||
332 | 343 | ||
333 | AgentCircuitData aCircuit = ((Scene)(obj.Scene)).AuthenticateHandler.GetAgentCircuitData(obj.CircuitCode); | 344 | AgentCircuitData aCircuit = ((Scene)(obj.Scene)).AuthenticateHandler.GetAgentCircuitData(obj.CircuitCode); |
334 | 345 | ||
335 | if (aCircuit.ServiceURLs.ContainsKey("HomeURI")) | 346 | if (aCircuit.ServiceURLs.ContainsKey("HomeURI")) |
336 | { | 347 | { |
337 | string url = aCircuit.ServiceURLs["HomeURI"].ToString(); | 348 | string url = aCircuit.ServiceURLs["HomeURI"].ToString(); |
338 | IUserAgentService security = new UserAgentServiceConnector(url); | 349 | IUserAgentService security = new UserAgentServiceConnector(url); |
339 | security.LogoutAgent(obj.AgentId, obj.SessionId); | 350 | security.LogoutAgent(obj.AgentId, obj.SessionId); |
340 | //m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Sent logout call to UserAgentService @ {0}", url); | 351 | //m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Sent logout call to UserAgentService @ {0}", url); |
341 | } | 352 | } |
342 | else | 353 | else |
354 | { | ||
343 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: HomeURI not found for agent {0} logout", obj.AgentId); | 355 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: HomeURI not found for agent {0} logout", obj.AgentId); |
344 | } | 356 | } |
345 | } | 357 | } |
346 | 358 | ||
347 | #endregion | 359 | #endregion |
348 | 360 | ||
349 | |||
350 | private GridRegion MakeRegion(AgentCircuitData aCircuit) | 361 | private GridRegion MakeRegion(AgentCircuitData aCircuit) |
351 | { | 362 | { |
352 | GridRegion region = new GridRegion(); | 363 | GridRegion region = new GridRegion(); |
@@ -363,6 +374,5 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
363 | region.InternalEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse("0.0.0.0"), (int)0); | 374 | region.InternalEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse("0.0.0.0"), (int)0); |
364 | return region; | 375 | return region; |
365 | } | 376 | } |
366 | |||
367 | } | 377 | } |
368 | } | 378 | } \ No newline at end of file |
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs index a71584a..cf72b58 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs | |||
@@ -364,8 +364,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
364 | { | 364 | { |
365 | m_log.DebugFormat("[HG INVENTORY ACCESS MODULE]: Changing root inventory for user {0}", client.Name); | 365 | m_log.DebugFormat("[HG INVENTORY ACCESS MODULE]: Changing root inventory for user {0}", client.Name); |
366 | InventoryCollection content = m_Scene.InventoryService.GetFolderContent(client.AgentId, root.ID); | 366 | InventoryCollection content = m_Scene.InventoryService.GetFolderContent(client.AgentId, root.ID); |
367 | List<UUID> fids = new List<UUID>(); | 367 | |
368 | List<UUID> iids = new List<UUID>(); | ||
369 | List<InventoryFolderBase> keep = new List<InventoryFolderBase>(); | 368 | List<InventoryFolderBase> keep = new List<InventoryFolderBase>(); |
370 | 369 | ||
371 | foreach (InventoryFolderBase f in content.Folders) | 370 | foreach (InventoryFolderBase f in content.Folders) |
@@ -395,4 +394,4 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
395 | 394 | ||
396 | #endregion | 395 | #endregion |
397 | } | 396 | } |
398 | } | 397 | } \ No newline at end of file |
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index ee9961f..d30c2e2 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs | |||
@@ -175,7 +175,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
175 | sbyte assetType, | 175 | sbyte assetType, |
176 | byte wearableType, uint nextOwnerMask, int creationDate) | 176 | byte wearableType, uint nextOwnerMask, int creationDate) |
177 | { | 177 | { |
178 | m_log.DebugFormat("[AGENT INVENTORY]: Received request to create inventory item {0} in folder {1}", name, folderID); | 178 | m_log.DebugFormat("[INVENTORY ACCESS MODULE]: Received request to create inventory item {0} in folder {1}", name, folderID); |
179 | 179 | ||
180 | if (!m_Scene.Permissions.CanCreateUserInventory(invType, remoteClient.AgentId)) | 180 | if (!m_Scene.Permissions.CanCreateUserInventory(invType, remoteClient.AgentId)) |
181 | return; | 181 | return; |
@@ -210,13 +210,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
210 | else | 210 | else |
211 | { | 211 | { |
212 | m_log.ErrorFormat( | 212 | m_log.ErrorFormat( |
213 | "ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem", | 213 | "[INVENTORY ACCESS MODULE]: ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem", |
214 | remoteClient.AgentId); | 214 | remoteClient.AgentId); |
215 | } | 215 | } |
216 | } | 216 | } |
217 | else | 217 | else |
218 | { | 218 | { |
219 | IAgentAssetTransactions agentTransactions = m_Scene.RequestModuleInterface<IAgentAssetTransactions>(); | 219 | IAgentAssetTransactions agentTransactions = m_Scene.AgentTransactionsModule; |
220 | if (agentTransactions != null) | 220 | if (agentTransactions != null) |
221 | { | 221 | { |
222 | agentTransactions.HandleItemCreationFromTransaction( | 222 | agentTransactions.HandleItemCreationFromTransaction( |
@@ -288,16 +288,19 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
288 | else | 288 | else |
289 | { | 289 | { |
290 | m_log.ErrorFormat( | 290 | m_log.ErrorFormat( |
291 | "[AGENT INVENTORY]: Could not find item {0} for caps inventory update", | 291 | "[INVENTORY ACCESS MODULE]: Could not find item {0} for caps inventory update", |
292 | itemID); | 292 | itemID); |
293 | } | 293 | } |
294 | 294 | ||
295 | return UUID.Zero; | 295 | return UUID.Zero; |
296 | } | 296 | } |
297 | 297 | ||
298 | public virtual UUID CopyToInventory(DeRezAction action, UUID folderID, | 298 | public virtual List<InventoryItemBase> CopyToInventory( |
299 | List<SceneObjectGroup> objectGroups, IClientAPI remoteClient) | 299 | DeRezAction action, UUID folderID, |
300 | List<SceneObjectGroup> objectGroups, IClientAPI remoteClient, bool asAttachment) | ||
300 | { | 301 | { |
302 | List<InventoryItemBase> copiedItems = new List<InventoryItemBase>(); | ||
303 | |||
301 | Dictionary<UUID, List<SceneObjectGroup>> bundlesToCopy = new Dictionary<UUID, List<SceneObjectGroup>>(); | 304 | Dictionary<UUID, List<SceneObjectGroup>> bundlesToCopy = new Dictionary<UUID, List<SceneObjectGroup>>(); |
302 | 305 | ||
303 | if (CoalesceMultipleObjectsToInventory) | 306 | if (CoalesceMultipleObjectsToInventory) |
@@ -324,16 +327,16 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
324 | } | 327 | } |
325 | } | 328 | } |
326 | 329 | ||
327 | // This is method scoped and will be returned. It will be the | 330 | // m_log.DebugFormat( |
328 | // last created asset id | 331 | // "[INVENTORY ACCESS MODULE]: Copying {0} object bundles to folder {1} action {2} for {3}", |
329 | UUID assetID = UUID.Zero; | 332 | // bundlesToCopy.Count, folderID, action, remoteClient.Name); |
330 | 333 | ||
331 | // Each iteration is really a separate asset being created, | 334 | // Each iteration is really a separate asset being created, |
332 | // with distinct destinations as well. | 335 | // with distinct destinations as well. |
333 | foreach (List<SceneObjectGroup> bundle in bundlesToCopy.Values) | 336 | foreach (List<SceneObjectGroup> bundle in bundlesToCopy.Values) |
334 | assetID = CopyBundleToInventory(action, folderID, bundle, remoteClient); | 337 | copiedItems.Add(CopyBundleToInventory(action, folderID, bundle, remoteClient, asAttachment)); |
335 | 338 | ||
336 | return assetID; | 339 | return copiedItems; |
337 | } | 340 | } |
338 | 341 | ||
339 | /// <summary> | 342 | /// <summary> |
@@ -344,12 +347,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
344 | /// <param name="folderID"></param> | 347 | /// <param name="folderID"></param> |
345 | /// <param name="objlist"></param> | 348 | /// <param name="objlist"></param> |
346 | /// <param name="remoteClient"></param> | 349 | /// <param name="remoteClient"></param> |
347 | /// <returns></returns> | 350 | /// <param name="asAttachment">Should be true if the bundle is being copied as an attachment. This prevents |
348 | protected UUID CopyBundleToInventory( | 351 | /// attempted serialization of any script state which would abort any operating scripts.</param> |
349 | DeRezAction action, UUID folderID, List<SceneObjectGroup> objlist, IClientAPI remoteClient) | 352 | /// <returns>The inventory item created by the copy</returns> |
353 | protected InventoryItemBase CopyBundleToInventory( | ||
354 | DeRezAction action, UUID folderID, List<SceneObjectGroup> objlist, IClientAPI remoteClient, | ||
355 | bool asAttachment) | ||
350 | { | 356 | { |
351 | UUID assetID = UUID.Zero; | ||
352 | |||
353 | CoalescedSceneObjects coa = new CoalescedSceneObjects(UUID.Zero); | 357 | CoalescedSceneObjects coa = new CoalescedSceneObjects(UUID.Zero); |
354 | Dictionary<UUID, Vector3> originalPositions = new Dictionary<UUID, Vector3>(); | 358 | Dictionary<UUID, Vector3> originalPositions = new Dictionary<UUID, Vector3>(); |
355 | 359 | ||
@@ -401,18 +405,27 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
401 | 405 | ||
402 | string itemXml; | 406 | string itemXml; |
403 | 407 | ||
408 | // If we're being called from a script, then trying to serialize that same script's state will not complete | ||
409 | // in any reasonable time period. Therefore, we'll avoid it. The worst that can happen is that if | ||
410 | // the client/server crashes rather than logging out normally, the attachment's scripts will resume | ||
411 | // without state on relog. Arguably, this is what we want anyway. | ||
404 | if (objlist.Count > 1) | 412 | if (objlist.Count > 1) |
405 | itemXml = CoalescedSceneObjectsSerializer.ToXml(coa); | 413 | itemXml = CoalescedSceneObjectsSerializer.ToXml(coa, !asAttachment); |
406 | else | 414 | else |
407 | itemXml = SceneObjectSerializer.ToOriginalXmlFormat(objlist[0]); | 415 | itemXml = SceneObjectSerializer.ToOriginalXmlFormat(objlist[0], !asAttachment); |
408 | 416 | ||
409 | // Restore the position of each group now that it has been stored to inventory. | 417 | // Restore the position of each group now that it has been stored to inventory. |
410 | foreach (SceneObjectGroup objectGroup in objlist) | 418 | foreach (SceneObjectGroup objectGroup in objlist) |
411 | objectGroup.AbsolutePosition = originalPositions[objectGroup.UUID]; | 419 | objectGroup.AbsolutePosition = originalPositions[objectGroup.UUID]; |
412 | 420 | ||
413 | InventoryItemBase item = CreateItemForObject(action, remoteClient, objlist[0], folderID); | 421 | InventoryItemBase item = CreateItemForObject(action, remoteClient, objlist[0], folderID); |
422 | |||
423 | // m_log.DebugFormat( | ||
424 | // "[INVENTORY ACCESS MODULE]: Created item is {0}", | ||
425 | // item != null ? item.ID.ToString() : "NULL"); | ||
426 | |||
414 | if (item == null) | 427 | if (item == null) |
415 | return UUID.Zero; | 428 | return null; |
416 | 429 | ||
417 | // Can't know creator is the same, so null it in inventory | 430 | // Can't know creator is the same, so null it in inventory |
418 | if (objlist.Count > 1) | 431 | if (objlist.Count > 1) |
@@ -422,7 +435,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
422 | } | 435 | } |
423 | else | 436 | else |
424 | { | 437 | { |
425 | item.CreatorId = objlist[0].RootPart.CreatorID.ToString(); | 438 | item.CreatorId = objlist[0].RootPart.CreatorID.ToString(); |
439 | item.CreatorData = objlist[0].RootPart.CreatorData; | ||
426 | item.SaleType = objlist[0].RootPart.ObjectSaleType; | 440 | item.SaleType = objlist[0].RootPart.ObjectSaleType; |
427 | item.SalePrice = objlist[0].RootPart.SalePrice; | 441 | item.SalePrice = objlist[0].RootPart.SalePrice; |
428 | } | 442 | } |
@@ -435,8 +449,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
435 | objlist[0].OwnerID.ToString()); | 449 | objlist[0].OwnerID.ToString()); |
436 | m_Scene.AssetService.Store(asset); | 450 | m_Scene.AssetService.Store(asset); |
437 | 451 | ||
438 | item.AssetID = asset.FullID; | 452 | item.AssetID = asset.FullID; |
439 | assetID = asset.FullID; | ||
440 | 453 | ||
441 | if (DeRezAction.SaveToExistingUserInventoryItem == action) | 454 | if (DeRezAction.SaveToExistingUserInventoryItem == action) |
442 | { | 455 | { |
@@ -469,9 +482,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
469 | 482 | ||
470 | // This is a hook to do some per-asset post-processing for subclasses that need that | 483 | // This is a hook to do some per-asset post-processing for subclasses that need that |
471 | if (remoteClient != null) | 484 | if (remoteClient != null) |
472 | ExportAsset(remoteClient.AgentId, assetID); | 485 | ExportAsset(remoteClient.AgentId, asset.FullID); |
473 | 486 | ||
474 | return assetID; | 487 | return item; |
475 | } | 488 | } |
476 | 489 | ||
477 | protected virtual void ExportAsset(UUID agentID, UUID assetID) | 490 | protected virtual void ExportAsset(UUID agentID, UUID assetID) |
@@ -617,7 +630,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
617 | if (null == item) | 630 | if (null == item) |
618 | { | 631 | { |
619 | m_log.DebugFormat( | 632 | m_log.DebugFormat( |
620 | "[AGENT INVENTORY]: Object {0} {1} scheduled for save to inventory has already been deleted.", | 633 | "[INVENTORY ACCESS MODULE]: Object {0} {1} scheduled for save to inventory has already been deleted.", |
621 | so.Name, so.UUID); | 634 | so.Name, so.UUID); |
622 | 635 | ||
623 | return null; | 636 | return null; |
@@ -668,7 +681,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
668 | { | 681 | { |
669 | // Catch all. Use lost & found | 682 | // Catch all. Use lost & found |
670 | // | 683 | // |
671 | |||
672 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); | 684 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); |
673 | } | 685 | } |
674 | } | 686 | } |
@@ -718,7 +730,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
718 | 730 | ||
719 | if (item == null) | 731 | if (item == null) |
720 | { | 732 | { |
721 | |||
722 | return null; | 733 | return null; |
723 | } | 734 | } |
724 | 735 | ||
@@ -748,7 +759,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
748 | else | 759 | else |
749 | { | 760 | { |
750 | m_log.WarnFormat( | 761 | m_log.WarnFormat( |
751 | "[InventoryAccessModule]: Could not find asset {0} for {1} in RezObject()", | 762 | "[INVENTORY ACCESS MODULE]: Could not find asset {0} for {1} in RezObject()", |
752 | assetID, remoteClient.Name); | 763 | assetID, remoteClient.Name); |
753 | } | 764 | } |
754 | 765 | ||
@@ -859,7 +870,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
859 | SceneObjectPart rootPart = group.RootPart; | 870 | SceneObjectPart rootPart = group.RootPart; |
860 | 871 | ||
861 | // m_log.DebugFormat( | 872 | // m_log.DebugFormat( |
862 | // "[InventoryAccessModule]: Preparing to rez {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}", | 873 | // "[INVENTORY ACCESS MODULE]: Preparing to rez {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}", |
863 | // group.Name, group.LocalId, group.UUID, | 874 | // group.Name, group.LocalId, group.UUID, |
864 | // group.RootPart.OwnerMask, group.RootPart.NextOwnerMask, group.RootPart.GroupMask, group.RootPart.EveryoneMask, | 875 | // group.RootPart.OwnerMask, group.RootPart.NextOwnerMask, group.RootPart.GroupMask, group.RootPart.EveryoneMask, |
865 | // remoteClient.Name); | 876 | // remoteClient.Name); |
@@ -867,7 +878,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
867 | // Vector3 storedPosition = group.AbsolutePosition; | 878 | // Vector3 storedPosition = group.AbsolutePosition; |
868 | if (group.UUID == UUID.Zero) | 879 | if (group.UUID == UUID.Zero) |
869 | { | 880 | { |
870 | m_log.Debug("[InventoryAccessModule]: Object has UUID.Zero! Position 3"); | 881 | m_log.Debug("[INVENTORY ACCESS MODULE]: Object has UUID.Zero! Position 3"); |
871 | } | 882 | } |
872 | 883 | ||
873 | foreach (SceneObjectPart part in group.Parts) | 884 | foreach (SceneObjectPart part in group.Parts) |
@@ -928,7 +939,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
928 | } | 939 | } |
929 | 940 | ||
930 | // m_log.DebugFormat( | 941 | // m_log.DebugFormat( |
931 | // "[InventoryAccessModule]: Rezzed {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}", | 942 | // "[INVENTORY ACCESS MODULE]: Rezzed {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}", |
932 | // group.Name, group.LocalId, group.UUID, | 943 | // group.Name, group.LocalId, group.UUID, |
933 | // group.RootPart.OwnerMask, group.RootPart.NextOwnerMask, group.RootPart.GroupMask, group.RootPart.EveryoneMask, | 944 | // group.RootPart.OwnerMask, group.RootPart.NextOwnerMask, group.RootPart.GroupMask, group.RootPart.EveryoneMask, |
934 | // remoteClient.Name); | 945 | // remoteClient.Name); |
@@ -1023,8 +1034,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
1023 | 1034 | ||
1024 | so.FromFolderID = item.Folder; | 1035 | so.FromFolderID = item.Folder; |
1025 | 1036 | ||
1026 | // Console.WriteLine("rootPart.OwnedID {0}, item.Owner {1}, item.CurrentPermissions {2:X}", | 1037 | // m_log.DebugFormat( |
1027 | // rootPart.OwnerID, item.Owner, item.CurrentPermissions); | 1038 | // "[INVENTORY ACCESS MODULE]: rootPart.OwnedID {0}, item.Owner {1}, item.CurrentPermissions {2:X}", |
1039 | // rootPart.OwnerID, item.Owner, item.CurrentPermissions); | ||
1028 | 1040 | ||
1029 | if ((rootPart.OwnerID != item.Owner) || | 1041 | if ((rootPart.OwnerID != item.Owner) || |
1030 | (item.CurrentPermissions & 16) != 0 || | 1042 | (item.CurrentPermissions & 16) != 0 || |
@@ -1160,7 +1172,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
1160 | if (assetRequestItem.AssetID != requestID) | 1172 | if (assetRequestItem.AssetID != requestID) |
1161 | { | 1173 | { |
1162 | m_log.WarnFormat( | 1174 | m_log.WarnFormat( |
1163 | "[CLIENT]: {0} requested asset {1} from item {2} but this does not match item's asset {3}", | 1175 | "[INVENTORY ACCESS MODULE]: {0} requested asset {1} from item {2} but this does not match item's asset {3}", |
1164 | Name, requestID, itemID, assetRequestItem.AssetID); | 1176 | Name, requestID, itemID, assetRequestItem.AssetID); |
1165 | 1177 | ||
1166 | return false; | 1178 | return false; |
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs index e74310c..21d8bd7 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs | |||
@@ -64,8 +64,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests | |||
64 | IConfigSource config = new IniConfigSource(); | 64 | IConfigSource config = new IniConfigSource(); |
65 | config.AddConfig("Modules"); | 65 | config.AddConfig("Modules"); |
66 | config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule"); | 66 | config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule"); |
67 | 67 | ||
68 | m_scene = SceneHelpers.SetupScene(); | 68 | SceneHelpers sceneHelpers = new SceneHelpers(); |
69 | m_scene = sceneHelpers.SetupScene(); | ||
69 | SceneHelpers.SetupSceneModules(m_scene, config, m_iam); | 70 | SceneHelpers.SetupSceneModules(m_scene, config, m_iam); |
70 | 71 | ||
71 | // Create user | 72 | // Create user |
@@ -76,7 +77,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests | |||
76 | 77 | ||
77 | AgentCircuitData acd = new AgentCircuitData(); | 78 | AgentCircuitData acd = new AgentCircuitData(); |
78 | acd.AgentID = m_userId; | 79 | acd.AgentID = m_userId; |
79 | m_tc = new TestClient(acd, m_scene); | 80 | m_tc = new TestClient(acd, m_scene); |
80 | } | 81 | } |
81 | 82 | ||
82 | [Test] | 83 | [Test] |
diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs index 7f8271d..e135c21 100644 --- a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs +++ b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs | |||
@@ -49,7 +49,16 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
49 | public bool Enabled { get; private set; } | 49 | public bool Enabled { get; private set; } |
50 | 50 | ||
51 | private Scene m_scene; | 51 | private Scene m_scene; |
52 | private readonly List<IMonitor> m_monitors = new List<IMonitor>(); | 52 | |
53 | /// <summary> | ||
54 | /// These are monitors where we know the static details in advance. | ||
55 | /// </summary> | ||
56 | /// <remarks> | ||
57 | /// Dynamic monitors also exist (we don't know any of the details of what stats we get back here) | ||
58 | /// but these are currently hardcoded. | ||
59 | /// </remarks> | ||
60 | private readonly List<IMonitor> m_staticMonitors = new List<IMonitor>(); | ||
61 | |||
53 | private readonly List<IAlert> m_alerts = new List<IAlert>(); | 62 | private readonly List<IAlert> m_alerts = new List<IAlert>(); |
54 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 63 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
55 | 64 | ||
@@ -84,9 +93,18 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
84 | 93 | ||
85 | public void DebugMonitors(string module, string[] args) | 94 | public void DebugMonitors(string module, string[] args) |
86 | { | 95 | { |
87 | foreach (IMonitor monitor in m_monitors) | 96 | foreach (IMonitor monitor in m_staticMonitors) |
88 | { | 97 | { |
89 | m_log.Info("[MonitorModule]: " + m_scene.RegionInfo.RegionName + " reports " + monitor.GetFriendlyName() + " = " + monitor.GetFriendlyValue()); | 98 | m_log.InfoFormat( |
99 | "[MONITOR MODULE]: {0} reports {1} = {2}", | ||
100 | m_scene.RegionInfo.RegionName, monitor.GetFriendlyName(), monitor.GetFriendlyValue()); | ||
101 | } | ||
102 | |||
103 | foreach (KeyValuePair<string, float> tuple in m_scene.StatsReporter.GetExtraSimStats()) | ||
104 | { | ||
105 | m_log.InfoFormat( | ||
106 | "[MONITOR MODULE]: {0} reports {1} = {2}", | ||
107 | m_scene.RegionInfo.RegionName, tuple.Key, tuple.Value); | ||
90 | } | 108 | } |
91 | } | 109 | } |
92 | 110 | ||
@@ -106,11 +124,12 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
106 | { | 124 | { |
107 | string monID = (string) request["monitor"]; | 125 | string monID = (string) request["monitor"]; |
108 | 126 | ||
109 | foreach (IMonitor monitor in m_monitors) | 127 | foreach (IMonitor monitor in m_staticMonitors) |
110 | { | 128 | { |
111 | string elemName = monitor.ToString(); | 129 | string elemName = monitor.ToString(); |
112 | if (elemName.StartsWith(monitor.GetType().Namespace)) | 130 | if (elemName.StartsWith(monitor.GetType().Namespace)) |
113 | elemName = elemName.Substring(monitor.GetType().Namespace.Length + 1); | 131 | elemName = elemName.Substring(monitor.GetType().Namespace.Length + 1); |
132 | |||
114 | if (elemName == monID || monitor.ToString() == monID) | 133 | if (elemName == monID || monitor.ToString() == monID) |
115 | { | 134 | { |
116 | Hashtable ereply3 = new Hashtable(); | 135 | Hashtable ereply3 = new Hashtable(); |
@@ -123,6 +142,9 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
123 | } | 142 | } |
124 | } | 143 | } |
125 | 144 | ||
145 | // FIXME: Arguably this should also be done with dynamic monitors but I'm not sure what the above code | ||
146 | // is even doing. Why are we inspecting the type of the monitor??? | ||
147 | |||
126 | // No monitor with that name | 148 | // No monitor with that name |
127 | Hashtable ereply2 = new Hashtable(); | 149 | Hashtable ereply2 = new Hashtable(); |
128 | 150 | ||
@@ -134,12 +156,18 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
134 | } | 156 | } |
135 | 157 | ||
136 | string xml = "<data>"; | 158 | string xml = "<data>"; |
137 | foreach (IMonitor monitor in m_monitors) | 159 | foreach (IMonitor monitor in m_staticMonitors) |
138 | { | 160 | { |
139 | string elemName = monitor.GetName(); | 161 | string elemName = monitor.GetName(); |
140 | xml += "<" + elemName + ">" + monitor.GetValue().ToString() + "</" + elemName + ">"; | 162 | xml += "<" + elemName + ">" + monitor.GetValue().ToString() + "</" + elemName + ">"; |
141 | // m_log.DebugFormat("[MONITOR MODULE]: {0} = {1}", elemName, monitor.GetValue()); | 163 | // m_log.DebugFormat("[MONITOR MODULE]: {0} = {1}", elemName, monitor.GetValue()); |
142 | } | 164 | } |
165 | |||
166 | foreach (KeyValuePair<string, float> tuple in m_scene.StatsReporter.GetExtraSimStats()) | ||
167 | { | ||
168 | xml += "<" + tuple.Key + ">" + tuple.Value + "</" + tuple.Key + ">"; | ||
169 | } | ||
170 | |||
143 | xml += "</data>"; | 171 | xml += "</data>"; |
144 | 172 | ||
145 | Hashtable ereply = new Hashtable(); | 173 | Hashtable ereply = new Hashtable(); |
@@ -156,20 +184,20 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
156 | if (!Enabled) | 184 | if (!Enabled) |
157 | return; | 185 | return; |
158 | 186 | ||
159 | m_monitors.Add(new AgentCountMonitor(m_scene)); | 187 | m_staticMonitors.Add(new AgentCountMonitor(m_scene)); |
160 | m_monitors.Add(new ChildAgentCountMonitor(m_scene)); | 188 | m_staticMonitors.Add(new ChildAgentCountMonitor(m_scene)); |
161 | m_monitors.Add(new GCMemoryMonitor()); | 189 | m_staticMonitors.Add(new GCMemoryMonitor()); |
162 | m_monitors.Add(new ObjectCountMonitor(m_scene)); | 190 | m_staticMonitors.Add(new ObjectCountMonitor(m_scene)); |
163 | m_monitors.Add(new PhysicsFrameMonitor(m_scene)); | 191 | m_staticMonitors.Add(new PhysicsFrameMonitor(m_scene)); |
164 | m_monitors.Add(new PhysicsUpdateFrameMonitor(m_scene)); | 192 | m_staticMonitors.Add(new PhysicsUpdateFrameMonitor(m_scene)); |
165 | m_monitors.Add(new PWSMemoryMonitor()); | 193 | m_staticMonitors.Add(new PWSMemoryMonitor()); |
166 | m_monitors.Add(new ThreadCountMonitor()); | 194 | m_staticMonitors.Add(new ThreadCountMonitor()); |
167 | m_monitors.Add(new TotalFrameMonitor(m_scene)); | 195 | m_staticMonitors.Add(new TotalFrameMonitor(m_scene)); |
168 | m_monitors.Add(new EventFrameMonitor(m_scene)); | 196 | m_staticMonitors.Add(new EventFrameMonitor(m_scene)); |
169 | m_monitors.Add(new LandFrameMonitor(m_scene)); | 197 | m_staticMonitors.Add(new LandFrameMonitor(m_scene)); |
170 | m_monitors.Add(new LastFrameTimeMonitor(m_scene)); | 198 | m_staticMonitors.Add(new LastFrameTimeMonitor(m_scene)); |
171 | 199 | ||
172 | m_monitors.Add( | 200 | m_staticMonitors.Add( |
173 | new GenericMonitor( | 201 | new GenericMonitor( |
174 | m_scene, | 202 | m_scene, |
175 | "TimeDilationMonitor", | 203 | "TimeDilationMonitor", |
@@ -177,7 +205,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
177 | m => m.Scene.StatsReporter.LastReportedSimStats[0], | 205 | m => m.Scene.StatsReporter.LastReportedSimStats[0], |
178 | m => m.GetValue().ToString())); | 206 | m => m.GetValue().ToString())); |
179 | 207 | ||
180 | m_monitors.Add( | 208 | m_staticMonitors.Add( |
181 | new GenericMonitor( | 209 | new GenericMonitor( |
182 | m_scene, | 210 | m_scene, |
183 | "SimFPSMonitor", | 211 | "SimFPSMonitor", |
@@ -185,7 +213,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
185 | m => m.Scene.StatsReporter.LastReportedSimStats[1], | 213 | m => m.Scene.StatsReporter.LastReportedSimStats[1], |
186 | m => string.Format("{0}", m.GetValue()))); | 214 | m => string.Format("{0}", m.GetValue()))); |
187 | 215 | ||
188 | m_monitors.Add( | 216 | m_staticMonitors.Add( |
189 | new GenericMonitor( | 217 | new GenericMonitor( |
190 | m_scene, | 218 | m_scene, |
191 | "PhysicsFPSMonitor", | 219 | "PhysicsFPSMonitor", |
@@ -193,7 +221,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
193 | m => m.Scene.StatsReporter.LastReportedSimStats[2], | 221 | m => m.Scene.StatsReporter.LastReportedSimStats[2], |
194 | m => string.Format("{0}", m.GetValue()))); | 222 | m => string.Format("{0}", m.GetValue()))); |
195 | 223 | ||
196 | m_monitors.Add( | 224 | m_staticMonitors.Add( |
197 | new GenericMonitor( | 225 | new GenericMonitor( |
198 | m_scene, | 226 | m_scene, |
199 | "AgentUpdatesPerSecondMonitor", | 227 | "AgentUpdatesPerSecondMonitor", |
@@ -201,15 +229,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
201 | m => m.Scene.StatsReporter.LastReportedSimStats[3], | 229 | m => m.Scene.StatsReporter.LastReportedSimStats[3], |
202 | m => string.Format("{0} per second", m.GetValue()))); | 230 | m => string.Format("{0} per second", m.GetValue()))); |
203 | 231 | ||
204 | m_monitors.Add( | 232 | m_staticMonitors.Add( |
205 | new GenericMonitor( | ||
206 | m_scene, | ||
207 | "ObjectUpdatesPerSecondMonitor", | ||
208 | "Object Updates", | ||
209 | m => m.Scene.StatsReporter.LastReportedObjectUpdates, | ||
210 | m => string.Format("{0} per second", m.GetValue()))); | ||
211 | |||
212 | m_monitors.Add( | ||
213 | new GenericMonitor( | 233 | new GenericMonitor( |
214 | m_scene, | 234 | m_scene, |
215 | "ActiveObjectCountMonitor", | 235 | "ActiveObjectCountMonitor", |
@@ -217,7 +237,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
217 | m => m.Scene.StatsReporter.LastReportedSimStats[7], | 237 | m => m.Scene.StatsReporter.LastReportedSimStats[7], |
218 | m => string.Format("{0}", m.GetValue()))); | 238 | m => string.Format("{0}", m.GetValue()))); |
219 | 239 | ||
220 | m_monitors.Add( | 240 | m_staticMonitors.Add( |
221 | new GenericMonitor( | 241 | new GenericMonitor( |
222 | m_scene, | 242 | m_scene, |
223 | "ActiveScriptsMonitor", | 243 | "ActiveScriptsMonitor", |
@@ -225,7 +245,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
225 | m => m.Scene.StatsReporter.LastReportedSimStats[19], | 245 | m => m.Scene.StatsReporter.LastReportedSimStats[19], |
226 | m => string.Format("{0}", m.GetValue()))); | 246 | m => string.Format("{0}", m.GetValue()))); |
227 | 247 | ||
228 | m_monitors.Add( | 248 | m_staticMonitors.Add( |
229 | new GenericMonitor( | 249 | new GenericMonitor( |
230 | m_scene, | 250 | m_scene, |
231 | "ScriptEventsPerSecondMonitor", | 251 | "ScriptEventsPerSecondMonitor", |
@@ -233,7 +253,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
233 | m => m.Scene.StatsReporter.LastReportedSimStats[20], | 253 | m => m.Scene.StatsReporter.LastReportedSimStats[20], |
234 | m => string.Format("{0} per second", m.GetValue()))); | 254 | m => string.Format("{0} per second", m.GetValue()))); |
235 | 255 | ||
236 | m_monitors.Add( | 256 | m_staticMonitors.Add( |
237 | new GenericMonitor( | 257 | new GenericMonitor( |
238 | m_scene, | 258 | m_scene, |
239 | "InPacketsPerSecondMonitor", | 259 | "InPacketsPerSecondMonitor", |
@@ -241,7 +261,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
241 | m => m.Scene.StatsReporter.LastReportedSimStats[13], | 261 | m => m.Scene.StatsReporter.LastReportedSimStats[13], |
242 | m => string.Format("{0} per second", m.GetValue()))); | 262 | m => string.Format("{0} per second", m.GetValue()))); |
243 | 263 | ||
244 | m_monitors.Add( | 264 | m_staticMonitors.Add( |
245 | new GenericMonitor( | 265 | new GenericMonitor( |
246 | m_scene, | 266 | m_scene, |
247 | "OutPacketsPerSecondMonitor", | 267 | "OutPacketsPerSecondMonitor", |
@@ -249,7 +269,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
249 | m => m.Scene.StatsReporter.LastReportedSimStats[14], | 269 | m => m.Scene.StatsReporter.LastReportedSimStats[14], |
250 | m => string.Format("{0} per second", m.GetValue()))); | 270 | m => string.Format("{0} per second", m.GetValue()))); |
251 | 271 | ||
252 | m_monitors.Add( | 272 | m_staticMonitors.Add( |
253 | new GenericMonitor( | 273 | new GenericMonitor( |
254 | m_scene, | 274 | m_scene, |
255 | "UnackedBytesMonitor", | 275 | "UnackedBytesMonitor", |
@@ -257,7 +277,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
257 | m => m.Scene.StatsReporter.LastReportedSimStats[15], | 277 | m => m.Scene.StatsReporter.LastReportedSimStats[15], |
258 | m => string.Format("{0}", m.GetValue()))); | 278 | m => string.Format("{0}", m.GetValue()))); |
259 | 279 | ||
260 | m_monitors.Add( | 280 | m_staticMonitors.Add( |
261 | new GenericMonitor( | 281 | new GenericMonitor( |
262 | m_scene, | 282 | m_scene, |
263 | "PendingDownloadsMonitor", | 283 | "PendingDownloadsMonitor", |
@@ -265,7 +285,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
265 | m => m.Scene.StatsReporter.LastReportedSimStats[17], | 285 | m => m.Scene.StatsReporter.LastReportedSimStats[17], |
266 | m => string.Format("{0}", m.GetValue()))); | 286 | m => string.Format("{0}", m.GetValue()))); |
267 | 287 | ||
268 | m_monitors.Add( | 288 | m_staticMonitors.Add( |
269 | new GenericMonitor( | 289 | new GenericMonitor( |
270 | m_scene, | 290 | m_scene, |
271 | "PendingUploadsMonitor", | 291 | "PendingUploadsMonitor", |
@@ -273,7 +293,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
273 | m => m.Scene.StatsReporter.LastReportedSimStats[18], | 293 | m => m.Scene.StatsReporter.LastReportedSimStats[18], |
274 | m => string.Format("{0}", m.GetValue()))); | 294 | m => string.Format("{0}", m.GetValue()))); |
275 | 295 | ||
276 | m_monitors.Add( | 296 | m_staticMonitors.Add( |
277 | new GenericMonitor( | 297 | new GenericMonitor( |
278 | m_scene, | 298 | m_scene, |
279 | "TotalFrameTimeMonitor", | 299 | "TotalFrameTimeMonitor", |
@@ -281,7 +301,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
281 | m => m.Scene.StatsReporter.LastReportedSimStats[8], | 301 | m => m.Scene.StatsReporter.LastReportedSimStats[8], |
282 | m => string.Format("{0} ms", m.GetValue()))); | 302 | m => string.Format("{0} ms", m.GetValue()))); |
283 | 303 | ||
284 | m_monitors.Add( | 304 | m_staticMonitors.Add( |
285 | new GenericMonitor( | 305 | new GenericMonitor( |
286 | m_scene, | 306 | m_scene, |
287 | "NetFrameTimeMonitor", | 307 | "NetFrameTimeMonitor", |
@@ -289,7 +309,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
289 | m => m.Scene.StatsReporter.LastReportedSimStats[9], | 309 | m => m.Scene.StatsReporter.LastReportedSimStats[9], |
290 | m => string.Format("{0} ms", m.GetValue()))); | 310 | m => string.Format("{0} ms", m.GetValue()))); |
291 | 311 | ||
292 | m_monitors.Add( | 312 | m_staticMonitors.Add( |
293 | new GenericMonitor( | 313 | new GenericMonitor( |
294 | m_scene, | 314 | m_scene, |
295 | "PhysicsFrameTimeMonitor", | 315 | "PhysicsFrameTimeMonitor", |
@@ -297,7 +317,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
297 | m => m.Scene.StatsReporter.LastReportedSimStats[10], | 317 | m => m.Scene.StatsReporter.LastReportedSimStats[10], |
298 | m => string.Format("{0} ms", m.GetValue()))); | 318 | m => string.Format("{0} ms", m.GetValue()))); |
299 | 319 | ||
300 | m_monitors.Add( | 320 | m_staticMonitors.Add( |
301 | new GenericMonitor( | 321 | new GenericMonitor( |
302 | m_scene, | 322 | m_scene, |
303 | "SimulationFrameTimeMonitor", | 323 | "SimulationFrameTimeMonitor", |
@@ -305,7 +325,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
305 | m => m.Scene.StatsReporter.LastReportedSimStats[12], | 325 | m => m.Scene.StatsReporter.LastReportedSimStats[12], |
306 | m => string.Format("{0} ms", m.GetValue()))); | 326 | m => string.Format("{0} ms", m.GetValue()))); |
307 | 327 | ||
308 | m_monitors.Add( | 328 | m_staticMonitors.Add( |
309 | new GenericMonitor( | 329 | new GenericMonitor( |
310 | m_scene, | 330 | m_scene, |
311 | "AgentFrameTimeMonitor", | 331 | "AgentFrameTimeMonitor", |
@@ -313,7 +333,7 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
313 | m => m.Scene.StatsReporter.LastReportedSimStats[16], | 333 | m => m.Scene.StatsReporter.LastReportedSimStats[16], |
314 | m => string.Format("{0} ms", m.GetValue()))); | 334 | m => string.Format("{0} ms", m.GetValue()))); |
315 | 335 | ||
316 | m_monitors.Add( | 336 | m_staticMonitors.Add( |
317 | new GenericMonitor( | 337 | new GenericMonitor( |
318 | m_scene, | 338 | m_scene, |
319 | "ImagesFrameTimeMonitor", | 339 | "ImagesFrameTimeMonitor", |
@@ -321,7 +341,15 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring | |||
321 | m => m.Scene.StatsReporter.LastReportedSimStats[11], | 341 | m => m.Scene.StatsReporter.LastReportedSimStats[11], |
322 | m => string.Format("{0} ms", m.GetValue()))); | 342 | m => string.Format("{0} ms", m.GetValue()))); |
323 | 343 | ||
324 | m_alerts.Add(new DeadlockAlert(m_monitors.Find(x => x is LastFrameTimeMonitor) as LastFrameTimeMonitor)); | 344 | m_staticMonitors.Add( |
345 | new GenericMonitor( | ||
346 | m_scene, | ||
347 | "SpareFrameTimeMonitor", | ||
348 | "Spare Frame Time", | ||
349 | m => m.Scene.StatsReporter.LastReportedSimStats[21], | ||
350 | m => string.Format("{0} ms", m.GetValue()))); | ||
351 | |||
352 | m_alerts.Add(new DeadlockAlert(m_staticMonitors.Find(x => x is LastFrameTimeMonitor) as LastFrameTimeMonitor)); | ||
325 | 353 | ||
326 | foreach (IAlert alert in m_alerts) | 354 | foreach (IAlert alert in m_alerts) |
327 | { | 355 | { |
diff --git a/OpenSim/Region/CoreModules/LightShare/EnvironmentModule.cs b/OpenSim/Region/CoreModules/LightShare/EnvironmentModule.cs new file mode 100644 index 0000000..1526886 --- /dev/null +++ b/OpenSim/Region/CoreModules/LightShare/EnvironmentModule.cs | |||
@@ -0,0 +1,224 @@ | |||
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 | |||
28 | using System; | ||
29 | using System.Reflection; | ||
30 | using OpenMetaverse; | ||
31 | using OpenSim.Framework; | ||
32 | using OpenSim.Framework.Capabilities; | ||
33 | using OpenSim.Framework.Servers.HttpServer; | ||
34 | using OpenSim.Region.Framework.Interfaces; | ||
35 | using OpenSim.Region.Framework.Scenes; | ||
36 | using log4net; | ||
37 | using Nini.Config; | ||
38 | using Mono.Addins; | ||
39 | |||
40 | using Caps = OpenSim.Framework.Capabilities.Caps; | ||
41 | |||
42 | |||
43 | namespace OpenSim.Region.CoreModules.World.LightShare | ||
44 | { | ||
45 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "EnvironmentModule")] | ||
46 | |||
47 | public class EnvironmentModule : INonSharedRegionModule, IEnvironmentModule | ||
48 | { | ||
49 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
50 | |||
51 | private Scene m_scene = null; | ||
52 | private UUID regionID = UUID.Zero; | ||
53 | private static bool Enabled = false; | ||
54 | |||
55 | private static readonly string capsName = "EnvironmentSettings"; | ||
56 | private static readonly string capsBase = "/CAPS/0020/"; | ||
57 | |||
58 | private LLSDEnvironmentSetResponse setResponse = null; | ||
59 | |||
60 | #region INonSharedRegionModule | ||
61 | public void Initialise(IConfigSource source) | ||
62 | { | ||
63 | IConfig config = source.Configs["ClientStack.LindenCaps"]; | ||
64 | |||
65 | if (null == config) | ||
66 | return; | ||
67 | |||
68 | if (config.GetString("Cap_EnvironmentSettings", String.Empty) != "localhost") | ||
69 | { | ||
70 | m_log.InfoFormat("[{0}]: Module is disabled.", Name); | ||
71 | return; | ||
72 | } | ||
73 | |||
74 | Enabled = true; | ||
75 | |||
76 | m_log.InfoFormat("[{0}]: Module is enabled.", Name); | ||
77 | } | ||
78 | |||
79 | public void Close() | ||
80 | { | ||
81 | } | ||
82 | |||
83 | public string Name | ||
84 | { | ||
85 | get { return "EnvironmentModule"; } | ||
86 | } | ||
87 | |||
88 | public Type ReplaceableInterface | ||
89 | { | ||
90 | get { return null; } | ||
91 | } | ||
92 | |||
93 | public void AddRegion(Scene scene) | ||
94 | { | ||
95 | if (!Enabled) | ||
96 | return; | ||
97 | |||
98 | scene.RegisterModuleInterface<IEnvironmentModule>(this); | ||
99 | m_scene = scene; | ||
100 | regionID = scene.RegionInfo.RegionID; | ||
101 | } | ||
102 | |||
103 | public void RegionLoaded(Scene scene) | ||
104 | { | ||
105 | if (!Enabled) | ||
106 | return; | ||
107 | |||
108 | setResponse = new LLSDEnvironmentSetResponse(); | ||
109 | scene.EventManager.OnRegisterCaps += OnRegisterCaps; | ||
110 | } | ||
111 | |||
112 | public void RemoveRegion(Scene scene) | ||
113 | { | ||
114 | if (Enabled) | ||
115 | return; | ||
116 | |||
117 | scene.EventManager.OnRegisterCaps -= OnRegisterCaps; | ||
118 | m_scene = null; | ||
119 | } | ||
120 | #endregion | ||
121 | |||
122 | #region IEnvironmentModule | ||
123 | public void ResetEnvironmentSettings(UUID regionUUID) | ||
124 | { | ||
125 | if (!Enabled) | ||
126 | return; | ||
127 | |||
128 | m_scene.SimulationDataService.RemoveRegionEnvironmentSettings(regionUUID); | ||
129 | } | ||
130 | #endregion | ||
131 | |||
132 | #region Events | ||
133 | private void OnRegisterCaps(UUID agentID, Caps caps) | ||
134 | { | ||
135 | // m_log.DebugFormat("[{0}]: Register capability for agentID {1} in region {2}", | ||
136 | // Name, agentID, caps.RegionName); | ||
137 | |||
138 | string capsPath = capsBase + UUID.Random(); | ||
139 | |||
140 | // Get handler | ||
141 | caps.RegisterHandler( | ||
142 | capsName, | ||
143 | new RestStreamHandler( | ||
144 | "GET", | ||
145 | capsPath, | ||
146 | (request, path, param, httpRequest, httpResponse) | ||
147 | => GetEnvironmentSettings(request, path, param, agentID, caps), | ||
148 | capsName, | ||
149 | agentID.ToString())); | ||
150 | |||
151 | // Set handler | ||
152 | caps.HttpListener.AddStreamHandler( | ||
153 | new RestStreamHandler( | ||
154 | "POST", | ||
155 | capsPath, | ||
156 | (request, path, param, httpRequest, httpResponse) | ||
157 | => SetEnvironmentSettings(request, path, param, agentID, caps), | ||
158 | capsName, | ||
159 | agentID.ToString())); | ||
160 | } | ||
161 | #endregion | ||
162 | |||
163 | private string GetEnvironmentSettings(string request, string path, string param, | ||
164 | UUID agentID, Caps caps) | ||
165 | { | ||
166 | // m_log.DebugFormat("[{0}]: Environment GET handle for agentID {1} in region {2}", | ||
167 | // Name, agentID, caps.RegionName); | ||
168 | |||
169 | string env = String.Empty; | ||
170 | |||
171 | try | ||
172 | { | ||
173 | env = m_scene.SimulationDataService.LoadRegionEnvironmentSettings(regionID); | ||
174 | } | ||
175 | catch (Exception e) | ||
176 | { | ||
177 | m_log.ErrorFormat("[{0}]: Unable to load environment settings for region {1}, Exception: {2} - {3}", | ||
178 | Name, caps.RegionName, e.Message, e.StackTrace); | ||
179 | } | ||
180 | |||
181 | if (String.IsNullOrEmpty(env)) | ||
182 | env = EnvironmentSettings.EmptySettings(UUID.Zero, regionID); | ||
183 | |||
184 | return env; | ||
185 | } | ||
186 | |||
187 | private string SetEnvironmentSettings(string request, string path, string param, | ||
188 | UUID agentID, Caps caps) | ||
189 | { | ||
190 | |||
191 | // m_log.DebugFormat("[{0}]: Environment SET handle from agentID {1} in region {2}", | ||
192 | // Name, agentID, caps.RegionName); | ||
193 | |||
194 | setResponse.regionID = regionID; | ||
195 | setResponse.success = false; | ||
196 | |||
197 | if (!m_scene.Permissions.CanIssueEstateCommand(agentID, false)) | ||
198 | { | ||
199 | setResponse.fail_reason = "Insufficient estate permissions, settings has not been saved."; | ||
200 | return LLSDHelpers.SerialiseLLSDReply(setResponse); | ||
201 | } | ||
202 | |||
203 | try | ||
204 | { | ||
205 | m_scene.SimulationDataService.StoreRegionEnvironmentSettings(regionID, request); | ||
206 | setResponse.success = true; | ||
207 | |||
208 | m_log.InfoFormat("[{0}]: New Environment settings has been saved from agentID {1} in region {2}", | ||
209 | Name, agentID, caps.RegionName); | ||
210 | } | ||
211 | catch (Exception e) | ||
212 | { | ||
213 | m_log.ErrorFormat("[{0}]: Environment settings has not been saved for region {1}, Exception: {2} - {3}", | ||
214 | Name, caps.RegionName, e.Message, e.StackTrace); | ||
215 | |||
216 | setResponse.success = false; | ||
217 | setResponse.fail_reason = String.Format("Environment Set for region {0} has failed, settings has not been saved.", caps.RegionName); | ||
218 | } | ||
219 | |||
220 | return LLSDHelpers.SerialiseLLSDReply(setResponse); | ||
221 | } | ||
222 | } | ||
223 | } | ||
224 | |||
diff --git a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml index dc6efed..424e0ab 100644 --- a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml +++ b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml | |||
@@ -79,7 +79,6 @@ | |||
79 | <RegionModule id="AuthenticationServiceInConnectorModule" type="OpenSim.Region.CoreModules.ServiceConnectorsIn.Authentication.AuthenticationServiceInConnectorModule" /> | 79 | <RegionModule id="AuthenticationServiceInConnectorModule" type="OpenSim.Region.CoreModules.ServiceConnectorsIn.Authentication.AuthenticationServiceInConnectorModule" /> |
80 | <RegionModule id="AccessModule" type="OpenSim.Region.CoreModules.World.AccessModule" /> \ | 80 | <RegionModule id="AccessModule" type="OpenSim.Region.CoreModules.World.AccessModule" /> \ |
81 | <RegionModule id="MapImageModule" type="OpenSim.Region.CoreModules.World.LegacyMap.MapImageModule" /> \ | 81 | <RegionModule id="MapImageModule" type="OpenSim.Region.CoreModules.World.LegacyMap.MapImageModule" /> \ |
82 | <RegionModule id="Warp3DImageModule" type="OpenSim.Region.CoreModules.World.Warp3DMap.Warp3DImageModule" /> \ | ||
83 | 82 | ||
84 | </Extension> | 83 | </Extension> |
85 | 84 | ||
diff --git a/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs b/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs index 9255791..e91e8b9 100644 --- a/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs | |||
@@ -64,6 +64,8 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules | |||
64 | private TimeSpan m_QueueTimeout = new TimeSpan(2, 0, 0); // 2 hours without llGetNextEmail drops the queue | 64 | private TimeSpan m_QueueTimeout = new TimeSpan(2, 0, 0); // 2 hours without llGetNextEmail drops the queue |
65 | private string m_InterObjectHostname = "lsl.opensim.local"; | 65 | private string m_InterObjectHostname = "lsl.opensim.local"; |
66 | 66 | ||
67 | private int m_MaxEmailSize = 4096; // largest email allowed by default, as per lsl docs. | ||
68 | |||
67 | // Scenes by Region Handle | 69 | // Scenes by Region Handle |
68 | private Dictionary<ulong, Scene> m_Scenes = | 70 | private Dictionary<ulong, Scene> m_Scenes = |
69 | new Dictionary<ulong, Scene>(); | 71 | new Dictionary<ulong, Scene>(); |
@@ -127,6 +129,7 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules | |||
127 | SMTP_SERVER_PORT = SMTPConfig.GetInt("SMTP_SERVER_PORT", SMTP_SERVER_PORT); | 129 | SMTP_SERVER_PORT = SMTPConfig.GetInt("SMTP_SERVER_PORT", SMTP_SERVER_PORT); |
128 | SMTP_SERVER_LOGIN = SMTPConfig.GetString("SMTP_SERVER_LOGIN", SMTP_SERVER_LOGIN); | 130 | SMTP_SERVER_LOGIN = SMTPConfig.GetString("SMTP_SERVER_LOGIN", SMTP_SERVER_LOGIN); |
129 | SMTP_SERVER_PASSWORD = SMTPConfig.GetString("SMTP_SERVER_PASSWORD", SMTP_SERVER_PASSWORD); | 131 | SMTP_SERVER_PASSWORD = SMTPConfig.GetString("SMTP_SERVER_PASSWORD", SMTP_SERVER_PASSWORD); |
132 | m_MaxEmailSize = SMTPConfig.GetInt("email_max_size", m_MaxEmailSize); | ||
130 | } | 133 | } |
131 | catch (Exception e) | 134 | catch (Exception e) |
132 | { | 135 | { |
@@ -176,18 +179,6 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules | |||
176 | get { return true; } | 179 | get { return true; } |
177 | } | 180 | } |
178 | 181 | ||
179 | /// <summary> | ||
180 | /// Delay function using thread in seconds | ||
181 | /// </summary> | ||
182 | /// <param name="seconds"></param> | ||
183 | private void DelayInSeconds(int delay) | ||
184 | { | ||
185 | delay = (int)((float)delay * 1000); | ||
186 | if (delay == 0) | ||
187 | return; | ||
188 | System.Threading.Thread.Sleep(delay); | ||
189 | } | ||
190 | |||
191 | private bool IsLocal(UUID objectID) | 182 | private bool IsLocal(UUID objectID) |
192 | { | 183 | { |
193 | string unused; | 184 | string unused; |
@@ -267,10 +258,9 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules | |||
267 | m_log.Error("[EMAIL] REGEX Problem in EMail Address: "+address); | 258 | m_log.Error("[EMAIL] REGEX Problem in EMail Address: "+address); |
268 | return; | 259 | return; |
269 | } | 260 | } |
270 | //FIXME:Check if subject + body = 4096 Byte | 261 | if ((subject.Length + body.Length) > m_MaxEmailSize) |
271 | if ((subject.Length + body.Length) > 1024) | ||
272 | { | 262 | { |
273 | m_log.Error("[EMAIL] subject + body > 1024 Byte"); | 263 | m_log.Error("[EMAIL] subject + body larger than limit of " + m_MaxEmailSize + " bytes"); |
274 | return; | 264 | return; |
275 | } | 265 | } |
276 | 266 | ||
@@ -345,10 +335,6 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules | |||
345 | // TODO FIX | 335 | // TODO FIX |
346 | } | 336 | } |
347 | } | 337 | } |
348 | |||
349 | //DONE: Message as Second Life style | ||
350 | //20 second delay - AntiSpam System - for now only 10 seconds | ||
351 | DelayInSeconds(10); | ||
352 | } | 338 | } |
353 | 339 | ||
354 | /// <summary> | 340 | /// <summary> |
diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs index dcf49a7..f4a89bd 100644 --- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs | |||
@@ -77,7 +77,9 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
77 | private Dictionary<string, UrlData> m_UrlMap = | 77 | private Dictionary<string, UrlData> m_UrlMap = |
78 | new Dictionary<string, UrlData>(); | 78 | new Dictionary<string, UrlData>(); |
79 | 79 | ||
80 | 80 | /// <summary> | |
81 | /// Maximum number of external urls that can be set up by this module. | ||
82 | /// </summary> | ||
81 | private int m_TotalUrls = 5000; | 83 | private int m_TotalUrls = 5000; |
82 | 84 | ||
83 | private uint https_port = 0; | 85 | private uint https_port = 0; |
@@ -85,6 +87,10 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
85 | private IHttpServer m_HttpsServer = null; | 87 | private IHttpServer m_HttpsServer = null; |
86 | 88 | ||
87 | private string m_ExternalHostNameForLSL = ""; | 89 | private string m_ExternalHostNameForLSL = ""; |
90 | public string ExternalHostNameForLSL | ||
91 | { | ||
92 | get { return m_ExternalHostNameForLSL; } | ||
93 | } | ||
88 | 94 | ||
89 | public Type ReplaceableInterface | 95 | public Type ReplaceableInterface |
90 | { | 96 | { |
@@ -104,6 +110,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
104 | { | 110 | { |
105 | https_port = (uint) config.Configs["Network"].GetInt("https_port",0); | 111 | https_port = (uint) config.Configs["Network"].GetInt("https_port",0); |
106 | } | 112 | } |
113 | |||
114 | IConfig llFunctionsConfig = config.Configs["LL-Functions"]; | ||
115 | |||
116 | if (llFunctionsConfig != null) | ||
117 | m_TotalUrls = llFunctionsConfig.GetInt("max_external_urls_per_simulator", m_TotalUrls); | ||
107 | } | 118 | } |
108 | 119 | ||
109 | public void PostInitialise() | 120 | public void PostInitialise() |
@@ -147,6 +158,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
147 | public void Close() | 158 | public void Close() |
148 | { | 159 | { |
149 | } | 160 | } |
161 | |||
150 | public UUID RequestURL(IScriptModule engine, SceneObjectPart host, UUID itemID) | 162 | public UUID RequestURL(IScriptModule engine, SceneObjectPart host, UUID itemID) |
151 | { | 163 | { |
152 | UUID urlcode = UUID.Random(); | 164 | UUID urlcode = UUID.Random(); |
@@ -176,6 +188,10 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
176 | args.Type = PollServiceEventArgs.EventType.LslHttp; | 188 | args.Type = PollServiceEventArgs.EventType.LslHttp; |
177 | m_HttpServer.AddPollServiceHTTPHandler(uri, args); | 189 | m_HttpServer.AddPollServiceHTTPHandler(uri, args); |
178 | 190 | ||
191 | m_log.DebugFormat( | ||
192 | "[URL MODULE]: Set up incoming request url {0} for {1} in {2} {3}", | ||
193 | uri, itemID, host.Name, host.LocalId); | ||
194 | |||
179 | engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url }); | 195 | engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url }); |
180 | } | 196 | } |
181 | 197 | ||
@@ -218,6 +234,10 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
218 | args.Type = PollServiceEventArgs.EventType.LslHttp; | 234 | args.Type = PollServiceEventArgs.EventType.LslHttp; |
219 | m_HttpsServer.AddPollServiceHTTPHandler(uri, args); | 235 | m_HttpsServer.AddPollServiceHTTPHandler(uri, args); |
220 | 236 | ||
237 | m_log.DebugFormat( | ||
238 | "[URL MODULE]: Set up incoming secure request url {0} for {1} in {2} {3}", | ||
239 | uri, itemID, host.Name, host.LocalId); | ||
240 | |||
221 | engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url }); | 241 | engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_GRANTED", url }); |
222 | } | 242 | } |
223 | 243 | ||
@@ -241,6 +261,10 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
241 | m_RequestMap.Remove(req); | 261 | m_RequestMap.Remove(req); |
242 | } | 262 | } |
243 | 263 | ||
264 | // m_log.DebugFormat( | ||
265 | // "[URL MODULE]: Releasing url {0} for {1} in {2}", | ||
266 | // url, data.itemID, data.hostID); | ||
267 | |||
244 | RemoveUrl(data); | 268 | RemoveUrl(data); |
245 | m_UrlMap.Remove(url); | 269 | m_UrlMap.Remove(url); |
246 | } | 270 | } |
diff --git a/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs b/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs index 40ffcb4..0003af2 100644 --- a/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs | |||
@@ -131,11 +131,12 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC | |||
131 | { | 131 | { |
132 | // Start http server | 132 | // Start http server |
133 | // Attach xmlrpc handlers | 133 | // Attach xmlrpc handlers |
134 | m_log.Info("[XML RPC MODULE]: " + | 134 | // m_log.InfoFormat( |
135 | "Starting up XMLRPC Server on port " + m_remoteDataPort + " for llRemoteData commands."); | 135 | // "[XML RPC MODULE]: Starting up XMLRPC Server on port {0} for llRemoteData commands.", |
136 | BaseHttpServer httpServer = new BaseHttpServer((uint) m_remoteDataPort); | 136 | // m_remoteDataPort); |
137 | |||
138 | IHttpServer httpServer = MainServer.GetHttpServer((uint)m_remoteDataPort); | ||
137 | httpServer.AddXmlRPCHandler("llRemoteData", XmlRpcRemoteData); | 139 | httpServer.AddXmlRPCHandler("llRemoteData", XmlRpcRemoteData); |
138 | httpServer.Start(); | ||
139 | } | 140 | } |
140 | } | 141 | } |
141 | 142 | ||
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs index 8df1c7b..a7dd0dd 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs | |||
@@ -122,7 +122,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid | |||
122 | ISimulationService simService = scene.RequestModuleInterface<ISimulationService>(); | 122 | ISimulationService simService = scene.RequestModuleInterface<ISimulationService>(); |
123 | IFriendsSimConnector friendsConn = scene.RequestModuleInterface<IFriendsSimConnector>(); | 123 | IFriendsSimConnector friendsConn = scene.RequestModuleInterface<IFriendsSimConnector>(); |
124 | Object[] args = new Object[] { m_Config }; | 124 | Object[] args = new Object[] { m_Config }; |
125 | IFriendsService friendsService = ServerUtils.LoadPlugin<IFriendsService>(m_LocalServiceDll, args); | 125 | // IFriendsService friendsService = ServerUtils.LoadPlugin<IFriendsService>(m_LocalServiceDll, args) |
126 | ServerUtils.LoadPlugin<IFriendsService>(m_LocalServiceDll, args); | ||
126 | 127 | ||
127 | m_HypergridHandler = new GatekeeperServiceInConnector(m_Config, MainServer.Instance, simService); | 128 | m_HypergridHandler = new GatekeeperServiceInConnector(m_Config, MainServer.Instance, simService); |
128 | 129 | ||
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Land/LandServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Land/LandServiceInConnectorModule.cs index c8f45f6..2f3c350 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Land/LandServiceInConnectorModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Land/LandServiceInConnectorModule.cs | |||
@@ -75,7 +75,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Land | |||
75 | if (!m_Enabled) | 75 | if (!m_Enabled) |
76 | return; | 76 | return; |
77 | 77 | ||
78 | m_log.Info("[LAND IN CONNECTOR]: Starting..."); | 78 | // m_log.Info("[LAND IN CONNECTOR]: Starting..."); |
79 | } | 79 | } |
80 | 80 | ||
81 | public void Close() | 81 | public void Close() |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Neighbour/NeighbourServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Neighbour/NeighbourServiceInConnectorModule.cs index 3fd89b9..b544ab3 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Neighbour/NeighbourServiceInConnectorModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Neighbour/NeighbourServiceInConnectorModule.cs | |||
@@ -74,7 +74,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Neighbour | |||
74 | if (!m_Enabled) | 74 | if (!m_Enabled) |
75 | return; | 75 | return; |
76 | 76 | ||
77 | m_log.Info("[NEIGHBOUR IN CONNECTOR]: Starting..."); | 77 | // m_log.Info("[NEIGHBOUR IN CONNECTOR]: Starting..."); |
78 | } | 78 | } |
79 | 79 | ||
80 | public void Close() | 80 | public void Close() |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs index 8395f83..008465f 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs | |||
@@ -149,7 +149,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset | |||
149 | 149 | ||
150 | m_aScene = scene; | 150 | m_aScene = scene; |
151 | 151 | ||
152 | scene.RegisterModuleInterface<IAssetService>(this); | 152 | m_aScene.RegisterModuleInterface<IAssetService>(this); |
153 | } | 153 | } |
154 | 154 | ||
155 | public void RemoveRegion(Scene scene) | 155 | public void RemoveRegion(Scene scene) |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/AuthorizationService.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/AuthorizationService.cs index f0d21e6..4470799 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/AuthorizationService.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/AuthorizationService.cs | |||
@@ -55,7 +55,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization | |||
55 | MethodBase.GetCurrentMethod().DeclaringType); | 55 | MethodBase.GetCurrentMethod().DeclaringType); |
56 | 56 | ||
57 | private IUserManagement m_UserManagement; | 57 | private IUserManagement m_UserManagement; |
58 | private IGridService m_GridService; | 58 | // private IGridService m_GridService; |
59 | 59 | ||
60 | private Scene m_Scene; | 60 | private Scene m_Scene; |
61 | AccessFlags m_accessValue = AccessFlags.None; | 61 | AccessFlags m_accessValue = AccessFlags.None; |
@@ -65,7 +65,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization | |||
65 | { | 65 | { |
66 | m_Scene = scene; | 66 | m_Scene = scene; |
67 | m_UserManagement = scene.RequestModuleInterface<IUserManagement>(); | 67 | m_UserManagement = scene.RequestModuleInterface<IUserManagement>(); |
68 | m_GridService = scene.GridService; | 68 | // m_GridService = scene.GridService; |
69 | 69 | ||
70 | if (config != null) | 70 | if (config != null) |
71 | { | 71 | { |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs index 540f33a..3c6e381 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs | |||
@@ -41,8 +41,7 @@ using OpenMetaverse; | |||
41 | 41 | ||
42 | namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | 42 | namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid |
43 | { | 43 | { |
44 | public class LocalGridServicesConnector : | 44 | public class LocalGridServicesConnector : ISharedRegionModule, IGridService |
45 | ISharedRegionModule, IGridService | ||
46 | { | 45 | { |
47 | private static readonly ILog m_log = | 46 | private static readonly ILog m_log = |
48 | LogManager.GetLogger( | 47 | LogManager.GetLogger( |
@@ -51,7 +50,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
51 | private IGridService m_GridService; | 50 | private IGridService m_GridService; |
52 | private Dictionary<UUID, RegionCache> m_LocalCache = new Dictionary<UUID, RegionCache>(); | 51 | private Dictionary<UUID, RegionCache> m_LocalCache = new Dictionary<UUID, RegionCache>(); |
53 | 52 | ||
54 | private bool m_Enabled = false; | 53 | private bool m_Enabled; |
55 | 54 | ||
56 | public LocalGridServicesConnector() | 55 | public LocalGridServicesConnector() |
57 | { | 56 | { |
@@ -59,7 +58,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
59 | 58 | ||
60 | public LocalGridServicesConnector(IConfigSource source) | 59 | public LocalGridServicesConnector(IConfigSource source) |
61 | { | 60 | { |
62 | m_log.Debug("[LOCAL GRID CONNECTOR]: LocalGridServicesConnector instantiated"); | 61 | m_log.Debug("[LOCAL GRID SERVICE CONNECTOR]: LocalGridServicesConnector instantiated directly."); |
63 | InitialiseService(source); | 62 | InitialiseService(source); |
64 | } | 63 | } |
65 | 64 | ||
@@ -84,8 +83,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
84 | if (name == Name) | 83 | if (name == Name) |
85 | { | 84 | { |
86 | InitialiseService(source); | 85 | InitialiseService(source); |
87 | m_Enabled = true; | 86 | m_log.Info("[LOCAL GRID SERVICE CONNECTOR]: Local grid connector enabled"); |
88 | m_log.Info("[LOCAL GRID CONNECTOR]: Local grid connector enabled"); | ||
89 | } | 87 | } |
90 | } | 88 | } |
91 | } | 89 | } |
@@ -95,7 +93,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
95 | IConfig assetConfig = source.Configs["GridService"]; | 93 | IConfig assetConfig = source.Configs["GridService"]; |
96 | if (assetConfig == null) | 94 | if (assetConfig == null) |
97 | { | 95 | { |
98 | m_log.Error("[LOCAL GRID CONNECTOR]: GridService missing from OpenSim.ini"); | 96 | m_log.Error("[LOCAL GRID SERVICE CONNECTOR]: GridService missing from OpenSim.ini"); |
99 | return; | 97 | return; |
100 | } | 98 | } |
101 | 99 | ||
@@ -104,7 +102,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
104 | 102 | ||
105 | if (serviceDll == String.Empty) | 103 | if (serviceDll == String.Empty) |
106 | { | 104 | { |
107 | m_log.Error("[LOCAL GRID CONNECTOR]: No LocalServiceModule named in section GridService"); | 105 | m_log.Error("[LOCAL GRID SERVICE CONNECTOR]: No LocalServiceModule named in section GridService"); |
108 | return; | 106 | return; |
109 | } | 107 | } |
110 | 108 | ||
@@ -115,16 +113,20 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
115 | 113 | ||
116 | if (m_GridService == null) | 114 | if (m_GridService == null) |
117 | { | 115 | { |
118 | m_log.Error("[LOCAL GRID CONNECTOR]: Can't load grid service"); | 116 | m_log.Error("[LOCAL GRID SERVICE CONNECTOR]: Can't load grid service"); |
119 | return; | 117 | return; |
120 | } | 118 | } |
119 | |||
120 | m_Enabled = true; | ||
121 | } | 121 | } |
122 | 122 | ||
123 | public void PostInitialise() | 123 | public void PostInitialise() |
124 | { | 124 | { |
125 | // FIXME: We will still add this command even if we aren't enabled since RemoteGridServiceConnector | ||
126 | // will have instantiated us directly. | ||
125 | MainConsole.Instance.Commands.AddCommand("Regions", false, "show neighbours", | 127 | MainConsole.Instance.Commands.AddCommand("Regions", false, "show neighbours", |
126 | "show neighbours", | 128 | "show neighbours", |
127 | "Shows the local regions' neighbours", NeighboursCommand); | 129 | "Shows the local regions' neighbours", HandleShowNeighboursCommand); |
128 | } | 130 | } |
129 | 131 | ||
130 | public void Close() | 132 | public void Close() |
@@ -133,17 +135,22 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
133 | 135 | ||
134 | public void AddRegion(Scene scene) | 136 | public void AddRegion(Scene scene) |
135 | { | 137 | { |
136 | if (m_Enabled) | 138 | if (!m_Enabled) |
137 | scene.RegisterModuleInterface<IGridService>(this); | 139 | return; |
140 | |||
141 | scene.RegisterModuleInterface<IGridService>(this); | ||
138 | 142 | ||
139 | if (m_LocalCache.ContainsKey(scene.RegionInfo.RegionID)) | 143 | if (m_LocalCache.ContainsKey(scene.RegionInfo.RegionID)) |
140 | m_log.ErrorFormat("[LOCAL GRID CONNECTOR]: simulator seems to have more than one region with the same UUID. Please correct this!"); | 144 | m_log.ErrorFormat("[LOCAL GRID SERVICE CONNECTOR]: simulator seems to have more than one region with the same UUID. Please correct this!"); |
141 | else | 145 | else |
142 | m_LocalCache.Add(scene.RegionInfo.RegionID, new RegionCache(scene)); | 146 | m_LocalCache.Add(scene.RegionInfo.RegionID, new RegionCache(scene)); |
143 | } | 147 | } |
144 | 148 | ||
145 | public void RemoveRegion(Scene scene) | 149 | public void RemoveRegion(Scene scene) |
146 | { | 150 | { |
151 | if (!m_Enabled) | ||
152 | return; | ||
153 | |||
147 | m_LocalCache[scene.RegionInfo.RegionID].Clear(); | 154 | m_LocalCache[scene.RegionInfo.RegionID].Clear(); |
148 | m_LocalCache.Remove(scene.RegionInfo.RegionID); | 155 | m_LocalCache.Remove(scene.RegionInfo.RegionID); |
149 | } | 156 | } |
@@ -232,7 +239,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
232 | 239 | ||
233 | #endregion | 240 | #endregion |
234 | 241 | ||
235 | public void NeighboursCommand(string module, string[] cmdparams) | 242 | public void HandleShowNeighboursCommand(string module, string[] cmdparams) |
236 | { | 243 | { |
237 | System.Text.StringBuilder caps = new System.Text.StringBuilder(); | 244 | System.Text.StringBuilder caps = new System.Text.StringBuilder(); |
238 | 245 | ||
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs index 4cf62ec..b0edce7 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs | |||
@@ -79,29 +79,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser | |||
79 | 79 | ||
80 | public void OnConnectionClose(IClientAPI client) | 80 | public void OnConnectionClose(IClientAPI client) |
81 | { | 81 | { |
82 | if (client.IsLoggingOut) | 82 | if (client.SceneAgent.IsChildAgent) |
83 | { | 83 | return; |
84 | object sp = null; | ||
85 | Vector3 position = new Vector3(128, 128, 0); | ||
86 | Vector3 lookat = new Vector3(0, 1, 0); | ||
87 | |||
88 | if (client.Scene.TryGetScenePresence(client.AgentId, out sp)) | ||
89 | { | ||
90 | if (sp is ScenePresence) | ||
91 | { | ||
92 | if (((ScenePresence)sp).IsChildAgent) | ||
93 | return; | ||
94 | |||
95 | position = ((ScenePresence)sp).AbsolutePosition; | ||
96 | lookat = ((ScenePresence)sp).Lookat; | ||
97 | } | ||
98 | } | ||
99 | |||
100 | // m_log.DebugFormat("[ACTIVITY DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName); | ||
101 | m_GridUserService.LoggedOut(client.AgentId.ToString(), client.SessionId, client.Scene.RegionInfo.RegionID, position, lookat); | ||
102 | } | ||
103 | 84 | ||
85 | // m_log.DebugFormat("[ACTIVITY DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName); | ||
86 | m_GridUserService.LoggedOut( | ||
87 | client.AgentId.ToString(), client.SessionId, client.Scene.RegionInfo.RegionID, | ||
88 | client.SceneAgent.AbsolutePosition, client.SceneAgent.Lookat); | ||
104 | } | 89 | } |
105 | |||
106 | } | 90 | } |
107 | } | 91 | } |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs index 3b862da..6cd077a 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs | |||
@@ -149,9 +149,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage | |||
149 | lock (m_scenes) | 149 | lock (m_scenes) |
150 | m_scenes[scene.RegionInfo.RegionID] = scene; | 150 | m_scenes[scene.RegionInfo.RegionID] = scene; |
151 | 151 | ||
152 | scene.EventManager.OnPrimsLoaded += new EventManager.PrimsLoaded(EventManager_OnPrimsLoaded); | 152 | scene.EventManager.OnLoginsEnabled += OnLoginsEnabled; |
153 | } | 153 | } |
154 | 154 | ||
155 | |||
155 | ///<summary> | 156 | ///<summary> |
156 | /// | 157 | /// |
157 | ///</summary> | 158 | ///</summary> |
@@ -166,9 +167,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage | |||
166 | 167 | ||
167 | #endregion ISharedRegionModule | 168 | #endregion ISharedRegionModule |
168 | 169 | ||
169 | void EventManager_OnPrimsLoaded(Scene s) | 170 | void OnLoginsEnabled(string regionName) |
170 | { | 171 | { |
171 | UploadMapTile(s); | 172 | Scene scene = null; |
173 | foreach (Scene s in m_scenes.Values) | ||
174 | if (s.RegionInfo.RegionName == regionName) | ||
175 | { | ||
176 | scene = s; | ||
177 | break; | ||
178 | } | ||
179 | if (scene != null) | ||
180 | UploadMapTile(scene); | ||
172 | } | 181 | } |
173 | 182 | ||
174 | 183 | ||
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Neighbour/LocalNeighbourServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Neighbour/LocalNeighbourServiceConnector.cs index 40cc536..7a90686 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Neighbour/LocalNeighbourServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Neighbour/LocalNeighbourServiceConnector.cs | |||
@@ -125,13 +125,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Neighbour | |||
125 | uint x, y; | 125 | uint x, y; |
126 | Utils.LongToUInts(regionHandle, out x, out y); | 126 | Utils.LongToUInts(regionHandle, out x, out y); |
127 | 127 | ||
128 | m_log.DebugFormat("[NEIGHBOUR CONNECTOR]: HelloNeighbour from region {0} to region at {1}-{2}", | ||
129 | thisRegion.RegionName, x / Constants.RegionSize, y / Constants.RegionSize); | ||
130 | |||
131 | foreach (Scene s in m_Scenes) | 128 | foreach (Scene s in m_Scenes) |
132 | { | 129 | { |
133 | if (s.RegionInfo.RegionHandle == regionHandle) | 130 | if (s.RegionInfo.RegionHandle == regionHandle) |
134 | { | 131 | { |
132 | m_log.DebugFormat("[LOCAL NEIGHBOUR SERVICE CONNECTOR]: HelloNeighbour from region {0} to neighbour {1} at {2}-{3}", | ||
133 | thisRegion.RegionName, s.Name, x / Constants.RegionSize, y / Constants.RegionSize); | ||
134 | |||
135 | //m_log.Debug("[NEIGHBOUR CONNECTOR]: Found region to SendHelloNeighbour"); | 135 | //m_log.Debug("[NEIGHBOUR CONNECTOR]: Found region to SendHelloNeighbour"); |
136 | return s.IncomingHelloNeighbour(thisRegion); | 136 | return s.IncomingHelloNeighbour(thisRegion); |
137 | } | 137 | } |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs index ccfbf78..172bea1 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs | |||
@@ -64,7 +64,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence | |||
64 | scene.EventManager.OnNewClient -= OnNewClient; | 64 | scene.EventManager.OnNewClient -= OnNewClient; |
65 | 65 | ||
66 | m_PresenceService.LogoutRegionAgents(scene.RegionInfo.RegionID); | 66 | m_PresenceService.LogoutRegionAgents(scene.RegionInfo.RegionID); |
67 | |||
68 | } | 67 | } |
69 | 68 | ||
70 | public void OnMakeRootAgent(ScenePresence sp) | 69 | public void OnMakeRootAgent(ScenePresence sp) |
@@ -80,18 +79,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence | |||
80 | 79 | ||
81 | public void OnConnectionClose(IClientAPI client) | 80 | public void OnConnectionClose(IClientAPI client) |
82 | { | 81 | { |
83 | if (client.IsLoggingOut) | 82 | if (!client.SceneAgent.IsChildAgent) |
84 | { | 83 | { |
85 | object sp = null; | ||
86 | if (client.Scene.TryGetScenePresence(client.AgentId, out sp)) | ||
87 | { | ||
88 | if (sp is ScenePresence) | ||
89 | { | ||
90 | if (((ScenePresence)sp).IsChildAgent) | ||
91 | return; | ||
92 | } | ||
93 | } | ||
94 | |||
95 | // m_log.DebugFormat("[PRESENCE DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName); | 84 | // m_log.DebugFormat("[PRESENCE DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName); |
96 | m_PresenceService.LogoutAgent(client.SessionId); | 85 | m_PresenceService.LogoutAgent(client.SessionId); |
97 | } | 86 | } |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs index 6e75692..6eb99ea 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs | |||
@@ -26,6 +26,7 @@ | |||
26 | */ | 26 | */ |
27 | using System; | 27 | using System; |
28 | using System.Collections.Generic; | 28 | using System.Collections.Generic; |
29 | using System.Linq; | ||
29 | using System.Reflection; | 30 | using System.Reflection; |
30 | using log4net; | 31 | using log4net; |
31 | using Nini.Config; | 32 | using Nini.Config; |
@@ -41,22 +42,20 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
41 | public class LocalSimulationConnectorModule : ISharedRegionModule, ISimulationService | 42 | public class LocalSimulationConnectorModule : ISharedRegionModule, ISimulationService |
42 | { | 43 | { |
43 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 44 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
44 | // Version of this service | ||
45 | private const string m_Version = "SIMULATION/0.1"; | ||
46 | 45 | ||
47 | private List<Scene> m_sceneList = new List<Scene>(); | 46 | /// <summary> |
47 | /// Version of this service | ||
48 | /// </summary> | ||
49 | private const string m_Version = "SIMULATION/0.1"; | ||
48 | 50 | ||
49 | private IEntityTransferModule m_AgentTransferModule; | 51 | /// <summary> |
50 | protected IEntityTransferModule AgentTransferModule | 52 | /// Map region ID to scene. |
51 | { | 53 | /// </summary> |
52 | get | 54 | private Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>(); |
53 | { | ||
54 | if (m_AgentTransferModule == null) | ||
55 | m_AgentTransferModule = m_sceneList[0].RequestModuleInterface<IEntityTransferModule>(); | ||
56 | return m_AgentTransferModule; | ||
57 | } | ||
58 | } | ||
59 | 55 | ||
56 | /// <summary> | ||
57 | /// Is this module enabled? | ||
58 | /// </summary> | ||
60 | private bool m_ModuleEnabled = false; | 59 | private bool m_ModuleEnabled = false; |
61 | 60 | ||
62 | #region IRegionModule | 61 | #region IRegionModule |
@@ -129,12 +128,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
129 | /// <param name="scene"></param> | 128 | /// <param name="scene"></param> |
130 | public void RemoveScene(Scene scene) | 129 | public void RemoveScene(Scene scene) |
131 | { | 130 | { |
132 | lock (m_sceneList) | 131 | lock (m_scenes) |
133 | { | 132 | { |
134 | if (m_sceneList.Contains(scene)) | 133 | if (m_scenes.ContainsKey(scene.RegionInfo.RegionID)) |
135 | { | 134 | m_scenes.Remove(scene.RegionInfo.RegionID); |
136 | m_sceneList.Remove(scene); | 135 | else |
137 | } | 136 | m_log.WarnFormat( |
137 | "[LOCAL SIMULATION CONNECTOR]: Tried to remove region {0} but it was not present", | ||
138 | scene.RegionInfo.RegionName); | ||
138 | } | 139 | } |
139 | } | 140 | } |
140 | 141 | ||
@@ -144,13 +145,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
144 | /// <param name="scene"></param> | 145 | /// <param name="scene"></param> |
145 | public void Init(Scene scene) | 146 | public void Init(Scene scene) |
146 | { | 147 | { |
147 | if (!m_sceneList.Contains(scene)) | 148 | lock (m_scenes) |
148 | { | 149 | { |
149 | lock (m_sceneList) | 150 | if (!m_scenes.ContainsKey(scene.RegionInfo.RegionID)) |
150 | { | 151 | m_scenes[scene.RegionInfo.RegionID] = scene; |
151 | m_sceneList.Add(scene); | 152 | else |
152 | } | 153 | m_log.WarnFormat( |
153 | 154 | "[LOCAL SIMULATION CONNECTOR]: Tried to add region {0} but it is already present", | |
155 | scene.RegionInfo.RegionName); | ||
154 | } | 156 | } |
155 | } | 157 | } |
156 | 158 | ||
@@ -158,15 +160,24 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
158 | 160 | ||
159 | #region ISimulation | 161 | #region ISimulation |
160 | 162 | ||
161 | public IScene GetScene(ulong regionhandle) | 163 | public IScene GetScene(UUID regionId) |
162 | { | 164 | { |
163 | foreach (Scene s in m_sceneList) | 165 | if (m_scenes.ContainsKey(regionId)) |
164 | { | 166 | { |
165 | if (s.RegionInfo.RegionHandle == regionhandle) | 167 | return m_scenes[regionId]; |
166 | return s; | 168 | } |
169 | else | ||
170 | { | ||
171 | // FIXME: This was pre-existing behaviour but possibly not a good idea, since it hides an error rather | ||
172 | // than making it obvious and fixable. Need to see if the error message comes up in practice. | ||
173 | Scene s = m_scenes.Values.ToArray()[0]; | ||
174 | |||
175 | m_log.ErrorFormat( | ||
176 | "[LOCAL SIMULATION CONNECTOR]: Region with id {0} not found. Returning {1} {2} instead", | ||
177 | regionId, s.RegionInfo.RegionName, s.RegionInfo.RegionID); | ||
178 | |||
179 | return s; | ||
167 | } | 180 | } |
168 | // ? weird. should not happen | ||
169 | return m_sceneList[0]; | ||
170 | } | 181 | } |
171 | 182 | ||
172 | public ISimulationService GetInnerService() | 183 | public ISimulationService GetInnerService() |
@@ -187,13 +198,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
187 | return false; | 198 | return false; |
188 | } | 199 | } |
189 | 200 | ||
190 | foreach (Scene s in m_sceneList) | 201 | if (m_scenes.ContainsKey(destination.RegionID)) |
191 | { | 202 | { |
192 | if (s.RegionInfo.RegionHandle == destination.RegionHandle) | 203 | // m_log.DebugFormat("[LOCAL SIMULATION CONNECTOR]: Found region {0} to send SendCreateChildAgent", destination.RegionName); |
193 | { | 204 | return m_scenes[destination.RegionID].NewUserConnection(aCircuit, teleportFlags, out reason); |
194 | m_log.DebugFormat("[LOCAL SIMULATION CONNECTOR]: Found region {0} to send SendCreateChildAgent", destination.RegionName); | ||
195 | return s.NewUserConnection(aCircuit, teleportFlags, out reason); | ||
196 | } | ||
197 | } | 205 | } |
198 | 206 | ||
199 | reason = "Did not find region " + destination.RegionName; | 207 | reason = "Did not find region " + destination.RegionName; |
@@ -205,17 +213,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
205 | if (destination == null) | 213 | if (destination == null) |
206 | return false; | 214 | return false; |
207 | 215 | ||
208 | foreach (Scene s in m_sceneList) | 216 | if (m_scenes.ContainsKey(destination.RegionID)) |
209 | { | 217 | { |
210 | if (s.RegionInfo.RegionHandle == destination.RegionHandle) | 218 | // m_log.DebugFormat( |
211 | { | 219 | // "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", |
212 | m_log.DebugFormat( | 220 | // s.RegionInfo.RegionName, destination.RegionHandle); |
213 | "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", | ||
214 | s.RegionInfo.RegionName, destination.RegionHandle); | ||
215 | 221 | ||
216 | s.IncomingChildAgentDataUpdate(cAgentData); | 222 | return m_scenes[destination.RegionID].IncomingChildAgentDataUpdate(cAgentData); |
217 | return true; | ||
218 | } | ||
219 | } | 223 | } |
220 | 224 | ||
221 | // m_log.DebugFormat("[LOCAL COMMS]: Did not find region {0} for ChildAgentUpdate", regionHandle); | 225 | // m_log.DebugFormat("[LOCAL COMMS]: Did not find region {0} for ChildAgentUpdate", regionHandle); |
@@ -231,11 +235,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
231 | // simulator so when we receive the update we need to hand it to each of the | 235 | // simulator so when we receive the update we need to hand it to each of the |
232 | // scenes; scenes each check to see if the is a scene presence for the avatar | 236 | // scenes; scenes each check to see if the is a scene presence for the avatar |
233 | // note that we really don't need the GridRegion for this call | 237 | // note that we really don't need the GridRegion for this call |
234 | foreach (Scene s in m_sceneList) | 238 | foreach (Scene s in m_scenes.Values) |
235 | { | 239 | { |
236 | //m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate"); | 240 | //m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate"); |
237 | s.IncomingChildAgentDataUpdate(cAgentData); | 241 | s.IncomingChildAgentDataUpdate(cAgentData); |
238 | } | 242 | } |
243 | |||
239 | //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate"); | 244 | //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate"); |
240 | return true; | 245 | return true; |
241 | } | 246 | } |
@@ -247,14 +252,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
247 | if (destination == null) | 252 | if (destination == null) |
248 | return false; | 253 | return false; |
249 | 254 | ||
250 | foreach (Scene s in m_sceneList) | 255 | if (m_scenes.ContainsKey(destination.RegionID)) |
251 | { | 256 | { |
252 | if (s.RegionInfo.RegionHandle == destination.RegionHandle) | 257 | // m_log.DebugFormat( |
253 | { | 258 | // "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", |
254 | //m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate"); | 259 | // s.RegionInfo.RegionName, destination.RegionHandle); |
255 | return s.IncomingRetrieveRootAgent(id, out agent); | 260 | |
256 | } | 261 | return m_scenes[destination.RegionID].IncomingRetrieveRootAgent(id, out agent); |
257 | } | 262 | } |
263 | |||
258 | //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate"); | 264 | //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate"); |
259 | return false; | 265 | return false; |
260 | } | 266 | } |
@@ -266,59 +272,49 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
266 | if (destination == null) | 272 | if (destination == null) |
267 | return false; | 273 | return false; |
268 | 274 | ||
269 | foreach (Scene s in m_sceneList) | 275 | if (m_scenes.ContainsKey(destination.RegionID)) |
270 | { | 276 | { |
271 | if (s.RegionInfo.RegionID == destination.RegionID) | 277 | // m_log.DebugFormat( |
272 | return s.QueryAccess(id, position, out reason); | 278 | // "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", |
279 | // s.RegionInfo.RegionName, destination.RegionHandle); | ||
280 | |||
281 | return m_scenes[destination.RegionID].QueryAccess(id, position, out reason); | ||
273 | } | 282 | } |
283 | |||
284 | //m_log.Debug("[LOCAL COMMS]: region not found for QueryAccess"); | ||
274 | return false; | 285 | return false; |
275 | } | 286 | } |
276 | 287 | ||
277 | public bool ReleaseAgent(UUID origin, UUID id, string uri) | 288 | public bool ReleaseAgent(UUID originId, UUID agentId, string uri) |
278 | { | 289 | { |
279 | foreach (Scene s in m_sceneList) | 290 | if (m_scenes.ContainsKey(originId)) |
280 | { | 291 | { |
281 | if (s.RegionInfo.RegionID == origin) | 292 | // m_log.DebugFormat( |
282 | { | 293 | // "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", |
283 | m_log.Debug("[LOCAL COMMS]: Found region to SendReleaseAgent"); | 294 | // s.RegionInfo.RegionName, destination.RegionHandle); |
284 | AgentTransferModule.AgentArrivedAtDestination(id); | 295 | |
285 | return true; | 296 | m_scenes[originId].EntityTransferModule.AgentArrivedAtDestination(agentId); |
286 | // return s.IncomingReleaseAgent(id); | 297 | return true; |
287 | } | ||
288 | } | 298 | } |
299 | |||
289 | //m_log.Debug("[LOCAL COMMS]: region not found in SendReleaseAgent " + origin); | 300 | //m_log.Debug("[LOCAL COMMS]: region not found in SendReleaseAgent " + origin); |
290 | return false; | 301 | return false; |
291 | } | 302 | } |
292 | 303 | ||
293 | public bool CloseAgent(GridRegion destination, UUID id) | 304 | public bool CloseChildAgent(GridRegion destination, UUID id) |
294 | { | 305 | { |
295 | if (destination == null) | 306 | return CloseAgent(destination, id); |
296 | return false; | ||
297 | |||
298 | foreach (Scene s in m_sceneList) | ||
299 | { | ||
300 | if (s.RegionInfo.RegionID == destination.RegionID) | ||
301 | { | ||
302 | //m_log.Debug("[LOCAL COMMS]: Found region to SendCloseAgent"); | ||
303 | return s.IncomingCloseAgent(id); | ||
304 | } | ||
305 | } | ||
306 | //m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent"); | ||
307 | return false; | ||
308 | } | 307 | } |
309 | 308 | ||
310 | public bool CloseChildAgent(GridRegion destination, UUID id) | 309 | public bool CloseAgent(GridRegion destination, UUID id) |
311 | { | 310 | { |
312 | if (destination == null) | 311 | if (destination == null) |
313 | return false; | 312 | return false; |
314 | 313 | ||
315 | foreach (Scene s in m_sceneList) | 314 | if (m_scenes.ContainsKey(destination.RegionID)) |
316 | { | 315 | { |
317 | if (s.RegionInfo.RegionID == destination.RegionID) | 316 | Util.FireAndForget(delegate { m_scenes[destination.RegionID].IncomingCloseAgent(id); }); |
318 | { | 317 | return true; |
319 | //m_log.Debug("[LOCAL COMMS]: Found region to SendCloseAgent"); | ||
320 | return s.IncomingCloseChildAgent(id); | ||
321 | } | ||
322 | } | 318 | } |
323 | //m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent"); | 319 | //m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent"); |
324 | return false; | 320 | return false; |
@@ -333,62 +329,47 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
333 | if (destination == null) | 329 | if (destination == null) |
334 | return false; | 330 | return false; |
335 | 331 | ||
336 | foreach (Scene s in m_sceneList) | 332 | if (m_scenes.ContainsKey(destination.RegionID)) |
337 | { | 333 | { |
338 | if (s.RegionInfo.RegionHandle == destination.RegionHandle) | 334 | // m_log.DebugFormat( |
339 | { | 335 | // "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", |
340 | //m_log.Debug("[LOCAL COMMS]: Found region to SendCreateObject"); | 336 | // s.RegionInfo.RegionName, destination.RegionHandle); |
341 | if (isLocalCall) | ||
342 | { | ||
343 | // We need to make a local copy of the object | ||
344 | ISceneObject sogClone = sog.CloneForNewScene(); | ||
345 | sogClone.SetState(sog.GetStateSnapshot(), s); | ||
346 | return s.IncomingCreateObject(newPosition, sogClone); | ||
347 | } | ||
348 | else | ||
349 | { | ||
350 | // Use the object as it came through the wire | ||
351 | return s.IncomingCreateObject(newPosition, sog); | ||
352 | } | ||
353 | } | ||
354 | } | ||
355 | return false; | ||
356 | } | ||
357 | 337 | ||
358 | public bool CreateObject(GridRegion destination, UUID userID, UUID itemID) | 338 | Scene s = m_scenes[destination.RegionID]; |
359 | { | ||
360 | if (destination == null) | ||
361 | return false; | ||
362 | 339 | ||
363 | foreach (Scene s in m_sceneList) | 340 | if (isLocalCall) |
364 | { | 341 | { |
365 | if (s.RegionInfo.RegionHandle == destination.RegionHandle) | 342 | // We need to make a local copy of the object |
343 | ISceneObject sogClone = sog.CloneForNewScene(); | ||
344 | sogClone.SetState(sog.GetStateSnapshot(), s); | ||
345 | return s.IncomingCreateObject(newPosition, sogClone); | ||
346 | } | ||
347 | else | ||
366 | { | 348 | { |
367 | return s.IncomingCreateObject(userID, itemID); | 349 | // Use the object as it came through the wire |
350 | return s.IncomingCreateObject(newPosition, sog); | ||
368 | } | 351 | } |
369 | } | 352 | } |
353 | |||
370 | return false; | 354 | return false; |
371 | } | 355 | } |
372 | 356 | ||
373 | |||
374 | #endregion /* IInterregionComms */ | 357 | #endregion /* IInterregionComms */ |
375 | 358 | ||
376 | #region Misc | 359 | #region Misc |
377 | 360 | ||
378 | public bool IsLocalRegion(ulong regionhandle) | 361 | public bool IsLocalRegion(ulong regionhandle) |
379 | { | 362 | { |
380 | foreach (Scene s in m_sceneList) | 363 | foreach (Scene s in m_scenes.Values) |
381 | if (s.RegionInfo.RegionHandle == regionhandle) | 364 | if (s.RegionInfo.RegionHandle == regionhandle) |
382 | return true; | 365 | return true; |
366 | |||
383 | return false; | 367 | return false; |
384 | } | 368 | } |
385 | 369 | ||
386 | public bool IsLocalRegion(UUID id) | 370 | public bool IsLocalRegion(UUID id) |
387 | { | 371 | { |
388 | foreach (Scene s in m_sceneList) | 372 | return m_scenes.ContainsKey(id); |
389 | if (s.RegionInfo.RegionID == id) | ||
390 | return true; | ||
391 | return false; | ||
392 | } | 373 | } |
393 | 374 | ||
394 | #endregion | 375 | #endregion |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs index 4b70692..68be552 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs | |||
@@ -151,9 +151,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
151 | 151 | ||
152 | #region IInterregionComms | 152 | #region IInterregionComms |
153 | 153 | ||
154 | public IScene GetScene(ulong handle) | 154 | public IScene GetScene(UUID regionId) |
155 | { | 155 | { |
156 | return m_localBackend.GetScene(handle); | 156 | return m_localBackend.GetScene(regionId); |
157 | } | 157 | } |
158 | 158 | ||
159 | public ISimulationService GetInnerService() | 159 | public ISimulationService GetInnerService() |
@@ -226,13 +226,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
226 | return m_remoteConnector.RetrieveAgent(destination, id, out agent); | 226 | return m_remoteConnector.RetrieveAgent(destination, id, out agent); |
227 | 227 | ||
228 | return false; | 228 | return false; |
229 | |||
230 | } | 229 | } |
231 | 230 | ||
232 | public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason) | 231 | public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason) |
233 | { | 232 | { |
234 | reason = "Communications failure"; | 233 | reason = "Communications failure"; |
235 | version = "Unknown"; | 234 | version = "Unknown"; |
235 | |||
236 | if (destination == null) | 236 | if (destination == null) |
237 | return false; | 237 | return false; |
238 | 238 | ||
@@ -245,7 +245,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
245 | return m_remoteConnector.QueryAccess(destination, id, position, out version, out reason); | 245 | return m_remoteConnector.QueryAccess(destination, id, position, out version, out reason); |
246 | 246 | ||
247 | return false; | 247 | return false; |
248 | |||
249 | } | 248 | } |
250 | 249 | ||
251 | public bool ReleaseAgent(UUID origin, UUID id, string uri) | 250 | public bool ReleaseAgent(UUID origin, UUID id, string uri) |
@@ -316,13 +315,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
316 | return false; | 315 | return false; |
317 | } | 316 | } |
318 | 317 | ||
319 | public bool CreateObject(GridRegion destination, UUID userID, UUID itemID) | ||
320 | { | ||
321 | // Not Implemented | ||
322 | return false; | ||
323 | } | ||
324 | |||
325 | #endregion /* IInterregionComms */ | 318 | #endregion /* IInterregionComms */ |
326 | |||
327 | } | 319 | } |
328 | } | 320 | } \ No newline at end of file |
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs index 38db239..619550c 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs | |||
@@ -41,6 +41,7 @@ using OpenSim.Framework.Serialization.External; | |||
41 | using OpenSim.Region.CoreModules.World.Terrain; | 41 | using OpenSim.Region.CoreModules.World.Terrain; |
42 | using OpenSim.Region.Framework.Interfaces; | 42 | using OpenSim.Region.Framework.Interfaces; |
43 | using OpenSim.Region.Framework.Scenes; | 43 | using OpenSim.Region.Framework.Scenes; |
44 | using OpenSim.Region.Framework.Scenes.Serialization; | ||
44 | using OpenSim.Services.Interfaces; | 45 | using OpenSim.Services.Interfaces; |
45 | 46 | ||
46 | namespace OpenSim.Region.CoreModules.World.Archiver | 47 | namespace OpenSim.Region.CoreModules.World.Archiver |
@@ -245,6 +246,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
245 | // Reload serialized prims | 246 | // Reload serialized prims |
246 | m_log.InfoFormat("[ARCHIVER]: Loading {0} scene objects. Please wait.", serialisedSceneObjects.Count); | 247 | m_log.InfoFormat("[ARCHIVER]: Loading {0} scene objects. Please wait.", serialisedSceneObjects.Count); |
247 | 248 | ||
249 | UUID oldTelehubUUID = m_scene.RegionInfo.RegionSettings.TelehubObject; | ||
250 | |||
248 | IRegionSerialiserModule serialiser = m_scene.RequestModuleInterface<IRegionSerialiserModule>(); | 251 | IRegionSerialiserModule serialiser = m_scene.RequestModuleInterface<IRegionSerialiserModule>(); |
249 | int sceneObjectsLoadedCount = 0; | 252 | int sceneObjectsLoadedCount = 0; |
250 | 253 | ||
@@ -266,11 +269,21 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
266 | 269 | ||
267 | SceneObjectGroup sceneObject = serialiser.DeserializeGroupFromXml2(serialisedSceneObject); | 270 | SceneObjectGroup sceneObject = serialiser.DeserializeGroupFromXml2(serialisedSceneObject); |
268 | 271 | ||
272 | bool isTelehub = (sceneObject.UUID == oldTelehubUUID); | ||
273 | |||
269 | // For now, give all incoming scene objects new uuids. This will allow scenes to be cloned | 274 | // For now, give all incoming scene objects new uuids. This will allow scenes to be cloned |
270 | // on the same region server and multiple examples a single object archive to be imported | 275 | // on the same region server and multiple examples a single object archive to be imported |
271 | // to the same scene (when this is possible). | 276 | // to the same scene (when this is possible). |
272 | sceneObject.ResetIDs(); | 277 | sceneObject.ResetIDs(); |
273 | 278 | ||
279 | if (isTelehub) | ||
280 | { | ||
281 | // Change the Telehub Object to the new UUID | ||
282 | m_scene.RegionInfo.RegionSettings.TelehubObject = sceneObject.UUID; | ||
283 | m_scene.RegionInfo.RegionSettings.Save(); | ||
284 | oldTelehubUUID = UUID.Zero; | ||
285 | } | ||
286 | |||
274 | // Try to retain the original creator/owner/lastowner if their uuid is present on this grid | 287 | // Try to retain the original creator/owner/lastowner if their uuid is present on this grid |
275 | // or creator data is present. Otherwise, use the estate owner instead. | 288 | // or creator data is present. Otherwise, use the estate owner instead. |
276 | foreach (SceneObjectPart part in sceneObject.Parts) | 289 | foreach (SceneObjectPart part in sceneObject.Parts) |
@@ -347,7 +360,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
347 | int ignoredObjects = serialisedSceneObjects.Count - sceneObjectsLoadedCount; | 360 | int ignoredObjects = serialisedSceneObjects.Count - sceneObjectsLoadedCount; |
348 | 361 | ||
349 | if (ignoredObjects > 0) | 362 | if (ignoredObjects > 0) |
350 | m_log.WarnFormat("[ARCHIVER]: Ignored {0} scene objects that already existed in the scene", ignoredObjects); | 363 | m_log.WarnFormat("[ARCHIVER]: Ignored {0} scene objects that already existed in the scene", ignoredObjects); |
364 | |||
365 | if (oldTelehubUUID != UUID.Zero) | ||
366 | { | ||
367 | m_log.WarnFormat("Telehub object not found: {0}", oldTelehubUUID); | ||
368 | m_scene.RegionInfo.RegionSettings.TelehubObject = UUID.Zero; | ||
369 | m_scene.RegionInfo.RegionSettings.ClearSpawnPoints(); | ||
370 | } | ||
351 | } | 371 | } |
352 | 372 | ||
353 | /// <summary> | 373 | /// <summary> |
@@ -523,6 +543,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
523 | currentRegionSettings.TerrainTexture4 = loadedRegionSettings.TerrainTexture4; | 543 | currentRegionSettings.TerrainTexture4 = loadedRegionSettings.TerrainTexture4; |
524 | currentRegionSettings.UseEstateSun = loadedRegionSettings.UseEstateSun; | 544 | currentRegionSettings.UseEstateSun = loadedRegionSettings.UseEstateSun; |
525 | currentRegionSettings.WaterHeight = loadedRegionSettings.WaterHeight; | 545 | currentRegionSettings.WaterHeight = loadedRegionSettings.WaterHeight; |
546 | currentRegionSettings.TelehubObject = loadedRegionSettings.TelehubObject; | ||
547 | currentRegionSettings.ClearSpawnPoints(); | ||
548 | foreach (SpawnPoint sp in loadedRegionSettings.SpawnPoints()) | ||
549 | currentRegionSettings.AddSpawnPoint(sp); | ||
526 | 550 | ||
527 | currentRegionSettings.Save(); | 551 | currentRegionSettings.Save(); |
528 | 552 | ||
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs index 4d459bf..4edaaca 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs | |||
@@ -40,6 +40,9 @@ using OpenSim.Framework.Serialization; | |||
40 | using OpenSim.Region.CoreModules.World.Terrain; | 40 | using OpenSim.Region.CoreModules.World.Terrain; |
41 | using OpenSim.Region.Framework.Interfaces; | 41 | using OpenSim.Region.Framework.Interfaces; |
42 | using OpenSim.Region.Framework.Scenes; | 42 | using OpenSim.Region.Framework.Scenes; |
43 | using Ionic.Zlib; | ||
44 | using GZipStream = Ionic.Zlib.GZipStream; | ||
45 | using CompressionMode = Ionic.Zlib.CompressionMode; | ||
43 | 46 | ||
44 | namespace OpenSim.Region.CoreModules.World.Archiver | 47 | namespace OpenSim.Region.CoreModules.World.Archiver |
45 | { | 48 | { |
@@ -64,7 +67,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
64 | /// Determine whether this archive will save assets. Default is true. | 67 | /// Determine whether this archive will save assets. Default is true. |
65 | /// </summary> | 68 | /// </summary> |
66 | public bool SaveAssets { get; set; } | 69 | public bool SaveAssets { get; set; } |
67 | 70 | ||
71 | protected ArchiverModule m_module; | ||
68 | protected Scene m_scene; | 72 | protected Scene m_scene; |
69 | protected Stream m_saveStream; | 73 | protected Stream m_saveStream; |
70 | protected Guid m_requestId; | 74 | protected Guid m_requestId; |
@@ -72,17 +76,17 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
72 | /// <summary> | 76 | /// <summary> |
73 | /// Constructor | 77 | /// Constructor |
74 | /// </summary> | 78 | /// </summary> |
75 | /// <param name="scene"></param> | 79 | /// <param name="module">Calling module</param> |
76 | /// <param name="savePath">The path to which to save data.</param> | 80 | /// <param name="savePath">The path to which to save data.</param> |
77 | /// <param name="requestId">The id associated with this request</param> | 81 | /// <param name="requestId">The id associated with this request</param> |
78 | /// <exception cref="System.IO.IOException"> | 82 | /// <exception cref="System.IO.IOException"> |
79 | /// If there was a problem opening a stream for the file specified by the savePath | 83 | /// If there was a problem opening a stream for the file specified by the savePath |
80 | /// </exception> | 84 | /// </exception> |
81 | public ArchiveWriteRequestPreparation(Scene scene, string savePath, Guid requestId) : this(scene, requestId) | 85 | public ArchiveWriteRequestPreparation(ArchiverModule module, string savePath, Guid requestId) : this(module, requestId) |
82 | { | 86 | { |
83 | try | 87 | try |
84 | { | 88 | { |
85 | m_saveStream = new GZipStream(new FileStream(savePath, FileMode.Create), CompressionMode.Compress); | 89 | m_saveStream = new GZipStream(new FileStream(savePath, FileMode.Create), CompressionMode.Compress, CompressionLevel.BestCompression); |
86 | } | 90 | } |
87 | catch (EntryPointNotFoundException e) | 91 | catch (EntryPointNotFoundException e) |
88 | { | 92 | { |
@@ -96,17 +100,23 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
96 | /// <summary> | 100 | /// <summary> |
97 | /// Constructor. | 101 | /// Constructor. |
98 | /// </summary> | 102 | /// </summary> |
99 | /// <param name="scene"></param> | 103 | /// <param name="module">Calling module</param> |
100 | /// <param name="saveStream">The stream to which to save data.</param> | 104 | /// <param name="saveStream">The stream to which to save data.</param> |
101 | /// <param name="requestId">The id associated with this request</param> | 105 | /// <param name="requestId">The id associated with this request</param> |
102 | public ArchiveWriteRequestPreparation(Scene scene, Stream saveStream, Guid requestId) : this(scene, requestId) | 106 | public ArchiveWriteRequestPreparation(ArchiverModule module, Stream saveStream, Guid requestId) : this(module, requestId) |
103 | { | 107 | { |
104 | m_saveStream = saveStream; | 108 | m_saveStream = saveStream; |
105 | } | 109 | } |
106 | 110 | ||
107 | protected ArchiveWriteRequestPreparation(Scene scene, Guid requestId) | 111 | protected ArchiveWriteRequestPreparation(ArchiverModule module, Guid requestId) |
108 | { | 112 | { |
109 | m_scene = scene; | 113 | m_module = module; |
114 | |||
115 | // FIXME: This is only here for regression test purposes since they do not supply a module. Need to fix | ||
116 | // this. | ||
117 | if (m_module != null) | ||
118 | m_scene = m_module.Scene; | ||
119 | |||
110 | m_requestId = requestId; | 120 | m_requestId = requestId; |
111 | 121 | ||
112 | SaveAssets = true; | 122 | SaveAssets = true; |
@@ -297,10 +307,15 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
297 | if (checkPermissions.Contains("T") && !canTransfer) | 307 | if (checkPermissions.Contains("T") && !canTransfer) |
298 | partPermitted = false; | 308 | partPermitted = false; |
299 | 309 | ||
310 | // If the user is the Creator of the object then it can always be included in the OAR | ||
311 | bool creator = (obj.CreatorID.Guid == user.Guid); | ||
312 | if (creator) | ||
313 | partPermitted = true; | ||
314 | |||
300 | //string name = (objGroup.PrimCount == 1) ? objGroup.Name : string.Format("{0} ({1}/{2})", obj.Name, primNumber, objGroup.PrimCount); | 315 | //string name = (objGroup.PrimCount == 1) ? objGroup.Name : string.Format("{0} ({1}/{2})", obj.Name, primNumber, objGroup.PrimCount); |
301 | //m_log.DebugFormat("[ARCHIVER]: Object permissions: {0}: Base={1:X4}, Owner={2:X4}, Everyone={3:X4}, permissionClass={4}, checkPermissions={5}, canCopy={6}, canTransfer={7}, permitted={8}", | 316 | //m_log.DebugFormat("[ARCHIVER]: Object permissions: {0}: Base={1:X4}, Owner={2:X4}, Everyone={3:X4}, permissionClass={4}, checkPermissions={5}, canCopy={6}, canTransfer={7}, creator={8}, permitted={9}", |
302 | // name, obj.BaseMask, obj.OwnerMask, obj.EveryoneMask, | 317 | // name, obj.BaseMask, obj.OwnerMask, obj.EveryoneMask, |
303 | // permissionClass, checkPermissions, canCopy, canTransfer, permitted); | 318 | // permissionClass, checkPermissions, canCopy, canTransfer, creator, partPermitted); |
304 | 319 | ||
305 | if (!partPermitted) | 320 | if (!partPermitted) |
306 | { | 321 | { |
@@ -320,7 +335,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
320 | /// <returns></returns> | 335 | /// <returns></returns> |
321 | public string CreateControlFile(Dictionary<string, object> options) | 336 | public string CreateControlFile(Dictionary<string, object> options) |
322 | { | 337 | { |
323 | int majorVersion = MAX_MAJOR_VERSION, minorVersion = 7; | 338 | int majorVersion = MAX_MAJOR_VERSION, minorVersion = 8; |
324 | // | 339 | // |
325 | // if (options.ContainsKey("version")) | 340 | // if (options.ContainsKey("version")) |
326 | // { | 341 | // { |
@@ -356,32 +371,66 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
356 | //if (majorVersion == 1) | 371 | //if (majorVersion == 1) |
357 | //{ | 372 | //{ |
358 | // m_log.WarnFormat("[ARCHIVER]: Please be aware that version 1.0 OARs are not compatible with OpenSim 0.7.0.2 and earlier. Please use the --version=0 option if you want to produce a compatible OAR"); | 373 | // m_log.WarnFormat("[ARCHIVER]: Please be aware that version 1.0 OARs are not compatible with OpenSim 0.7.0.2 and earlier. Please use the --version=0 option if you want to produce a compatible OAR"); |
359 | //} | 374 | //} |
375 | |||
376 | String s; | ||
360 | 377 | ||
361 | StringWriter sw = new StringWriter(); | 378 | using (StringWriter sw = new StringWriter()) |
362 | XmlTextWriter xtw = new XmlTextWriter(sw); | 379 | { |
363 | xtw.Formatting = Formatting.Indented; | 380 | using (XmlTextWriter xtw = new XmlTextWriter(sw)) |
364 | xtw.WriteStartDocument(); | 381 | { |
365 | xtw.WriteStartElement("archive"); | 382 | xtw.Formatting = Formatting.Indented; |
366 | xtw.WriteAttributeString("major_version", majorVersion.ToString()); | 383 | xtw.WriteStartDocument(); |
367 | xtw.WriteAttributeString("minor_version", minorVersion.ToString()); | 384 | xtw.WriteStartElement("archive"); |
368 | 385 | xtw.WriteAttributeString("major_version", majorVersion.ToString()); | |
369 | xtw.WriteStartElement("creation_info"); | 386 | xtw.WriteAttributeString("minor_version", minorVersion.ToString()); |
370 | DateTime now = DateTime.UtcNow; | 387 | |
371 | TimeSpan t = now - new DateTime(1970, 1, 1); | 388 | xtw.WriteStartElement("creation_info"); |
372 | xtw.WriteElementString("datetime", ((int)t.TotalSeconds).ToString()); | 389 | DateTime now = DateTime.UtcNow; |
373 | xtw.WriteElementString("id", UUID.Random().ToString()); | 390 | TimeSpan t = now - new DateTime(1970, 1, 1); |
374 | xtw.WriteEndElement(); | 391 | xtw.WriteElementString("datetime", ((int)t.TotalSeconds).ToString()); |
375 | 392 | xtw.WriteElementString("id", UUID.Random().ToString()); | |
376 | xtw.WriteElementString("assets_included", SaveAssets.ToString()); | 393 | xtw.WriteEndElement(); |
377 | 394 | ||
378 | xtw.WriteEndElement(); | 395 | xtw.WriteStartElement("region_info"); |
379 | 396 | ||
380 | xtw.Flush(); | 397 | bool isMegaregion; |
381 | xtw.Close(); | 398 | Vector2 size; |
382 | 399 | IRegionCombinerModule rcMod = null; | |
383 | String s = sw.ToString(); | 400 | |
384 | sw.Close(); | 401 | // FIXME: This is only here for regression test purposes since they do not supply a module. Need to fix |
402 | // this, possibly by doing control file creation somewhere else. | ||
403 | if (m_module != null) | ||
404 | rcMod = m_module.RegionCombinerModule; | ||
405 | |||
406 | if (rcMod != null) | ||
407 | isMegaregion = rcMod.IsRootForMegaregion(m_scene.RegionInfo.RegionID); | ||
408 | else | ||
409 | isMegaregion = false; | ||
410 | |||
411 | if (isMegaregion) | ||
412 | size = rcMod.GetSizeOfMegaregion(m_scene.RegionInfo.RegionID); | ||
413 | else | ||
414 | size = new Vector2((float)Constants.RegionSize, (float)Constants.RegionSize); | ||
415 | |||
416 | xtw.WriteElementString("is_megaregion", isMegaregion.ToString()); | ||
417 | xtw.WriteElementString("size_in_meters", string.Format("{0},{1}", size.X, size.Y)); | ||
418 | |||
419 | xtw.WriteEndElement(); | ||
420 | |||
421 | xtw.WriteElementString("assets_included", SaveAssets.ToString()); | ||
422 | |||
423 | xtw.WriteEndElement(); | ||
424 | |||
425 | xtw.Flush(); | ||
426 | } | ||
427 | |||
428 | s = sw.ToString(); | ||
429 | } | ||
430 | |||
431 | // if (m_scene != null) | ||
432 | // Console.WriteLine( | ||
433 | // "[ARCHIVE WRITE REQUEST PREPARATION]: Control file for {0} is: {1}", m_scene.RegionInfo.RegionName, s); | ||
385 | 434 | ||
386 | return s; | 435 | return s; |
387 | } | 436 | } |
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs index f5a5a8d..bf3b124 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs | |||
@@ -45,7 +45,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
45 | private static readonly ILog m_log = | 45 | private static readonly ILog m_log = |
46 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 46 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
47 | 47 | ||
48 | private Scene m_scene; | 48 | public Scene Scene { get; private set; } |
49 | public IRegionCombinerModule RegionCombinerModule { get; private set; } | ||
49 | 50 | ||
50 | /// <value> | 51 | /// <value> |
51 | /// The file used to load and save an opensimulator archive if no filename has been specified | 52 | /// The file used to load and save an opensimulator archive if no filename has been specified |
@@ -70,13 +71,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
70 | 71 | ||
71 | public void AddRegion(Scene scene) | 72 | public void AddRegion(Scene scene) |
72 | { | 73 | { |
73 | m_scene = scene; | 74 | Scene = scene; |
74 | m_scene.RegisterModuleInterface<IRegionArchiverModule>(this); | 75 | Scene.RegisterModuleInterface<IRegionArchiverModule>(this); |
75 | //m_log.DebugFormat("[ARCHIVER]: Enabled for region {0}", scene.RegionInfo.RegionName); | 76 | //m_log.DebugFormat("[ARCHIVER]: Enabled for region {0}", scene.RegionInfo.RegionName); |
76 | } | 77 | } |
77 | 78 | ||
78 | public void RegionLoaded(Scene scene) | 79 | public void RegionLoaded(Scene scene) |
79 | { | 80 | { |
81 | RegionCombinerModule = scene.RequestModuleInterface<IRegionCombinerModule>(); | ||
80 | } | 82 | } |
81 | 83 | ||
82 | public void RemoveRegion(Scene scene) | 84 | public void RemoveRegion(Scene scene) |
@@ -165,9 +167,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
165 | public void ArchiveRegion(string savePath, Guid requestId, Dictionary<string, object> options) | 167 | public void ArchiveRegion(string savePath, Guid requestId, Dictionary<string, object> options) |
166 | { | 168 | { |
167 | m_log.InfoFormat( | 169 | m_log.InfoFormat( |
168 | "[ARCHIVER]: Writing archive for region {0} to {1}", m_scene.RegionInfo.RegionName, savePath); | 170 | "[ARCHIVER]: Writing archive for region {0} to {1}", Scene.RegionInfo.RegionName, savePath); |
169 | 171 | ||
170 | new ArchiveWriteRequestPreparation(m_scene, savePath, requestId).ArchiveRegion(options); | 172 | new ArchiveWriteRequestPreparation(this, savePath, requestId).ArchiveRegion(options); |
171 | } | 173 | } |
172 | 174 | ||
173 | public void ArchiveRegion(Stream saveStream) | 175 | public void ArchiveRegion(Stream saveStream) |
@@ -182,7 +184,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
182 | 184 | ||
183 | public void ArchiveRegion(Stream saveStream, Guid requestId, Dictionary<string, object> options) | 185 | public void ArchiveRegion(Stream saveStream, Guid requestId, Dictionary<string, object> options) |
184 | { | 186 | { |
185 | new ArchiveWriteRequestPreparation(m_scene, saveStream, requestId).ArchiveRegion(options); | 187 | new ArchiveWriteRequestPreparation(this, saveStream, requestId).ArchiveRegion(options); |
186 | } | 188 | } |
187 | 189 | ||
188 | public void DearchiveRegion(string loadPath) | 190 | public void DearchiveRegion(string loadPath) |
@@ -193,9 +195,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
193 | public void DearchiveRegion(string loadPath, bool merge, bool skipAssets, Guid requestId) | 195 | public void DearchiveRegion(string loadPath, bool merge, bool skipAssets, Guid requestId) |
194 | { | 196 | { |
195 | m_log.InfoFormat( | 197 | m_log.InfoFormat( |
196 | "[ARCHIVER]: Loading archive to region {0} from {1}", m_scene.RegionInfo.RegionName, loadPath); | 198 | "[ARCHIVER]: Loading archive to region {0} from {1}", Scene.RegionInfo.RegionName, loadPath); |
197 | 199 | ||
198 | new ArchiveReadRequest(m_scene, loadPath, merge, skipAssets, requestId).DearchiveRegion(); | 200 | new ArchiveReadRequest(Scene, loadPath, merge, skipAssets, requestId).DearchiveRegion(); |
199 | } | 201 | } |
200 | 202 | ||
201 | public void DearchiveRegion(Stream loadStream) | 203 | public void DearchiveRegion(Stream loadStream) |
@@ -205,7 +207,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
205 | 207 | ||
206 | public void DearchiveRegion(Stream loadStream, bool merge, bool skipAssets, Guid requestId) | 208 | public void DearchiveRegion(Stream loadStream, bool merge, bool skipAssets, Guid requestId) |
207 | { | 209 | { |
208 | new ArchiveReadRequest(m_scene, loadStream, merge, skipAssets, requestId).DearchiveRegion(); | 210 | new ArchiveReadRequest(Scene, loadStream, merge, skipAssets, requestId).DearchiveRegion(); |
209 | } | 211 | } |
210 | } | 212 | } |
211 | } | 213 | } |
diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsDearchiver.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsDearchiver.cs index 2c04008..8c0ef88 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/AssetsDearchiver.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsDearchiver.cs | |||
@@ -46,8 +46,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
46 | { | 46 | { |
47 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 47 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
48 | 48 | ||
49 | protected static ASCIIEncoding m_asciiEncoding = new ASCIIEncoding(); | ||
50 | |||
51 | /// <summary> | 49 | /// <summary> |
52 | /// Store for asset data we received before we get the metadata | 50 | /// Store for asset data we received before we get the metadata |
53 | /// </summary> | 51 | /// </summary> |
diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs index 63f1363..5deaf52 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs | |||
@@ -68,7 +68,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests | |||
68 | SerialiserModule serialiserModule = new SerialiserModule(); | 68 | SerialiserModule serialiserModule = new SerialiserModule(); |
69 | TerrainModule terrainModule = new TerrainModule(); | 69 | TerrainModule terrainModule = new TerrainModule(); |
70 | 70 | ||
71 | m_scene = SceneHelpers.SetupScene(); | 71 | m_scene = new SceneHelpers().SetupScene(); |
72 | SceneHelpers.SetupSceneModules(m_scene, m_archiverModule, serialiserModule, terrainModule); | 72 | SceneHelpers.SetupSceneModules(m_scene, m_archiverModule, serialiserModule, terrainModule); |
73 | } | 73 | } |
74 | 74 | ||
@@ -102,9 +102,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests | |||
102 | PrimitiveBaseShape shape = PrimitiveBaseShape.CreateSphere(); | 102 | PrimitiveBaseShape shape = PrimitiveBaseShape.CreateSphere(); |
103 | Vector3 groupPosition = new Vector3(10, 20, 30); | 103 | Vector3 groupPosition = new Vector3(10, 20, 30); |
104 | Quaternion rotationOffset = new Quaternion(20, 30, 40, 50); | 104 | Quaternion rotationOffset = new Quaternion(20, 30, 40, 50); |
105 | Vector3 offsetPosition = new Vector3(5, 10, 15); | 105 | // Vector3 offsetPosition = new Vector3(5, 10, 15); |
106 | 106 | ||
107 | return new SceneObjectPart(ownerId, shape, groupPosition, rotationOffset, offsetPosition) { Name = partName }; | 107 | return new SceneObjectPart(ownerId, shape, groupPosition, rotationOffset, Vector3.Zero) { Name = partName }; |
108 | } | 108 | } |
109 | 109 | ||
110 | protected SceneObjectPart CreateSceneObjectPart2() | 110 | protected SceneObjectPart CreateSceneObjectPart2() |
@@ -292,6 +292,59 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests | |||
292 | } | 292 | } |
293 | 293 | ||
294 | /// <summary> | 294 | /// <summary> |
295 | /// Test loading an OpenSim Region Archive where the scene object parts are not ordered by link number (e.g. | ||
296 | /// 2 can come after 3). | ||
297 | /// </summary> | ||
298 | [Test] | ||
299 | public void TestLoadOarUnorderedParts() | ||
300 | { | ||
301 | TestHelpers.InMethod(); | ||
302 | |||
303 | UUID ownerId = TestHelpers.ParseTail(0xaaaa); | ||
304 | |||
305 | MemoryStream archiveWriteStream = new MemoryStream(); | ||
306 | TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream); | ||
307 | |||
308 | tar.WriteFile( | ||
309 | ArchiveConstants.CONTROL_FILE_PATH, | ||
310 | new ArchiveWriteRequestPreparation(null, (Stream)null, Guid.Empty).CreateControlFile(new Dictionary<string, Object>())); | ||
311 | |||
312 | SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, ownerId, "obj1-", 0x11); | ||
313 | SceneObjectPart sop2 | ||
314 | = SceneHelpers.CreateSceneObjectPart("obj1-Part2", TestHelpers.ParseTail(0x12), ownerId); | ||
315 | SceneObjectPart sop3 | ||
316 | = SceneHelpers.CreateSceneObjectPart("obj1-Part3", TestHelpers.ParseTail(0x13), ownerId); | ||
317 | |||
318 | // Add the parts so they will be written out in reverse order to the oar | ||
319 | sog1.AddPart(sop3); | ||
320 | sop3.LinkNum = 3; | ||
321 | sog1.AddPart(sop2); | ||
322 | sop2.LinkNum = 2; | ||
323 | |||
324 | tar.WriteFile( | ||
325 | ArchiveConstants.CreateOarObjectPath(sog1.Name, sog1.UUID, sog1.AbsolutePosition), | ||
326 | SceneObjectSerializer.ToXml2Format(sog1)); | ||
327 | |||
328 | tar.Close(); | ||
329 | |||
330 | MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray()); | ||
331 | |||
332 | lock (this) | ||
333 | { | ||
334 | m_scene.EventManager.OnOarFileLoaded += LoadCompleted; | ||
335 | m_archiverModule.DearchiveRegion(archiveReadStream); | ||
336 | } | ||
337 | |||
338 | Assert.That(m_lastErrorMessage, Is.Null); | ||
339 | |||
340 | SceneObjectPart part2 = m_scene.GetSceneObjectPart("obj1-Part2"); | ||
341 | Assert.That(part2.LinkNum, Is.EqualTo(2)); | ||
342 | |||
343 | SceneObjectPart part3 = m_scene.GetSceneObjectPart("obj1-Part3"); | ||
344 | Assert.That(part3.LinkNum, Is.EqualTo(3)); | ||
345 | } | ||
346 | |||
347 | /// <summary> | ||
295 | /// Test loading an OpenSim Region Archive. | 348 | /// Test loading an OpenSim Region Archive. |
296 | /// </summary> | 349 | /// </summary> |
297 | [Test] | 350 | [Test] |
@@ -463,7 +516,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests | |||
463 | SerialiserModule serialiserModule = new SerialiserModule(); | 516 | SerialiserModule serialiserModule = new SerialiserModule(); |
464 | TerrainModule terrainModule = new TerrainModule(); | 517 | TerrainModule terrainModule = new TerrainModule(); |
465 | 518 | ||
466 | TestScene scene2 = SceneHelpers.SetupScene(); | 519 | TestScene scene2 = new SceneHelpers().SetupScene(); |
467 | SceneHelpers.SetupSceneModules(scene2, archiverModule, serialiserModule, terrainModule); | 520 | SceneHelpers.SetupSceneModules(scene2, archiverModule, serialiserModule, terrainModule); |
468 | 521 | ||
469 | // Make sure there's a valid owner for the owner we saved (this should have been wiped if the code is | 522 | // Make sure there's a valid owner for the owner we saved (this should have been wiped if the code is |
@@ -534,6 +587,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests | |||
534 | rs.TerrainTexture4 = UUID.Parse("00000000-0000-0000-0000-000000000080"); | 587 | rs.TerrainTexture4 = UUID.Parse("00000000-0000-0000-0000-000000000080"); |
535 | rs.UseEstateSun = true; | 588 | rs.UseEstateSun = true; |
536 | rs.WaterHeight = 23; | 589 | rs.WaterHeight = 23; |
590 | rs.TelehubObject = UUID.Parse("00000000-0000-0000-0000-111111111111"); | ||
591 | rs.AddSpawnPoint(SpawnPoint.Parse("1,-2,0.33")); | ||
537 | 592 | ||
538 | tar.WriteFile(ArchiveConstants.SETTINGS_PATH + "region1.xml", RegionSettingsSerializer.Serialize(rs)); | 593 | tar.WriteFile(ArchiveConstants.SETTINGS_PATH + "region1.xml", RegionSettingsSerializer.Serialize(rs)); |
539 | 594 | ||
@@ -580,6 +635,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests | |||
580 | Assert.That(loadedRs.TerrainTexture4, Is.EqualTo(UUID.Parse("00000000-0000-0000-0000-000000000080"))); | 635 | Assert.That(loadedRs.TerrainTexture4, Is.EqualTo(UUID.Parse("00000000-0000-0000-0000-000000000080"))); |
581 | Assert.That(loadedRs.UseEstateSun, Is.True); | 636 | Assert.That(loadedRs.UseEstateSun, Is.True); |
582 | Assert.That(loadedRs.WaterHeight, Is.EqualTo(23)); | 637 | Assert.That(loadedRs.WaterHeight, Is.EqualTo(23)); |
638 | Assert.AreEqual(UUID.Zero, loadedRs.TelehubObject); // because no object was found with the original UUID | ||
639 | Assert.AreEqual(0, loadedRs.SpawnPoints().Count); | ||
583 | } | 640 | } |
584 | 641 | ||
585 | /// <summary> | 642 | /// <summary> |
@@ -607,7 +664,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests | |||
607 | SerialiserModule serialiserModule = new SerialiserModule(); | 664 | SerialiserModule serialiserModule = new SerialiserModule(); |
608 | TerrainModule terrainModule = new TerrainModule(); | 665 | TerrainModule terrainModule = new TerrainModule(); |
609 | 666 | ||
610 | Scene scene = SceneHelpers.SetupScene(); | 667 | Scene scene = new SceneHelpers().SetupScene(); |
611 | SceneHelpers.SetupSceneModules(scene, archiverModule, serialiserModule, terrainModule); | 668 | SceneHelpers.SetupSceneModules(scene, archiverModule, serialiserModule, terrainModule); |
612 | 669 | ||
613 | m_scene.AddNewSceneObject(new SceneObjectGroup(part2), false); | 670 | m_scene.AddNewSceneObject(new SceneObjectGroup(part2), false); |
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs index d2bbea3..3b84d57 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs | |||
@@ -73,7 +73,7 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
73 | "set terrain heights <corner> <min> <max> [<x>] [<y>]", | 73 | "set terrain heights <corner> <min> <max> [<x>] [<y>]", |
74 | "Sets the terrain texture heights on corner #<corner> to <min>/<max>, if <x> or <y> are specified, it will only " + | 74 | "Sets the terrain texture heights on corner #<corner> to <min>/<max>, if <x> or <y> are specified, it will only " + |
75 | "set it on regions with a matching coordinate. Specify -1 in <x> or <y> to wildcard" + | 75 | "set it on regions with a matching coordinate. Specify -1 in <x> or <y> to wildcard" + |
76 | " that coordinate. Corner # SW = 0, NW = 1, SE = 2, NE = 3.", | 76 | " that coordinate. Corner # SW = 0, NW = 1, SE = 2, NE = 3, all corners = -1.", |
77 | consoleSetTerrainHeights); | 77 | consoleSetTerrainHeights); |
78 | 78 | ||
79 | m_module.Scene.AddCommand( | 79 | m_module.Scene.AddCommand( |
@@ -143,6 +143,16 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
143 | 143 | ||
144 | switch (corner) | 144 | switch (corner) |
145 | { | 145 | { |
146 | case -1: | ||
147 | m_module.Scene.RegionInfo.RegionSettings.Elevation1SW = lowValue; | ||
148 | m_module.Scene.RegionInfo.RegionSettings.Elevation2SW = highValue; | ||
149 | m_module.Scene.RegionInfo.RegionSettings.Elevation1NW = lowValue; | ||
150 | m_module.Scene.RegionInfo.RegionSettings.Elevation2NW = highValue; | ||
151 | m_module.Scene.RegionInfo.RegionSettings.Elevation1SE = lowValue; | ||
152 | m_module.Scene.RegionInfo.RegionSettings.Elevation2SE = highValue; | ||
153 | m_module.Scene.RegionInfo.RegionSettings.Elevation1NE = lowValue; | ||
154 | m_module.Scene.RegionInfo.RegionSettings.Elevation2NE = highValue; | ||
155 | break; | ||
146 | case 0: | 156 | case 0: |
147 | m_module.Scene.RegionInfo.RegionSettings.Elevation1SW = lowValue; | 157 | m_module.Scene.RegionInfo.RegionSettings.Elevation1SW = lowValue; |
148 | m_module.Scene.RegionInfo.RegionSettings.Elevation2SW = highValue; | 158 | m_module.Scene.RegionInfo.RegionSettings.Elevation2SW = highValue; |
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index 97a2f4a..fdef9d8 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs | |||
@@ -170,12 +170,18 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
170 | sendRegionInfoPacketToAll(); | 170 | sendRegionInfoPacketToAll(); |
171 | } | 171 | } |
172 | 172 | ||
173 | public void setEstateTerrainBaseTexture(IClientAPI remoteClient, int corner, UUID texture) | 173 | public void setEstateTerrainBaseTexture(int level, UUID texture) |
174 | { | ||
175 | setEstateTerrainBaseTexture(null, level, texture); | ||
176 | sendRegionHandshakeToAll(); | ||
177 | } | ||
178 | |||
179 | public void setEstateTerrainBaseTexture(IClientAPI remoteClient, int level, UUID texture) | ||
174 | { | 180 | { |
175 | if (texture == UUID.Zero) | 181 | if (texture == UUID.Zero) |
176 | return; | 182 | return; |
177 | 183 | ||
178 | switch (corner) | 184 | switch (level) |
179 | { | 185 | { |
180 | case 0: | 186 | case 0: |
181 | Scene.RegionInfo.RegionSettings.TerrainTexture1 = texture; | 187 | Scene.RegionInfo.RegionSettings.TerrainTexture1 = texture; |
@@ -195,6 +201,11 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
195 | sendRegionInfoPacketToAll(); | 201 | sendRegionInfoPacketToAll(); |
196 | } | 202 | } |
197 | 203 | ||
204 | public void setEstateTerrainTextureHeights(int corner, float lowValue, float highValue) | ||
205 | { | ||
206 | setEstateTerrainTextureHeights(null, corner, lowValue, highValue); | ||
207 | } | ||
208 | |||
198 | public void setEstateTerrainTextureHeights(IClientAPI client, int corner, float lowValue, float highValue) | 209 | public void setEstateTerrainTextureHeights(IClientAPI client, int corner, float lowValue, float highValue) |
199 | { | 210 | { |
200 | switch (corner) | 211 | switch (corner) |
@@ -993,7 +1004,7 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
993 | { | 1004 | { |
994 | RegionHandshakeArgs args = new RegionHandshakeArgs(); | 1005 | RegionHandshakeArgs args = new RegionHandshakeArgs(); |
995 | 1006 | ||
996 | args.isEstateManager = Scene.RegionInfo.EstateSettings.IsEstateManager(remoteClient.AgentId); | 1007 | args.isEstateManager = Scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(remoteClient.AgentId); |
997 | if (Scene.RegionInfo.EstateSettings.EstateOwner != UUID.Zero && Scene.RegionInfo.EstateSettings.EstateOwner == remoteClient.AgentId) | 1008 | if (Scene.RegionInfo.EstateSettings.EstateOwner != UUID.Zero && Scene.RegionInfo.EstateSettings.EstateOwner == remoteClient.AgentId) |
998 | args.isEstateManager = true; | 1009 | args.isEstateManager = true; |
999 | 1010 | ||
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index add1551..51dcb67 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs | |||
@@ -1395,21 +1395,26 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1395 | private void EventManagerOnRegisterCaps(UUID agentID, Caps caps) | 1395 | private void EventManagerOnRegisterCaps(UUID agentID, Caps caps) |
1396 | { | 1396 | { |
1397 | string capsBase = "/CAPS/" + caps.CapsObjectPath; | 1397 | string capsBase = "/CAPS/" + caps.CapsObjectPath; |
1398 | caps.RegisterHandler("RemoteParcelRequest", | 1398 | caps.RegisterHandler( |
1399 | new RestStreamHandler("POST", capsBase + remoteParcelRequestPath, | 1399 | "RemoteParcelRequest", |
1400 | delegate(string request, string path, string param, | 1400 | new RestStreamHandler( |
1401 | IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) | 1401 | "POST", |
1402 | { | 1402 | capsBase + remoteParcelRequestPath, |
1403 | return RemoteParcelRequest(request, path, param, agentID, caps); | 1403 | (request, path, param, httpRequest, httpResponse) |
1404 | })); | 1404 | => RemoteParcelRequest(request, path, param, agentID, caps), |
1405 | "RemoteParcelRequest", | ||
1406 | agentID.ToString())); | ||
1407 | |||
1405 | UUID parcelCapID = UUID.Random(); | 1408 | UUID parcelCapID = UUID.Random(); |
1406 | caps.RegisterHandler("ParcelPropertiesUpdate", | 1409 | caps.RegisterHandler( |
1407 | new RestStreamHandler("POST", "/CAPS/" + parcelCapID, | 1410 | "ParcelPropertiesUpdate", |
1408 | delegate(string request, string path, string param, | 1411 | new RestStreamHandler( |
1409 | IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) | 1412 | "POST", |
1410 | { | 1413 | "/CAPS/" + parcelCapID, |
1411 | return ProcessPropertiesUpdate(request, path, param, agentID, caps); | 1414 | (request, path, param, httpRequest, httpResponse) |
1412 | })); | 1415 | => ProcessPropertiesUpdate(request, path, param, agentID, caps), |
1416 | "ParcelPropertiesUpdate", | ||
1417 | agentID.ToString())); | ||
1413 | } | 1418 | } |
1414 | private string ProcessPropertiesUpdate(string request, string path, string param, UUID agentID, Caps caps) | 1419 | private string ProcessPropertiesUpdate(string request, string path, string param, UUID agentID, Caps caps) |
1415 | { | 1420 | { |
@@ -1774,7 +1779,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1774 | 1779 | ||
1775 | Vector3 pos = m_scene.GetNearestAllowedPosition(targetAvatar, land); | 1780 | Vector3 pos = m_scene.GetNearestAllowedPosition(targetAvatar, land); |
1776 | 1781 | ||
1777 | targetAvatar.TeleportWithMomentum(pos); | 1782 | targetAvatar.TeleportWithMomentum(pos, null); |
1778 | targetAvatar.ControllingClient.SendAlertMessage("You have been ejected by " + parcelManager.Firstname + " " + parcelManager.Lastname); | 1783 | targetAvatar.ControllingClient.SendAlertMessage("You have been ejected by " + parcelManager.Firstname + " " + parcelManager.Lastname); |
1779 | parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected."); | 1784 | parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected."); |
1780 | 1785 | ||
diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index 5974112..4f06737 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs | |||
@@ -450,7 +450,10 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
450 | { | 450 | { |
451 | bool isMember; | 451 | bool isMember; |
452 | if (m_groupMemberCache.TryGetValue(avatar, out isMember)) | 452 | if (m_groupMemberCache.TryGetValue(avatar, out isMember)) |
453 | { | ||
454 | m_groupMemberCache.Update(avatar, isMember, m_groupMemberCacheTimeout); | ||
453 | return isMember; | 455 | return isMember; |
456 | } | ||
454 | 457 | ||
455 | IGroupsModule groupsModule = m_scene.RequestModuleInterface<IGroupsModule>(); | 458 | IGroupsModule groupsModule = m_scene.RequestModuleInterface<IGroupsModule>(); |
456 | if (groupsModule == null) | 459 | if (groupsModule == null) |
@@ -487,7 +490,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
487 | if (m_scene.Permissions.IsAdministrator(avatar)) | 490 | if (m_scene.Permissions.IsAdministrator(avatar)) |
488 | return false; | 491 | return false; |
489 | 492 | ||
490 | if (m_scene.RegionInfo.EstateSettings.IsEstateManager(avatar)) | 493 | if (m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(avatar)) |
491 | return false; | 494 | return false; |
492 | 495 | ||
493 | if (avatar == LandData.OwnerID) | 496 | if (avatar == LandData.OwnerID) |
@@ -517,7 +520,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
517 | if (m_scene.Permissions.IsAdministrator(avatar)) | 520 | if (m_scene.Permissions.IsAdministrator(avatar)) |
518 | return false; | 521 | return false; |
519 | 522 | ||
520 | if (m_scene.RegionInfo.EstateSettings.IsEstateManager(avatar)) | 523 | if (m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(avatar)) |
521 | return false; | 524 | return false; |
522 | 525 | ||
523 | if (avatar == LandData.OwnerID) | 526 | if (avatar == LandData.OwnerID) |
@@ -1230,7 +1233,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1230 | if (land.LandData.LocalID == LandData.LocalID) | 1233 | if (land.LandData.LocalID == LandData.LocalID) |
1231 | { | 1234 | { |
1232 | Vector3 pos = m_scene.GetNearestAllowedPosition(presence, land); | 1235 | Vector3 pos = m_scene.GetNearestAllowedPosition(presence, land); |
1233 | presence.TeleportWithMomentum(pos); | 1236 | presence.TeleportWithMomentum(pos, null); |
1234 | presence.ControllingClient.SendAlertMessage("You have been ejected from this land"); | 1237 | presence.ControllingClient.SendAlertMessage("You have been ejected from this land"); |
1235 | } | 1238 | } |
1236 | } | 1239 | } |
diff --git a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs index 5122734..102b4d7 100644 --- a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs | |||
@@ -126,7 +126,6 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
126 | // m_log.DebugFormat( | 126 | // m_log.DebugFormat( |
127 | // "[PRIM COUNT MODULE]: Ignoring OnParcelPrimCountAdd() for {0} on {1} since count is tainted", | 127 | // "[PRIM COUNT MODULE]: Ignoring OnParcelPrimCountAdd() for {0} on {1} since count is tainted", |
128 | // obj.Name, m_Scene.RegionInfo.RegionName); | 128 | // obj.Name, m_Scene.RegionInfo.RegionName); |
129 | |||
130 | } | 129 | } |
131 | } | 130 | } |
132 | 131 | ||
diff --git a/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs b/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs index e553ffa..b5ee4d2 100644 --- a/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs +++ b/OpenSim/Region/CoreModules/World/Land/Tests/PrimCountModuleTests.cs | |||
@@ -64,7 +64,7 @@ namespace OpenSim.Region.CoreModules.World.Land.Tests | |||
64 | { | 64 | { |
65 | m_pcm = new PrimCountModule(); | 65 | m_pcm = new PrimCountModule(); |
66 | LandManagementModule lmm = new LandManagementModule(); | 66 | LandManagementModule lmm = new LandManagementModule(); |
67 | m_scene = SceneHelpers.SetupScene(); | 67 | m_scene = new SceneHelpers().SetupScene(); |
68 | SceneHelpers.SetupSceneModules(m_scene, lmm, m_pcm); | 68 | SceneHelpers.SetupSceneModules(m_scene, lmm, m_pcm); |
69 | 69 | ||
70 | int xParcelDivider = (int)Constants.RegionSize - 1; | 70 | int xParcelDivider = (int)Constants.RegionSize - 1; |
diff --git a/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs b/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs index f86c790..aa306c7 100644 --- a/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs +++ b/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs | |||
@@ -225,7 +225,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
225 | int tc = 0; | 225 | int tc = 0; |
226 | double[,] hm = whichScene.Heightmap.GetDoubles(); | 226 | double[,] hm = whichScene.Heightmap.GetDoubles(); |
227 | tc = Environment.TickCount; | 227 | tc = Environment.TickCount; |
228 | m_log.Info("[MAPTILE]: Generating Maptile Step 2: Object Volume Profile"); | 228 | m_log.Debug("[MAPTILE]: Generating Maptile Step 2: Object Volume Profile"); |
229 | EntityBase[] objs = whichScene.GetEntities(); | 229 | EntityBase[] objs = whichScene.GetEntities(); |
230 | Dictionary<uint, DrawStruct> z_sort = new Dictionary<uint, DrawStruct>(); | 230 | Dictionary<uint, DrawStruct> z_sort = new Dictionary<uint, DrawStruct>(); |
231 | //SortedList<float, RectangleDrawStruct> z_sort = new SortedList<float, RectangleDrawStruct>(); | 231 | //SortedList<float, RectangleDrawStruct> z_sort = new SortedList<float, RectangleDrawStruct>(); |
@@ -541,7 +541,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
541 | g.Dispose(); | 541 | g.Dispose(); |
542 | } // lock entities objs | 542 | } // lock entities objs |
543 | 543 | ||
544 | m_log.Info("[MAPTILE]: Generating Maptile Step 2: Done in " + (Environment.TickCount - tc) + " ms"); | 544 | m_log.Debug("[MAPTILE]: Generating Maptile Step 2: Done in " + (Environment.TickCount - tc) + " ms"); |
545 | return mapbmp; | 545 | return mapbmp; |
546 | } | 546 | } |
547 | 547 | ||
diff --git a/OpenSim/Region/CoreModules/World/LegacyMap/ShadedMapTileRenderer.cs b/OpenSim/Region/CoreModules/World/LegacyMap/ShadedMapTileRenderer.cs index eb1a27f..992bff3 100644 --- a/OpenSim/Region/CoreModules/World/LegacyMap/ShadedMapTileRenderer.cs +++ b/OpenSim/Region/CoreModules/World/LegacyMap/ShadedMapTileRenderer.cs | |||
@@ -54,7 +54,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
54 | public void TerrainToBitmap(Bitmap mapbmp) | 54 | public void TerrainToBitmap(Bitmap mapbmp) |
55 | { | 55 | { |
56 | int tc = Environment.TickCount; | 56 | int tc = Environment.TickCount; |
57 | m_log.Info("[MAPTILE]: Generating Maptile Step 1: Terrain"); | 57 | m_log.Debug("[MAPTILE]: Generating Maptile Step 1: Terrain"); |
58 | 58 | ||
59 | double[,] hm = m_scene.Heightmap.GetDoubles(); | 59 | double[,] hm = m_scene.Heightmap.GetDoubles(); |
60 | bool ShadowDebugContinue = true; | 60 | bool ShadowDebugContinue = true; |
@@ -238,7 +238,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
238 | } | 238 | } |
239 | } | 239 | } |
240 | } | 240 | } |
241 | m_log.Info("[MAPTILE]: Generating Maptile Step 1: Done in " + (Environment.TickCount - tc) + " ms"); | 241 | m_log.Debug("[MAPTILE]: Generating Maptile Step 1: Done in " + (Environment.TickCount - tc) + " ms"); |
242 | } | 242 | } |
243 | } | 243 | } |
244 | } | 244 | } |
diff --git a/OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs b/OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs index 1d2141e..d13c2ef 100644 --- a/OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs +++ b/OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs | |||
@@ -278,7 +278,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
278 | public void TerrainToBitmap(Bitmap mapbmp) | 278 | public void TerrainToBitmap(Bitmap mapbmp) |
279 | { | 279 | { |
280 | int tc = Environment.TickCount; | 280 | int tc = Environment.TickCount; |
281 | m_log.Info("[MAPTILE]: Generating Maptile Step 1: Terrain"); | 281 | m_log.Debug("[MAPTILE]: Generating Maptile Step 1: Terrain"); |
282 | 282 | ||
283 | // These textures should be in the AssetCache anyway, as every client conneting to this | 283 | // These textures should be in the AssetCache anyway, as every client conneting to this |
284 | // region needs them. Except on start, when the map is recreated (before anyone connected), | 284 | // region needs them. Except on start, when the map is recreated (before anyone connected), |
@@ -412,7 +412,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
412 | } | 412 | } |
413 | } | 413 | } |
414 | } | 414 | } |
415 | m_log.Info("[MAPTILE]: Generating Maptile Step 1: Done in " + (Environment.TickCount - tc) + " ms"); | 415 | m_log.Debug("[MAPTILE]: Generating Maptile Step 1: Done in " + (Environment.TickCount - tc) + " ms"); |
416 | } | 416 | } |
417 | } | 417 | } |
418 | } | 418 | } |
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs index 5239f50..601e81e 100644 --- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs +++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs | |||
@@ -145,7 +145,9 @@ namespace OpenSim.Region.CoreModules.World.Media.Moap | |||
145 | 145 | ||
146 | // Even though we're registering for POST we're going to get GETS and UPDATES too | 146 | // Even though we're registering for POST we're going to get GETS and UPDATES too |
147 | caps.RegisterHandler( | 147 | caps.RegisterHandler( |
148 | "ObjectMedia", new RestStreamHandler("POST", omCapUrl, HandleObjectMediaMessage)); | 148 | "ObjectMedia", |
149 | new RestStreamHandler( | ||
150 | "POST", omCapUrl, HandleObjectMediaMessage, "ObjectMedia", agentID.ToString())); | ||
149 | } | 151 | } |
150 | 152 | ||
151 | string omuCapUrl = "/CAPS/" + UUID.Random(); | 153 | string omuCapUrl = "/CAPS/" + UUID.Random(); |
@@ -157,7 +159,9 @@ namespace OpenSim.Region.CoreModules.World.Media.Moap | |||
157 | 159 | ||
158 | // Even though we're registering for POST we're going to get GETS and UPDATES too | 160 | // Even though we're registering for POST we're going to get GETS and UPDATES too |
159 | caps.RegisterHandler( | 161 | caps.RegisterHandler( |
160 | "ObjectMediaNavigate", new RestStreamHandler("POST", omuCapUrl, HandleObjectMediaNavigateMessage)); | 162 | "ObjectMediaNavigate", |
163 | new RestStreamHandler( | ||
164 | "POST", omuCapUrl, HandleObjectMediaNavigateMessage, "ObjectMediaNavigate", agentID.ToString())); | ||
161 | } | 165 | } |
162 | } | 166 | } |
163 | 167 | ||
diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs b/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs index 4326606..396095a 100644 --- a/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs +++ b/OpenSim/Region/CoreModules/World/Media/Moap/Tests/MoapTests.cs | |||
@@ -53,7 +53,7 @@ namespace OpenSim.Region.CoreModules.World.Media.Moap.Tests | |||
53 | public void SetUp() | 53 | public void SetUp() |
54 | { | 54 | { |
55 | m_module = new MoapModule(); | 55 | m_module = new MoapModule(); |
56 | m_scene = SceneHelpers.SetupScene(); | 56 | m_scene = new SceneHelpers().SetupScene(); |
57 | SceneHelpers.SetupSceneModules(m_scene, m_module); | 57 | SceneHelpers.SetupSceneModules(m_scene, m_module); |
58 | } | 58 | } |
59 | 59 | ||
@@ -63,7 +63,7 @@ namespace OpenSim.Region.CoreModules.World.Media.Moap.Tests | |||
63 | TestHelpers.InMethod(); | 63 | TestHelpers.InMethod(); |
64 | // log4net.Config.XmlConfigurator.Configure(); | 64 | // log4net.Config.XmlConfigurator.Configure(); |
65 | 65 | ||
66 | SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene); | 66 | SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene).RootPart; |
67 | MediaEntry me = new MediaEntry(); | 67 | MediaEntry me = new MediaEntry(); |
68 | 68 | ||
69 | m_module.SetMediaEntry(part, 1, me); | 69 | m_module.SetMediaEntry(part, 1, me); |
@@ -88,7 +88,7 @@ namespace OpenSim.Region.CoreModules.World.Media.Moap.Tests | |||
88 | 88 | ||
89 | string homeUrl = "opensimulator.org"; | 89 | string homeUrl = "opensimulator.org"; |
90 | 90 | ||
91 | SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene); | 91 | SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene).RootPart; |
92 | MediaEntry me = new MediaEntry() { HomeURL = homeUrl }; | 92 | MediaEntry me = new MediaEntry() { HomeURL = homeUrl }; |
93 | 93 | ||
94 | m_module.SetMediaEntry(part, 1, me); | 94 | m_module.SetMediaEntry(part, 1, me); |
diff --git a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs index f5a5c92..e5cd3e2 100644 --- a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs +++ b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs | |||
@@ -29,8 +29,10 @@ using System; | |||
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Reflection; | 30 | using System.Reflection; |
31 | using System.Text; | 31 | using System.Text; |
32 | using System.Text.RegularExpressions; | ||
32 | using log4net; | 33 | using log4net; |
33 | using Mono.Addins; | 34 | using Mono.Addins; |
35 | using NDesk.Options; | ||
34 | using Nini.Config; | 36 | using Nini.Config; |
35 | using OpenMetaverse; | 37 | using OpenMetaverse; |
36 | using OpenSim.Framework; | 38 | using OpenSim.Framework; |
@@ -78,49 +80,64 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands | |||
78 | m_scene = scene; | 80 | m_scene = scene; |
79 | m_console = MainConsole.Instance; | 81 | m_console = MainConsole.Instance; |
80 | 82 | ||
81 | m_console.Commands.AddCommand("Regions", false, "delete object owner", | 83 | m_console.Commands.AddCommand( |
82 | "delete object owner <UUID>", | 84 | "Objects", false, "delete object owner", |
83 | "Delete a scene object by owner", HandleDeleteObject); | 85 | "delete object owner <UUID>", |
84 | m_console.Commands.AddCommand("Regions", false, "delete object creator", | 86 | "Delete a scene object by owner", HandleDeleteObject); |
85 | "delete object creator <UUID>", | 87 | |
86 | "Delete a scene object by creator", HandleDeleteObject); | 88 | m_console.Commands.AddCommand( |
87 | m_console.Commands.AddCommand("Regions", false, "delete object uuid", | 89 | "Objects", false, "delete object creator", |
88 | "delete object uuid <UUID>", | 90 | "delete object creator <UUID>", |
89 | "Delete a scene object by uuid", HandleDeleteObject); | 91 | "Delete a scene object by creator", HandleDeleteObject); |
90 | m_console.Commands.AddCommand("Regions", false, "delete object name", | 92 | |
91 | "delete object name <name>", | 93 | m_console.Commands.AddCommand( |
92 | "Delete a scene object by name", HandleDeleteObject); | 94 | "Objects", false, "delete object uuid", |
93 | m_console.Commands.AddCommand("Regions", false, "delete object outside", | 95 | "delete object uuid <UUID>", |
94 | "delete object outside", | 96 | "Delete a scene object by uuid", HandleDeleteObject); |
95 | "Delete all scene objects outside region boundaries", HandleDeleteObject); | 97 | |
98 | m_console.Commands.AddCommand( | ||
99 | "Objects", false, "delete object name", | ||
100 | "delete object name [--regex] <name>", | ||
101 | "Delete a scene object by name.", | ||
102 | "If --regex is specified then the name is treatead as a regular expression", | ||
103 | HandleDeleteObject); | ||
104 | |||
105 | m_console.Commands.AddCommand( | ||
106 | "Objects", false, "delete object outside", | ||
107 | "delete object outside", | ||
108 | "Delete all scene objects outside region boundaries", HandleDeleteObject); | ||
96 | 109 | ||
97 | m_console.Commands.AddCommand( | 110 | m_console.Commands.AddCommand( |
98 | "Regions", | 111 | "Objects", |
99 | false, | 112 | false, |
100 | "show object uuid", | 113 | "show object uuid", |
101 | "show object uuid <UUID>", | 114 | "show object uuid <UUID>", |
102 | "Show details of a scene object with the given UUID", HandleShowObjectByUuid); | 115 | "Show details of a scene object with the given UUID", HandleShowObjectByUuid); |
103 | 116 | ||
104 | m_console.Commands.AddCommand( | 117 | m_console.Commands.AddCommand( |
105 | "Regions", | 118 | "Objects", |
106 | false, | 119 | false, |
107 | "show object name", | 120 | "show object name", |
108 | "show object name <name>", | 121 | "show object name [--regex] <name>", |
109 | "Show details of scene objects with the given name", HandleShowObjectByName); | 122 | "Show details of scene objects with the given name.", |
123 | "If --regex is specified then the name is treatead as a regular expression", | ||
124 | HandleShowObjectByName); | ||
110 | 125 | ||
111 | m_console.Commands.AddCommand( | 126 | m_console.Commands.AddCommand( |
112 | "Regions", | 127 | "Objects", |
113 | false, | 128 | false, |
114 | "show part uuid", | 129 | "show part uuid", |
115 | "show part uuid <UUID>", | 130 | "show part uuid <UUID>", |
116 | "Show details of a scene object parts with the given UUID", HandleShowPartByUuid); | 131 | "Show details of a scene object parts with the given UUID", HandleShowPartByUuid); |
117 | 132 | ||
118 | m_console.Commands.AddCommand( | 133 | m_console.Commands.AddCommand( |
119 | "Regions", | 134 | "Objects", |
120 | false, | 135 | false, |
121 | "show part name", | 136 | "show part name", |
122 | "show part name <name>", | 137 | "show part name [--regex] <name>", |
123 | "Show details of scene object parts with the given name", HandleShowPartByName); | 138 | "Show details of scene object parts with the given name.", |
139 | "If --regex is specified then the name is treatead as a regular expression", | ||
140 | HandleShowPartByName); | ||
124 | } | 141 | } |
125 | 142 | ||
126 | public void RemoveRegion(Scene scene) | 143 | public void RemoveRegion(Scene scene) |
@@ -165,22 +182,38 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands | |||
165 | m_console.OutputFormat(sb.ToString()); | 182 | m_console.OutputFormat(sb.ToString()); |
166 | } | 183 | } |
167 | 184 | ||
168 | private void HandleShowObjectByName(string module, string[] cmd) | 185 | private void HandleShowObjectByName(string module, string[] cmdparams) |
169 | { | 186 | { |
170 | if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) | 187 | if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) |
171 | return; | 188 | return; |
172 | 189 | ||
173 | if (cmd.Length < 4) | 190 | bool useRegex = false; |
191 | OptionSet options = new OptionSet().Add("regex", v=> useRegex = v != null ); | ||
192 | |||
193 | List<string> mainParams = options.Parse(cmdparams); | ||
194 | |||
195 | if (mainParams.Count < 4) | ||
174 | { | 196 | { |
175 | m_console.OutputFormat("Usage: show object name <name>"); | 197 | m_console.OutputFormat("Usage: show object name [--regex] <name>"); |
176 | return; | 198 | return; |
177 | } | 199 | } |
178 | 200 | ||
179 | string name = cmd[3]; | 201 | string name = mainParams[3]; |
180 | 202 | ||
181 | List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>(); | 203 | List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>(); |
204 | Action<SceneObjectGroup> searchAction; | ||
182 | 205 | ||
183 | m_scene.ForEachSOG(so => { if (so.Name == name) { sceneObjects.Add(so); }}); | 206 | if (useRegex) |
207 | { | ||
208 | Regex nameRegex = new Regex(name); | ||
209 | searchAction = so => { if (nameRegex.IsMatch(so.Name)) { sceneObjects.Add(so); }}; | ||
210 | } | ||
211 | else | ||
212 | { | ||
213 | searchAction = so => { if (so.Name == name) { sceneObjects.Add(so); }}; | ||
214 | } | ||
215 | |||
216 | m_scene.ForEachSOG(searchAction); | ||
184 | 217 | ||
185 | if (sceneObjects.Count == 0) | 218 | if (sceneObjects.Count == 0) |
186 | { | 219 | { |
@@ -231,22 +264,39 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands | |||
231 | m_console.OutputFormat(sb.ToString()); | 264 | m_console.OutputFormat(sb.ToString()); |
232 | } | 265 | } |
233 | 266 | ||
234 | private void HandleShowPartByName(string module, string[] cmd) | 267 | private void HandleShowPartByName(string module, string[] cmdparams) |
235 | { | 268 | { |
236 | if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) | 269 | if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) |
237 | return; | 270 | return; |
238 | 271 | ||
239 | if (cmd.Length < 4) | 272 | bool useRegex = false; |
273 | OptionSet options = new OptionSet().Add("regex", v=> useRegex = v != null ); | ||
274 | |||
275 | List<string> mainParams = options.Parse(cmdparams); | ||
276 | |||
277 | if (mainParams.Count < 4) | ||
240 | { | 278 | { |
241 | m_console.OutputFormat("Usage: show part name <name>"); | 279 | m_console.OutputFormat("Usage: show part name [--regex] <name>"); |
242 | return; | 280 | return; |
243 | } | 281 | } |
244 | 282 | ||
245 | string name = cmd[3]; | 283 | string name = mainParams[3]; |
246 | 284 | ||
247 | List<SceneObjectPart> parts = new List<SceneObjectPart>(); | 285 | List<SceneObjectPart> parts = new List<SceneObjectPart>(); |
248 | 286 | ||
249 | m_scene.ForEachSOG(so => so.ForEachPart(sop => { if (sop.Name == name) { parts.Add(sop); } })); | 287 | Action<SceneObjectGroup> searchAction; |
288 | |||
289 | if (useRegex) | ||
290 | { | ||
291 | Regex nameRegex = new Regex(name); | ||
292 | searchAction = so => so.ForEachPart(sop => { if (nameRegex.IsMatch(sop.Name)) { parts.Add(sop); } }); | ||
293 | } | ||
294 | else | ||
295 | { | ||
296 | searchAction = so => so.ForEachPart(sop => { if (sop.Name == name) { parts.Add(sop); } }); | ||
297 | } | ||
298 | |||
299 | m_scene.ForEachSOG(searchAction); | ||
250 | 300 | ||
251 | if (parts.Count == 0) | 301 | if (parts.Count == 0) |
252 | { | 302 | { |
@@ -271,6 +321,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands | |||
271 | sb.AppendFormat("Description: {0}\n", so.Description); | 321 | sb.AppendFormat("Description: {0}\n", so.Description); |
272 | sb.AppendFormat("Location: {0} @ {1}\n", so.AbsolutePosition, so.Scene.RegionInfo.RegionName); | 322 | sb.AppendFormat("Location: {0} @ {1}\n", so.AbsolutePosition, so.Scene.RegionInfo.RegionName); |
273 | sb.AppendFormat("Parts: {0}\n", so.PrimCount); | 323 | sb.AppendFormat("Parts: {0}\n", so.PrimCount); |
324 | sb.AppendFormat("Flags: {0}\n", so.RootPart.Flags); | ||
274 | 325 | ||
275 | return sb; | 326 | return sb; |
276 | } | 327 | } |
@@ -282,7 +333,8 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands | |||
282 | sb.AppendFormat("Location: {0} @ {1}\n", sop.AbsolutePosition, sop.ParentGroup.Scene.RegionInfo.RegionName); | 333 | sb.AppendFormat("Location: {0} @ {1}\n", sop.AbsolutePosition, sop.ParentGroup.Scene.RegionInfo.RegionName); |
283 | sb.AppendFormat("Parent: {0}", | 334 | sb.AppendFormat("Parent: {0}", |
284 | sop.IsRoot ? "Is Root\n" : string.Format("{0} {1}\n", sop.ParentGroup.Name, sop.ParentGroup.UUID)); | 335 | sop.IsRoot ? "Is Root\n" : string.Format("{0} {1}\n", sop.ParentGroup.Name, sop.ParentGroup.UUID)); |
285 | sb.AppendFormat("Parts: {0}\n", !sop.IsRoot ? "1" : sop.ParentGroup.PrimCount.ToString());; | 336 | sb.AppendFormat("Link number: {0}\n", sop.LinkNum); |
337 | sb.AppendFormat("Flags: {0}\n", sop.Flags); | ||
286 | 338 | ||
287 | return sb; | 339 | return sb; |
288 | } | 340 | } |
@@ -306,105 +358,169 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands | |||
306 | o = cmd[3]; | 358 | o = cmd[3]; |
307 | } | 359 | } |
308 | 360 | ||
309 | List<SceneObjectGroup> deletes = new List<SceneObjectGroup>(); | 361 | List<SceneObjectGroup> deletes = null; |
310 | |||
311 | UUID match; | 362 | UUID match; |
363 | bool requireConfirmation = true; | ||
312 | 364 | ||
313 | switch (mode) | 365 | switch (mode) |
314 | { | 366 | { |
315 | case "owner": | 367 | case "owner": |
316 | if (!UUID.TryParse(o, out match)) | 368 | if (!UUID.TryParse(o, out match)) |
317 | return; | 369 | return; |
318 | 370 | ||
319 | m_scene.ForEachSOG(delegate (SceneObjectGroup g) | 371 | deletes = new List<SceneObjectGroup>(); |
320 | { | ||
321 | if (g.OwnerID == match && !g.IsAttachment) | ||
322 | deletes.Add(g); | ||
323 | }); | ||
324 | 372 | ||
325 | // if (deletes.Count == 0) | 373 | m_scene.ForEachSOG(delegate (SceneObjectGroup g) |
326 | // m_console.OutputFormat("No objects were found with owner {0}", match); | 374 | { |
327 | 375 | if (g.OwnerID == match && !g.IsAttachment) | |
328 | break; | 376 | deletes.Add(g); |
377 | }); | ||
378 | |||
379 | // if (deletes.Count == 0) | ||
380 | // m_console.OutputFormat("No objects were found with owner {0}", match); | ||
381 | |||
382 | break; | ||
383 | |||
384 | case "creator": | ||
385 | if (!UUID.TryParse(o, out match)) | ||
386 | return; | ||
329 | 387 | ||
330 | case "creator": | 388 | deletes = new List<SceneObjectGroup>(); |
331 | if (!UUID.TryParse(o, out match)) | ||
332 | return; | ||
333 | 389 | ||
334 | m_scene.ForEachSOG(delegate (SceneObjectGroup g) | 390 | m_scene.ForEachSOG(delegate (SceneObjectGroup g) |
335 | { | 391 | { |
336 | if (g.RootPart.CreatorID == match && !g.IsAttachment) | 392 | if (g.RootPart.CreatorID == match && !g.IsAttachment) |
337 | deletes.Add(g); | 393 | deletes.Add(g); |
338 | }); | 394 | }); |
395 | |||
396 | // if (deletes.Count == 0) | ||
397 | // m_console.OutputFormat("No objects were found with creator {0}", match); | ||
398 | |||
399 | break; | ||
400 | |||
401 | case "uuid": | ||
402 | if (!UUID.TryParse(o, out match)) | ||
403 | return; | ||
339 | 404 | ||
340 | // if (deletes.Count == 0) | 405 | requireConfirmation = false; |
341 | // m_console.OutputFormat("No objects were found with creator {0}", match); | 406 | deletes = new List<SceneObjectGroup>(); |
407 | |||
408 | m_scene.ForEachSOG(delegate (SceneObjectGroup g) | ||
409 | { | ||
410 | if (g.UUID == match && !g.IsAttachment) | ||
411 | deletes.Add(g); | ||
412 | }); | ||
413 | |||
414 | // if (deletes.Count == 0) | ||
415 | // m_console.OutputFormat("No objects were found with uuid {0}", match); | ||
416 | |||
417 | break; | ||
418 | |||
419 | case "name": | ||
420 | deletes = GetDeleteCandidatesByName(module, cmd); | ||
421 | break; | ||
422 | |||
423 | case "outside": | ||
424 | deletes = new List<SceneObjectGroup>(); | ||
342 | 425 | ||
343 | break; | 426 | m_scene.ForEachSOG(delegate (SceneObjectGroup g) |
427 | { | ||
428 | SceneObjectPart rootPart = g.RootPart; | ||
429 | bool delete = false; | ||
430 | |||
431 | if (rootPart.GroupPosition.Z < 0.0 || rootPart.GroupPosition.Z > 10000.0) | ||
432 | { | ||
433 | delete = true; | ||
434 | } | ||
435 | else | ||
436 | { | ||
437 | ILandObject parcel | ||
438 | = m_scene.LandChannel.GetLandObject(rootPart.GroupPosition.X, rootPart.GroupPosition.Y); | ||
439 | |||
440 | if (parcel == null || parcel.LandData.Name == "NO LAND") | ||
441 | delete = true; | ||
442 | } | ||
443 | |||
444 | if (delete && !g.IsAttachment && !deletes.Contains(g)) | ||
445 | deletes.Add(g); | ||
446 | }); | ||
447 | |||
448 | if (deletes.Count == 0) | ||
449 | m_console.OutputFormat("No objects were found outside region bounds"); | ||
450 | |||
451 | break; | ||
344 | 452 | ||
345 | case "uuid": | 453 | default: |
346 | if (!UUID.TryParse(o, out match)) | 454 | m_console.OutputFormat("Unrecognized mode {0}", mode); |
347 | return; | 455 | return; |
456 | } | ||
348 | 457 | ||
349 | m_scene.ForEachSOG(delegate (SceneObjectGroup g) | 458 | if (deletes == null || deletes.Count <= 0) |
350 | { | 459 | return; |
351 | if (g.UUID == match && !g.IsAttachment) | ||
352 | deletes.Add(g); | ||
353 | }); | ||
354 | |||
355 | // if (deletes.Count == 0) | ||
356 | // m_console.OutputFormat("No objects were found with uuid {0}", match); | ||
357 | |||
358 | break; | ||
359 | 460 | ||
360 | case "name": | 461 | if (requireConfirmation) |
361 | m_scene.ForEachSOG(delegate (SceneObjectGroup g) | 462 | { |
463 | string response = MainConsole.Instance.CmdPrompt( | ||
464 | string.Format( | ||
465 | "Are you sure that you want to delete {0} objects from {1}", | ||
466 | deletes.Count, m_scene.RegionInfo.RegionName), | ||
467 | "n"); | ||
468 | |||
469 | if (response.ToLower() != "y") | ||
362 | { | 470 | { |
363 | if (g.RootPart.Name == o && !g.IsAttachment) | 471 | MainConsole.Instance.OutputFormat( |
364 | deletes.Add(g); | 472 | "Aborting delete of {0} objects from {1}", deletes.Count, m_scene.RegionInfo.RegionName); |
365 | }); | ||
366 | 473 | ||
367 | // if (deletes.Count == 0) | 474 | return; |
368 | // m_console.OutputFormat("No objects were found with name {0}", o); | 475 | } |
369 | 476 | } | |
370 | break; | ||
371 | 477 | ||
372 | case "outside": | 478 | m_console.OutputFormat("Deleting {0} objects in {1}", deletes.Count, m_scene.RegionInfo.RegionName); |
373 | m_scene.ForEachSOG(delegate (SceneObjectGroup g) | ||
374 | { | ||
375 | SceneObjectPart rootPart = g.RootPart; | ||
376 | bool delete = false; | ||
377 | 479 | ||
378 | if (rootPart.GroupPosition.Z < 0.0 || rootPart.GroupPosition.Z > 10000.0) | 480 | foreach (SceneObjectGroup g in deletes) |
379 | { | 481 | { |
380 | delete = true; | 482 | m_console.OutputFormat("Deleting object {0} {1}", g.UUID, g.Name); |
381 | } | 483 | m_scene.DeleteSceneObject(g, false); |
382 | else | 484 | } |
383 | { | 485 | } |
384 | ILandObject parcel | ||
385 | = m_scene.LandChannel.GetLandObject(rootPart.GroupPosition.X, rootPart.GroupPosition.Y); | ||
386 | 486 | ||
387 | if (parcel == null || parcel.LandData.Name == "NO LAND") | 487 | private List<SceneObjectGroup> GetDeleteCandidatesByName(string module, string[] cmdparams) |
388 | delete = true; | 488 | { |
389 | } | 489 | if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) |
490 | return null; | ||
390 | 491 | ||
391 | if (delete && !g.IsAttachment && !deletes.Contains(g)) | 492 | bool useRegex = false; |
392 | deletes.Add(g); | 493 | OptionSet options = new OptionSet().Add("regex", v=> useRegex = v != null ); |
393 | }); | ||
394 | 494 | ||
395 | // if (deletes.Count == 0) | 495 | List<string> mainParams = options.Parse(cmdparams); |
396 | // m_console.OutputFormat("No objects were found outside region bounds"); | ||
397 | 496 | ||
398 | break; | 497 | if (mainParams.Count < 4) |
498 | { | ||
499 | m_console.OutputFormat("Usage: delete object name [--regex] <name>"); | ||
500 | return null; | ||
399 | } | 501 | } |
400 | 502 | ||
401 | m_console.OutputFormat("Deleting {0} objects in {1}", deletes.Count, m_scene.RegionInfo.RegionName); | 503 | string name = mainParams[3]; |
402 | 504 | ||
403 | foreach (SceneObjectGroup g in deletes) | 505 | List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>(); |
506 | Action<SceneObjectGroup> searchAction; | ||
507 | |||
508 | if (useRegex) | ||
404 | { | 509 | { |
405 | m_console.OutputFormat("Deleting object {0} {1}", g.UUID, g.Name); | 510 | Regex nameRegex = new Regex(name); |
406 | m_scene.DeleteSceneObject(g, false); | 511 | searchAction = so => { if (nameRegex.IsMatch(so.Name)) { sceneObjects.Add(so); }}; |
512 | } | ||
513 | else | ||
514 | { | ||
515 | searchAction = so => { if (so.Name == name) { sceneObjects.Add(so); }}; | ||
407 | } | 516 | } |
517 | |||
518 | m_scene.ForEachSOG(searchAction); | ||
519 | |||
520 | if (sceneObjects.Count == 0) | ||
521 | m_console.OutputFormat("No objects with name {0} found in {1}", name, m_scene.RegionInfo.RegionName); | ||
522 | |||
523 | return sceneObjects; | ||
408 | } | 524 | } |
409 | } | 525 | } |
410 | } \ No newline at end of file | 526 | } \ No newline at end of file |
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index 82ccaf8..f3d38bc 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs | |||
@@ -166,6 +166,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions | |||
166 | m_scene.Permissions.OnDeedParcel += CanDeedParcel; | 166 | m_scene.Permissions.OnDeedParcel += CanDeedParcel; |
167 | m_scene.Permissions.OnDeedObject += CanDeedObject; | 167 | m_scene.Permissions.OnDeedObject += CanDeedObject; |
168 | m_scene.Permissions.OnIsGod += IsGod; | 168 | m_scene.Permissions.OnIsGod += IsGod; |
169 | m_scene.Permissions.OnIsGridGod += IsGridGod; | ||
169 | m_scene.Permissions.OnIsAdministrator += IsAdministrator; | 170 | m_scene.Permissions.OnIsAdministrator += IsAdministrator; |
170 | m_scene.Permissions.OnDuplicateObject += CanDuplicateObject; | 171 | m_scene.Permissions.OnDuplicateObject += CanDuplicateObject; |
171 | m_scene.Permissions.OnDeleteObject += CanDeleteObject; //MAYBE FULLY IMPLEMENTED | 172 | m_scene.Permissions.OnDeleteObject += CanDeleteObject; //MAYBE FULLY IMPLEMENTED |
@@ -220,7 +221,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions | |||
220 | "Force permissions on or off", | 221 | "Force permissions on or off", |
221 | HandleForcePermissions); | 222 | HandleForcePermissions); |
222 | 223 | ||
223 | m_scene.AddCommand("Users", this, "debug permissions", | 224 | m_scene.AddCommand("Debug", this, "debug permissions", |
224 | "debug permissions <true / false>", | 225 | "debug permissions <true / false>", |
225 | "Turn on permissions debugging", | 226 | "Turn on permissions debugging", |
226 | HandleDebugPermissions); | 227 | HandleDebugPermissions); |
@@ -347,12 +348,12 @@ namespace OpenSim.Region.CoreModules.World.Permissions | |||
347 | m_friendsModule = m_scene.RequestModuleInterface<IFriendsModule>(); | 348 | m_friendsModule = m_scene.RequestModuleInterface<IFriendsModule>(); |
348 | 349 | ||
349 | if (m_friendsModule == null) | 350 | if (m_friendsModule == null) |
350 | m_log.Warn("[PERMISSIONS]: Friends module not found, friend permissions will not work"); | 351 | m_log.Debug("[PERMISSIONS]: Friends module not found, friend permissions will not work"); |
351 | 352 | ||
352 | m_groupsModule = m_scene.RequestModuleInterface<IGroupsModule>(); | 353 | m_groupsModule = m_scene.RequestModuleInterface<IGroupsModule>(); |
353 | 354 | ||
354 | if (m_groupsModule == null) | 355 | if (m_groupsModule == null) |
355 | m_log.Warn("[PERMISSIONS]: Groups module not found, group permissions will not work"); | 356 | m_log.Debug("[PERMISSIONS]: Groups module not found, group permissions will not work"); |
356 | 357 | ||
357 | m_moapModule = m_scene.RequestModuleInterface<IMoapModule>(); | 358 | m_moapModule = m_scene.RequestModuleInterface<IMoapModule>(); |
358 | 359 | ||
@@ -449,39 +450,49 @@ namespace OpenSim.Region.CoreModules.World.Permissions | |||
449 | } | 450 | } |
450 | 451 | ||
451 | /// <summary> | 452 | /// <summary> |
452 | /// Is the given user an administrator (in other words, a god)? | 453 | /// Is the user regarded as an administrator? |
453 | /// </summary> | 454 | /// </summary> |
454 | /// <param name="user"></param> | 455 | /// <param name="user"></param> |
455 | /// <returns></returns> | 456 | /// <returns></returns> |
456 | protected bool IsAdministrator(UUID user) | 457 | protected bool IsAdministrator(UUID user) |
457 | { | 458 | { |
458 | if (user == UUID.Zero) return false; | 459 | if (user == UUID.Zero) |
459 | 460 | return false; | |
460 | if (m_scene.RegionInfo.EstateSettings.EstateOwner != UUID.Zero) | 461 | |
461 | { | 462 | if (m_scene.RegionInfo.EstateSettings.EstateOwner == user && m_RegionOwnerIsGod) |
462 | if (m_scene.RegionInfo.EstateSettings.EstateOwner == user && m_RegionOwnerIsGod) | 463 | return true; |
463 | return true; | ||
464 | } | ||
465 | 464 | ||
466 | if (IsEstateManager(user) && m_RegionManagerIsGod) | 465 | if (IsEstateManager(user) && m_RegionManagerIsGod) |
467 | return true; | 466 | return true; |
468 | 467 | ||
468 | if (IsGridGod(user, null)) | ||
469 | return true; | ||
470 | |||
471 | return false; | ||
472 | } | ||
473 | |||
474 | /// <summary> | ||
475 | /// Is the given user a God throughout the grid (not just in the current scene)? | ||
476 | /// </summary> | ||
477 | /// <param name="user">The user</param> | ||
478 | /// <param name="scene">Unused, can be null</param> | ||
479 | /// <returns></returns> | ||
480 | protected bool IsGridGod(UUID user, Scene scene) | ||
481 | { | ||
482 | DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); | ||
483 | if (m_bypassPermissions) return m_bypassPermissionsValue; | ||
484 | |||
485 | if (user == UUID.Zero) return false; | ||
486 | |||
469 | if (m_allowGridGods) | 487 | if (m_allowGridGods) |
470 | { | 488 | { |
471 | ScenePresence sp = m_scene.GetScenePresence(user); | 489 | ScenePresence sp = m_scene.GetScenePresence(user); |
472 | if (sp != null) | 490 | if (sp != null) |
473 | { | 491 | return (sp.UserLevel >= 200); |
474 | if (sp.UserLevel >= 200) | ||
475 | return true; | ||
476 | return false; | ||
477 | } | ||
478 | 492 | ||
479 | UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, user); | 493 | UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, user); |
480 | if (account != null) | 494 | if (account != null) |
481 | { | 495 | return (account.UserLevel >= 200); |
482 | if (account.UserLevel >= 200) | ||
483 | return true; | ||
484 | } | ||
485 | } | 496 | } |
486 | 497 | ||
487 | return false; | 498 | return false; |
@@ -503,7 +514,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions | |||
503 | { | 514 | { |
504 | if (user == UUID.Zero) return false; | 515 | if (user == UUID.Zero) return false; |
505 | 516 | ||
506 | return m_scene.RegionInfo.EstateSettings.IsEstateManager(user); | 517 | return m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(user); |
507 | } | 518 | } |
508 | 519 | ||
509 | #endregion | 520 | #endregion |
diff --git a/OpenSim/Region/CoreModules/World/Region/RegionCommandsModule.cs b/OpenSim/Region/CoreModules/World/Region/RegionCommandsModule.cs new file mode 100644 index 0000000..2838e0c --- /dev/null +++ b/OpenSim/Region/CoreModules/World/Region/RegionCommandsModule.cs | |||
@@ -0,0 +1,155 @@ | |||
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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Reflection; | ||
31 | using System.Text; | ||
32 | using System.Text.RegularExpressions; | ||
33 | using log4net; | ||
34 | using Mono.Addins; | ||
35 | using NDesk.Options; | ||
36 | using Nini.Config; | ||
37 | using OpenMetaverse; | ||
38 | using OpenSim.Framework; | ||
39 | using OpenSim.Framework.Console; | ||
40 | using OpenSim.Framework.Statistics; | ||
41 | using OpenSim.Region.Framework.Interfaces; | ||
42 | using OpenSim.Region.Framework.Scenes; | ||
43 | |||
44 | namespace OpenSim.Region.CoreModules.World.Objects.Commands | ||
45 | { | ||
46 | /// <summary> | ||
47 | /// A module that holds commands for manipulating objects in the scene. | ||
48 | /// </summary> | ||
49 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RegionCommandsModule")] | ||
50 | public class RegionCommandsModule : INonSharedRegionModule | ||
51 | { | ||
52 | private Scene m_scene; | ||
53 | private ICommandConsole m_console; | ||
54 | |||
55 | public string Name { get { return "Region Commands Module"; } } | ||
56 | |||
57 | public Type ReplaceableInterface { get { return null; } } | ||
58 | |||
59 | public void Initialise(IConfigSource source) | ||
60 | { | ||
61 | // m_log.DebugFormat("[REGION COMMANDS MODULE]: INITIALIZED MODULE"); | ||
62 | } | ||
63 | |||
64 | public void PostInitialise() | ||
65 | { | ||
66 | // m_log.DebugFormat("[REGION COMMANDS MODULE]: POST INITIALIZED MODULE"); | ||
67 | } | ||
68 | |||
69 | public void Close() | ||
70 | { | ||
71 | // m_log.DebugFormat("[REGION COMMANDS MODULE]: CLOSED MODULE"); | ||
72 | } | ||
73 | |||
74 | public void AddRegion(Scene scene) | ||
75 | { | ||
76 | // m_log.DebugFormat("[REGION COMMANDS MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName); | ||
77 | |||
78 | m_scene = scene; | ||
79 | m_console = MainConsole.Instance; | ||
80 | |||
81 | m_console.Commands.AddCommand( | ||
82 | "Regions", false, "show scene", | ||
83 | "show scene", | ||
84 | "Show live scene information for the currently selected region.", HandleShowScene); | ||
85 | } | ||
86 | |||
87 | public void RemoveRegion(Scene scene) | ||
88 | { | ||
89 | // m_log.DebugFormat("[REGION COMMANDS MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName); | ||
90 | } | ||
91 | |||
92 | public void RegionLoaded(Scene scene) | ||
93 | { | ||
94 | // m_log.DebugFormat("[REGION COMMANDS MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); | ||
95 | } | ||
96 | |||
97 | private void HandleShowScene(string module, string[] cmd) | ||
98 | { | ||
99 | if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_scene)) | ||
100 | return; | ||
101 | |||
102 | SimStatsReporter r = m_scene.StatsReporter; | ||
103 | float[] stats = r.LastReportedSimStats; | ||
104 | |||
105 | float timeDilation = stats[0]; | ||
106 | float simFps = stats[1]; | ||
107 | float physicsFps = stats[2]; | ||
108 | float agentUpdates = stats[3]; | ||
109 | float rootAgents = stats[4]; | ||
110 | float childAgents = stats[5]; | ||
111 | float totalPrims = stats[6]; | ||
112 | float activePrims = stats[7]; | ||
113 | float totalFrameTime = stats[8]; | ||
114 | // float netFrameTime = stats.StatsBlock[9].StatValue; // Ignored - not used by OpenSimulator | ||
115 | float physicsFrameTime = stats[10]; | ||
116 | float otherFrameTime = stats[11]; | ||
117 | // float imageFrameTime = stats.StatsBlock[12].StatValue; // Ignored | ||
118 | float inPacketsPerSecond = stats[13]; | ||
119 | float outPacketsPerSecond = stats[14]; | ||
120 | float unackedBytes = stats[15]; | ||
121 | // float agentFrameTime = stats.StatsBlock[16].StatValue; // Not really used | ||
122 | float pendingDownloads = stats[17]; | ||
123 | float pendingUploads = stats[18]; | ||
124 | float activeScripts = stats[19]; | ||
125 | float scriptLinesPerSecond = stats[20]; | ||
126 | |||
127 | StringBuilder sb = new StringBuilder(); | ||
128 | sb.AppendFormat("Scene statistics for {0}\n", m_scene.RegionInfo.RegionName); | ||
129 | |||
130 | ConsoleDisplayList dispList = new ConsoleDisplayList(); | ||
131 | dispList.AddRow("Time Dilation", timeDilation); | ||
132 | dispList.AddRow("Sim FPS", simFps); | ||
133 | dispList.AddRow("Physics FPS", physicsFps); | ||
134 | dispList.AddRow("Avatars", rootAgents); | ||
135 | dispList.AddRow("Child agents", childAgents); | ||
136 | dispList.AddRow("Total prims", totalPrims); | ||
137 | dispList.AddRow("Scripts", activeScripts); | ||
138 | dispList.AddRow("Script lines processed per second", scriptLinesPerSecond); | ||
139 | dispList.AddRow("Physics enabled prims", activePrims); | ||
140 | dispList.AddRow("Total frame time", totalFrameTime); | ||
141 | dispList.AddRow("Physics frame time", physicsFrameTime); | ||
142 | dispList.AddRow("Other frame time", otherFrameTime); | ||
143 | dispList.AddRow("Agent Updates per second", agentUpdates); | ||
144 | dispList.AddRow("Packets processed from clients per second", inPacketsPerSecond); | ||
145 | dispList.AddRow("Packets sent to clients per second", outPacketsPerSecond); | ||
146 | dispList.AddRow("Bytes unacknowledged by clients", unackedBytes); | ||
147 | dispList.AddRow("Pending asset downloads to clients", pendingDownloads); | ||
148 | dispList.AddRow("Pending asset uploads from clients", pendingUploads); | ||
149 | |||
150 | dispList.AddToStringBuilder(sb); | ||
151 | |||
152 | MainConsole.Instance.Output(sb.ToString()); | ||
153 | } | ||
154 | } | ||
155 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs b/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs index d1d2020..7825e3e 100644 --- a/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs +++ b/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs | |||
@@ -343,7 +343,7 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests | |||
343 | public void Init() | 343 | public void Init() |
344 | { | 344 | { |
345 | m_serialiserModule = new SerialiserModule(); | 345 | m_serialiserModule = new SerialiserModule(); |
346 | m_scene = SceneHelpers.SetupScene(); | 346 | m_scene = new SceneHelpers().SetupScene(); |
347 | SceneHelpers.SetupSceneModules(m_scene, m_serialiserModule); | 347 | SceneHelpers.SetupSceneModules(m_scene, m_serialiserModule); |
348 | } | 348 | } |
349 | 349 | ||
diff --git a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs index 93b1005..d768a1a 100644 --- a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs +++ b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs | |||
@@ -78,11 +78,8 @@ namespace OpenSim.Region.CoreModules.World.Sound | |||
78 | 78 | ||
79 | if (grp.IsAttachment) | 79 | if (grp.IsAttachment) |
80 | { | 80 | { |
81 | if (grp.AttachmentPoint > 30) // HUD | 81 | if (grp.HasPrivateAttachmentPoint && sp.ControllingClient.AgentId != grp.OwnerID) |
82 | { | 82 | return; |
83 | if (sp.ControllingClient.AgentId != grp.OwnerID) | ||
84 | return; | ||
85 | } | ||
86 | 83 | ||
87 | if (sp.ControllingClient.AgentId == grp.OwnerID) | 84 | if (sp.ControllingClient.AgentId == grp.OwnerID) |
88 | dis = 0; | 85 | dis = 0; |
diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs index da81dc1..d78ade5 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/GenericSystemDrawing.cs | |||
@@ -59,28 +59,32 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders | |||
59 | /// <returns>A terrain channel generated from the image.</returns> | 59 | /// <returns>A terrain channel generated from the image.</returns> |
60 | public virtual ITerrainChannel LoadFile(string filename) | 60 | public virtual ITerrainChannel LoadFile(string filename) |
61 | { | 61 | { |
62 | return LoadBitmap(new Bitmap(filename)); | 62 | using (Bitmap b = new Bitmap(filename)) |
63 | return LoadBitmap(b); | ||
63 | } | 64 | } |
64 | 65 | ||
65 | public virtual ITerrainChannel LoadFile(string filename, int offsetX, int offsetY, int fileWidth, int fileHeight, int w, int h) | 66 | public virtual ITerrainChannel LoadFile(string filename, int offsetX, int offsetY, int fileWidth, int fileHeight, int w, int h) |
66 | { | 67 | { |
67 | Bitmap bitmap = new Bitmap(filename); | 68 | using (Bitmap bitmap = new Bitmap(filename)) |
68 | ITerrainChannel retval = new TerrainChannel(true); | ||
69 | |||
70 | for (int x = 0; x < retval.Width; x++) | ||
71 | { | 69 | { |
72 | for (int y = 0; y < retval.Height; y++) | 70 | ITerrainChannel retval = new TerrainChannel(true); |
71 | |||
72 | for (int x = 0; x < retval.Width; x++) | ||
73 | { | 73 | { |
74 | retval[x, y] = bitmap.GetPixel(offsetX * retval.Width + x, (bitmap.Height - (retval.Height * (offsetY + 1))) + retval.Height - y - 1).GetBrightness() * 128; | 74 | for (int y = 0; y < retval.Height; y++) |
75 | { | ||
76 | retval[x, y] = bitmap.GetPixel(offsetX * retval.Width + x, (bitmap.Height - (retval.Height * (offsetY + 1))) + retval.Height - y - 1).GetBrightness() * 128; | ||
77 | } | ||
75 | } | 78 | } |
76 | } | ||
77 | 79 | ||
78 | return retval; | 80 | return retval; |
81 | } | ||
79 | } | 82 | } |
80 | 83 | ||
81 | public virtual ITerrainChannel LoadStream(Stream stream) | 84 | public virtual ITerrainChannel LoadStream(Stream stream) |
82 | { | 85 | { |
83 | return LoadBitmap(new Bitmap(stream)); | 86 | using (Bitmap b = new Bitmap(stream)) |
87 | return LoadBitmap(b); | ||
84 | } | 88 | } |
85 | 89 | ||
86 | protected virtual ITerrainChannel LoadBitmap(Bitmap bitmap) | 90 | protected virtual ITerrainChannel LoadBitmap(Bitmap bitmap) |
@@ -134,35 +138,53 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders | |||
134 | // "Saving the image to the same file it was constructed from is not allowed and throws an exception." | 138 | // "Saving the image to the same file it was constructed from is not allowed and throws an exception." |
135 | string tempName = Path.GetTempFileName(); | 139 | string tempName = Path.GetTempFileName(); |
136 | 140 | ||
137 | Bitmap entireBitmap = null; | 141 | Bitmap existingBitmap = null; |
138 | Bitmap thisBitmap = null; | 142 | Bitmap thisBitmap = null; |
139 | if (File.Exists(filename)) | 143 | Bitmap newBitmap = null; |
144 | |||
145 | try | ||
140 | { | 146 | { |
141 | File.Copy(filename, tempName, true); | 147 | if (File.Exists(filename)) |
142 | entireBitmap = new Bitmap(tempName); | 148 | { |
143 | if (entireBitmap.Width != fileWidth * regionSizeX || entireBitmap.Height != fileHeight * regionSizeY) | 149 | File.Copy(filename, tempName, true); |
150 | existingBitmap = new Bitmap(tempName); | ||
151 | if (existingBitmap.Width != fileWidth * regionSizeX || existingBitmap.Height != fileHeight * regionSizeY) | ||
152 | { | ||
153 | // old file, let's overwrite it | ||
154 | newBitmap = new Bitmap(fileWidth * regionSizeX, fileHeight * regionSizeY); | ||
155 | } | ||
156 | else | ||
157 | { | ||
158 | newBitmap = existingBitmap; | ||
159 | } | ||
160 | } | ||
161 | else | ||
144 | { | 162 | { |
145 | // old file, let's overwrite it | 163 | newBitmap = new Bitmap(fileWidth * regionSizeX, fileHeight * regionSizeY); |
146 | entireBitmap = new Bitmap(fileWidth * regionSizeX, fileHeight * regionSizeY); | ||
147 | } | 164 | } |
165 | |||
166 | thisBitmap = CreateGrayscaleBitmapFromMap(m_channel); | ||
167 | // Console.WriteLine("offsetX=" + offsetX + " offsetY=" + offsetY); | ||
168 | for (int x = 0; x < regionSizeX; x++) | ||
169 | for (int y = 0; y < regionSizeY; y++) | ||
170 | newBitmap.SetPixel(x + offsetX * regionSizeX, y + (fileHeight - 1 - offsetY) * regionSizeY, thisBitmap.GetPixel(x, y)); | ||
171 | |||
172 | Save(newBitmap, filename); | ||
148 | } | 173 | } |
149 | else | 174 | finally |
150 | { | 175 | { |
151 | entireBitmap = new Bitmap(fileWidth * regionSizeX, fileHeight * regionSizeY); | 176 | if (existingBitmap != null) |
152 | } | 177 | existingBitmap.Dispose(); |
153 | 178 | ||
154 | thisBitmap = CreateGrayscaleBitmapFromMap(m_channel); | 179 | if (thisBitmap != null) |
155 | // Console.WriteLine("offsetX=" + offsetX + " offsetY=" + offsetY); | 180 | thisBitmap.Dispose(); |
156 | for (int x = 0; x < regionSizeX; x++) | ||
157 | for (int y = 0; y < regionSizeY; y++) | ||
158 | entireBitmap.SetPixel(x + offsetX * regionSizeX, y + (fileHeight - 1 - offsetY) * regionSizeY, thisBitmap.GetPixel(x, y)); | ||
159 | 181 | ||
160 | Save(entireBitmap, filename); | 182 | if (newBitmap != null) |
161 | thisBitmap.Dispose(); | 183 | newBitmap.Dispose(); |
162 | entireBitmap.Dispose(); | ||
163 | 184 | ||
164 | if (File.Exists(tempName)) | 185 | if (File.Exists(tempName)) |
165 | File.Delete(tempName); | 186 | File.Delete(tempName); |
187 | } | ||
166 | } | 188 | } |
167 | 189 | ||
168 | protected virtual void Save(Bitmap bmp, string filename) | 190 | protected virtual void Save(Bitmap bmp, string filename) |
@@ -226,16 +248,21 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders | |||
226 | /// <returns>A System.Drawing.Bitmap containing a coloured image</returns> | 248 | /// <returns>A System.Drawing.Bitmap containing a coloured image</returns> |
227 | protected static Bitmap CreateBitmapFromMap(ITerrainChannel map) | 249 | protected static Bitmap CreateBitmapFromMap(ITerrainChannel map) |
228 | { | 250 | { |
229 | Bitmap gradientmapLd = new Bitmap("defaultstripe.png"); | 251 | int pallete; |
230 | 252 | Bitmap bmp; | |
231 | int pallete = gradientmapLd.Height; | 253 | Color[] colours; |
232 | 254 | ||
233 | Bitmap bmp = new Bitmap(map.Width, map.Height); | 255 | using (Bitmap gradientmapLd = new Bitmap("defaultstripe.png")) |
234 | Color[] colours = new Color[pallete]; | ||
235 | |||
236 | for (int i = 0; i < pallete; i++) | ||
237 | { | 256 | { |
238 | colours[i] = gradientmapLd.GetPixel(0, i); | 257 | pallete = gradientmapLd.Height; |
258 | |||
259 | bmp = new Bitmap(map.Width, map.Height); | ||
260 | colours = new Color[pallete]; | ||
261 | |||
262 | for (int i = 0; i < pallete; i++) | ||
263 | { | ||
264 | colours[i] = gradientmapLd.GetPixel(0, i); | ||
265 | } | ||
239 | } | 266 | } |
240 | 267 | ||
241 | for (int y = 0; y < map.Height; y++) | 268 | for (int y = 0; y < map.Height; y++) |
diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/JPEG.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/JPEG.cs index 699d67a..9cc767a 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/JPEG.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/JPEG.cs | |||
@@ -99,16 +99,21 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders | |||
99 | 99 | ||
100 | private static Bitmap CreateBitmapFromMap(ITerrainChannel map) | 100 | private static Bitmap CreateBitmapFromMap(ITerrainChannel map) |
101 | { | 101 | { |
102 | Bitmap gradientmapLd = new Bitmap("defaultstripe.png"); | 102 | int pallete; |
103 | Bitmap bmp; | ||
104 | Color[] colours; | ||
103 | 105 | ||
104 | int pallete = gradientmapLd.Height; | 106 | using (Bitmap gradientmapLd = new Bitmap("defaultstripe.png")) |
105 | |||
106 | Bitmap bmp = new Bitmap(map.Width, map.Height); | ||
107 | Color[] colours = new Color[pallete]; | ||
108 | |||
109 | for (int i = 0; i < pallete; i++) | ||
110 | { | 107 | { |
111 | colours[i] = gradientmapLd.GetPixel(0, i); | 108 | pallete = gradientmapLd.Height; |
109 | |||
110 | bmp = new Bitmap(map.Width, map.Height); | ||
111 | colours = new Color[pallete]; | ||
112 | |||
113 | for (int i = 0; i < pallete; i++) | ||
114 | { | ||
115 | colours[i] = gradientmapLd.GetPixel(0, i); | ||
116 | } | ||
112 | } | 117 | } |
113 | 118 | ||
114 | for (int y = 0; y < map.Height; y++) | 119 | for (int y = 0; y < map.Height; y++) |
diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/TIFF.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/TIFF.cs index 5d2f893..b416b82 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/TIFF.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/TIFF.cs | |||
@@ -59,7 +59,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders | |||
59 | } | 59 | } |
60 | 60 | ||
61 | //Returns true if this extension is supported for terrain save-tile | 61 | //Returns true if this extension is supported for terrain save-tile |
62 | public bool SupportsTileSave() | 62 | public override bool SupportsTileSave() |
63 | { | 63 | { |
64 | return false; | 64 | return false; |
65 | } | 65 | } |
diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs index 1ebf916..b5c7d33 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs | |||
@@ -65,7 +65,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders | |||
65 | bool eof = false; | 65 | bool eof = false; |
66 | 66 | ||
67 | int fileXPoints = 0; | 67 | int fileXPoints = 0; |
68 | int fileYPoints = 0; | 68 | // int fileYPoints = 0; |
69 | 69 | ||
70 | // Terragen file | 70 | // Terragen file |
71 | while (eof == false) | 71 | while (eof == false) |
@@ -75,7 +75,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders | |||
75 | { | 75 | { |
76 | case "SIZE": | 76 | case "SIZE": |
77 | fileXPoints = bs.ReadInt16() + 1; | 77 | fileXPoints = bs.ReadInt16() + 1; |
78 | fileYPoints = fileXPoints; | 78 | // fileYPoints = fileXPoints; |
79 | bs.ReadInt16(); | 79 | bs.ReadInt16(); |
80 | break; | 80 | break; |
81 | case "XPTS": | 81 | case "XPTS": |
@@ -83,7 +83,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders | |||
83 | bs.ReadInt16(); | 83 | bs.ReadInt16(); |
84 | break; | 84 | break; |
85 | case "YPTS": | 85 | case "YPTS": |
86 | fileYPoints = bs.ReadInt16(); | 86 | // fileYPoints = bs.ReadInt16(); |
87 | bs.ReadInt16(); | ||
87 | bs.ReadInt16(); | 88 | bs.ReadInt16(); |
88 | break; | 89 | break; |
89 | case "ALTW": | 90 | case "ALTW": |
@@ -164,10 +165,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders | |||
164 | bool eof = false; | 165 | bool eof = false; |
165 | if (Encoding.ASCII.GetString(bs.ReadBytes(16)) == "TERRAGENTERRAIN ") | 166 | if (Encoding.ASCII.GetString(bs.ReadBytes(16)) == "TERRAGENTERRAIN ") |
166 | { | 167 | { |
167 | 168 | // int fileWidth = w; | |
168 | int fileWidth = w; | 169 | // int fileHeight = h; |
169 | int fileHeight = h; | ||
170 | |||
171 | 170 | ||
172 | // Terragen file | 171 | // Terragen file |
173 | while (eof == false) | 172 | while (eof == false) |
@@ -176,17 +175,20 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders | |||
176 | switch (tmp) | 175 | switch (tmp) |
177 | { | 176 | { |
178 | case "SIZE": | 177 | case "SIZE": |
179 | int sztmp = bs.ReadInt16() + 1; | 178 | // int sztmp = bs.ReadInt16() + 1; |
180 | fileWidth = sztmp; | 179 | // fileWidth = sztmp; |
181 | fileHeight = sztmp; | 180 | // fileHeight = sztmp; |
181 | bs.ReadInt16(); | ||
182 | bs.ReadInt16(); | 182 | bs.ReadInt16(); |
183 | break; | 183 | break; |
184 | case "XPTS": | 184 | case "XPTS": |
185 | fileWidth = bs.ReadInt16(); | 185 | // fileWidth = bs.ReadInt16(); |
186 | bs.ReadInt16(); | ||
186 | bs.ReadInt16(); | 187 | bs.ReadInt16(); |
187 | break; | 188 | break; |
188 | case "YPTS": | 189 | case "YPTS": |
189 | fileHeight = bs.ReadInt16(); | 190 | // fileHeight = bs.ReadInt16(); |
191 | bs.ReadInt16(); | ||
190 | bs.ReadInt16(); | 192 | bs.ReadInt16(); |
191 | break; | 193 | break; |
192 | case "ALTW": | 194 | case "ALTW": |
@@ -250,7 +252,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders | |||
250 | if (horizontalScale < 0.01d) | 252 | if (horizontalScale < 0.01d) |
251 | horizontalScale = 0.01d; | 253 | horizontalScale = 0.01d; |
252 | 254 | ||
253 | System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding(); | 255 | Encoding enc = Encoding.ASCII; |
254 | 256 | ||
255 | bs.Write(enc.GetBytes("TERRAGENTERRAIN ")); | 257 | bs.Write(enc.GetBytes("TERRAGENTERRAIN ")); |
256 | 258 | ||
diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs index e2bd769..402b9fb 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs | |||
@@ -724,6 +724,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
724 | } | 724 | } |
725 | if (shouldTaint) | 725 | if (shouldTaint) |
726 | { | 726 | { |
727 | m_scene.EventManager.TriggerTerrainTainted(); | ||
727 | m_tainted = true; | 728 | m_tainted = true; |
728 | } | 729 | } |
729 | } | 730 | } |
@@ -1109,6 +1110,32 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1109 | CheckForTerrainUpdates(); | 1110 | CheckForTerrainUpdates(); |
1110 | } | 1111 | } |
1111 | 1112 | ||
1113 | private void InterfaceMinTerrain(Object[] args) | ||
1114 | { | ||
1115 | int x, y; | ||
1116 | for (x = 0; x < m_channel.Width; x++) | ||
1117 | { | ||
1118 | for (y = 0; y < m_channel.Height; y++) | ||
1119 | { | ||
1120 | m_channel[x, y] = Math.Max((double)args[0], m_channel[x, y]); | ||
1121 | } | ||
1122 | } | ||
1123 | CheckForTerrainUpdates(); | ||
1124 | } | ||
1125 | |||
1126 | private void InterfaceMaxTerrain(Object[] args) | ||
1127 | { | ||
1128 | int x, y; | ||
1129 | for (x = 0; x < m_channel.Width; x++) | ||
1130 | { | ||
1131 | for (y = 0; y < m_channel.Height; y++) | ||
1132 | { | ||
1133 | m_channel[x, y] = Math.Min((double)args[0], m_channel[x, y]); | ||
1134 | } | ||
1135 | } | ||
1136 | CheckForTerrainUpdates(); | ||
1137 | } | ||
1138 | |||
1112 | private void InterfaceShowDebugStats(Object[] args) | 1139 | private void InterfaceShowDebugStats(Object[] args) |
1113 | { | 1140 | { |
1114 | double max = Double.MinValue; | 1141 | double max = Double.MinValue; |
@@ -1249,6 +1276,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1249 | rescaleCommand.AddArgument("min", "min terrain height after rescaling", "Double"); | 1276 | rescaleCommand.AddArgument("min", "min terrain height after rescaling", "Double"); |
1250 | rescaleCommand.AddArgument("max", "max terrain height after rescaling", "Double"); | 1277 | rescaleCommand.AddArgument("max", "max terrain height after rescaling", "Double"); |
1251 | 1278 | ||
1279 | Command minCommand = new Command("min", CommandIntentions.COMMAND_HAZARDOUS, InterfaceMinTerrain, "Sets the minimum terrain height to the specified value."); | ||
1280 | minCommand.AddArgument("min", "terrain height to use as minimum", "Double"); | ||
1281 | |||
1282 | Command maxCommand = new Command("max", CommandIntentions.COMMAND_HAZARDOUS, InterfaceMaxTerrain, "Sets the maximum terrain height to the specified value."); | ||
1283 | maxCommand.AddArgument("min", "terrain height to use as maximum", "Double"); | ||
1284 | |||
1252 | 1285 | ||
1253 | // Debug | 1286 | // Debug |
1254 | Command showDebugStatsCommand = | 1287 | Command showDebugStatsCommand = |
@@ -1280,6 +1313,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1280 | m_commander.RegisterCommand("effect", pluginRunCommand); | 1313 | m_commander.RegisterCommand("effect", pluginRunCommand); |
1281 | m_commander.RegisterCommand("flip", flipCommand); | 1314 | m_commander.RegisterCommand("flip", flipCommand); |
1282 | m_commander.RegisterCommand("rescale", rescaleCommand); | 1315 | m_commander.RegisterCommand("rescale", rescaleCommand); |
1316 | m_commander.RegisterCommand("min", minCommand); | ||
1317 | m_commander.RegisterCommand("max", maxCommand); | ||
1283 | 1318 | ||
1284 | // Add this to our scene so scripts can call these functions | 1319 | // Add this to our scene so scripts can call these functions |
1285 | m_scene.RegisterModuleCommander(m_commander); | 1320 | m_scene.RegisterModuleCommander(m_commander); |
diff --git a/OpenSim/Region/CoreModules/World/Warp3DMap/TerrainSplat.cs b/OpenSim/Region/CoreModules/World/Warp3DMap/TerrainSplat.cs index 7bf675d..df5ac92 100644 --- a/OpenSim/Region/CoreModules/World/Warp3DMap/TerrainSplat.cs +++ b/OpenSim/Region/CoreModules/World/Warp3DMap/TerrainSplat.cs | |||
@@ -84,218 +84,241 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
84 | Debug.Assert(heightRanges.Length == 4); | 84 | Debug.Assert(heightRanges.Length == 4); |
85 | 85 | ||
86 | Bitmap[] detailTexture = new Bitmap[4]; | 86 | Bitmap[] detailTexture = new Bitmap[4]; |
87 | Bitmap output = null; | ||
88 | BitmapData outputData = null; | ||
87 | 89 | ||
88 | if (textureTerrain) | 90 | try |
89 | { | 91 | { |
90 | // Swap empty terrain textureIDs with default IDs | 92 | if (textureTerrain) |
91 | for (int i = 0; i < textureIDs.Length; i++) | ||
92 | { | 93 | { |
93 | if (textureIDs[i] == UUID.Zero) | 94 | // Swap empty terrain textureIDs with default IDs |
94 | textureIDs[i] = DEFAULT_TERRAIN_DETAIL[i]; | 95 | for (int i = 0; i < textureIDs.Length; i++) |
95 | } | ||
96 | |||
97 | #region Texture Fetching | ||
98 | |||
99 | if (assetService != null) | ||
100 | { | ||
101 | for (int i = 0; i < 4; i++) | ||
102 | { | 96 | { |
103 | AssetBase asset; | 97 | if (textureIDs[i] == UUID.Zero) |
104 | UUID cacheID = UUID.Combine(TERRAIN_CACHE_MAGIC, textureIDs[i]); | 98 | textureIDs[i] = DEFAULT_TERRAIN_DETAIL[i]; |
105 | 99 | } | |
106 | // Try to fetch a cached copy of the decoded/resized version of this texture | 100 | |
107 | asset = assetService.GetCached(cacheID.ToString()); | 101 | #region Texture Fetching |
108 | if (asset != null) | 102 | |
109 | { | 103 | if (assetService != null) |
110 | try | 104 | { |
111 | { | 105 | for (int i = 0; i < 4; i++) |
112 | using (System.IO.MemoryStream stream = new System.IO.MemoryStream(asset.Data)) | ||
113 | detailTexture[i] = (Bitmap)Image.FromStream(stream); | ||
114 | } | ||
115 | catch (Exception ex) | ||
116 | { | ||
117 | m_log.Warn("Failed to decode cached terrain texture " + cacheID + | ||
118 | " (textureID: " + textureIDs[i] + "): " + ex.Message); | ||
119 | } | ||
120 | } | ||
121 | |||
122 | if (detailTexture[i] == null) | ||
123 | { | 106 | { |
124 | // Try to fetch the original JPEG2000 texture, resize if needed, and cache as PNG | 107 | AssetBase asset; |
125 | asset = assetService.Get(textureIDs[i].ToString()); | 108 | UUID cacheID = UUID.Combine(TERRAIN_CACHE_MAGIC, textureIDs[i]); |
109 | |||
110 | // Try to fetch a cached copy of the decoded/resized version of this texture | ||
111 | asset = assetService.GetCached(cacheID.ToString()); | ||
126 | if (asset != null) | 112 | if (asset != null) |
127 | { | 113 | { |
128 | try { detailTexture[i] = (Bitmap)CSJ2K.J2kImage.FromBytes(asset.Data); } | 114 | // m_log.DebugFormat( |
115 | // "[TERRAIN SPLAT]: Got asset service cached terrain texture {0} {1}", i, asset.ID); | ||
116 | |||
117 | try | ||
118 | { | ||
119 | using (System.IO.MemoryStream stream = new System.IO.MemoryStream(asset.Data)) | ||
120 | detailTexture[i] = (Bitmap)Image.FromStream(stream); | ||
121 | } | ||
129 | catch (Exception ex) | 122 | catch (Exception ex) |
130 | { | 123 | { |
131 | m_log.Warn("Failed to decode terrain texture " + asset.ID + ": " + ex.Message); | 124 | m_log.Warn("Failed to decode cached terrain texture " + cacheID + |
125 | " (textureID: " + textureIDs[i] + "): " + ex.Message); | ||
132 | } | 126 | } |
133 | } | 127 | } |
134 | 128 | ||
135 | if (detailTexture[i] != null) | 129 | if (detailTexture[i] == null) |
136 | { | 130 | { |
137 | Bitmap bitmap = detailTexture[i]; | 131 | // Try to fetch the original JPEG2000 texture, resize if needed, and cache as PNG |
138 | 132 | asset = assetService.Get(textureIDs[i].ToString()); | |
139 | // Make sure this texture is the correct size, otherwise resize | 133 | if (asset != null) |
140 | if (bitmap.Width != 256 || bitmap.Height != 256) | ||
141 | bitmap = ImageUtils.ResizeImage(bitmap, 256, 256); | ||
142 | |||
143 | // Save the decoded and resized texture to the cache | ||
144 | byte[] data; | ||
145 | using (System.IO.MemoryStream stream = new System.IO.MemoryStream()) | ||
146 | { | 134 | { |
147 | bitmap.Save(stream, ImageFormat.Png); | 135 | // m_log.DebugFormat( |
148 | data = stream.ToArray(); | 136 | // "[TERRAIN SPLAT]: Got cached original JPEG2000 terrain texture {0} {1}", i, asset.ID); |
137 | |||
138 | try { detailTexture[i] = (Bitmap)CSJ2K.J2kImage.FromBytes(asset.Data); } | ||
139 | catch (Exception ex) | ||
140 | { | ||
141 | m_log.Warn("Failed to decode terrain texture " + asset.ID + ": " + ex.Message); | ||
142 | } | ||
143 | } | ||
144 | |||
145 | if (detailTexture[i] != null) | ||
146 | { | ||
147 | // Make sure this texture is the correct size, otherwise resize | ||
148 | if (detailTexture[i].Width != 256 || detailTexture[i].Height != 256) | ||
149 | { | ||
150 | using (Bitmap origBitmap = detailTexture[i]) | ||
151 | { | ||
152 | detailTexture[i] = ImageUtils.ResizeImage(origBitmap, 256, 256); | ||
153 | } | ||
154 | } | ||
155 | |||
156 | // Save the decoded and resized texture to the cache | ||
157 | byte[] data; | ||
158 | using (System.IO.MemoryStream stream = new System.IO.MemoryStream()) | ||
159 | { | ||
160 | detailTexture[i].Save(stream, ImageFormat.Png); | ||
161 | data = stream.ToArray(); | ||
162 | } | ||
163 | |||
164 | // Cache a PNG copy of this terrain texture | ||
165 | AssetBase newAsset = new AssetBase | ||
166 | { | ||
167 | Data = data, | ||
168 | Description = "PNG", | ||
169 | Flags = AssetFlags.Collectable, | ||
170 | FullID = cacheID, | ||
171 | ID = cacheID.ToString(), | ||
172 | Local = true, | ||
173 | Name = String.Empty, | ||
174 | Temporary = true, | ||
175 | Type = (sbyte)AssetType.Unknown | ||
176 | }; | ||
177 | newAsset.Metadata.ContentType = "image/png"; | ||
178 | assetService.Store(newAsset); | ||
149 | } | 179 | } |
150 | |||
151 | // Cache a PNG copy of this terrain texture | ||
152 | AssetBase newAsset = new AssetBase | ||
153 | { | ||
154 | Data = data, | ||
155 | Description = "PNG", | ||
156 | Flags = AssetFlags.Collectable, | ||
157 | FullID = cacheID, | ||
158 | ID = cacheID.ToString(), | ||
159 | Local = true, | ||
160 | Name = String.Empty, | ||
161 | Temporary = true, | ||
162 | Type = (sbyte)AssetType.Unknown | ||
163 | }; | ||
164 | newAsset.Metadata.ContentType = "image/png"; | ||
165 | assetService.Store(newAsset); | ||
166 | } | 180 | } |
167 | } | 181 | } |
168 | } | 182 | } |
183 | |||
184 | #endregion Texture Fetching | ||
169 | } | 185 | } |
170 | 186 | ||
171 | #endregion Texture Fetching | 187 | // Fill in any missing textures with a solid color |
172 | } | 188 | for (int i = 0; i < 4; i++) |
173 | |||
174 | // Fill in any missing textures with a solid color | ||
175 | for (int i = 0; i < 4; i++) | ||
176 | { | ||
177 | if (detailTexture[i] == null) | ||
178 | { | 189 | { |
179 | // Create a solid color texture for this layer | 190 | if (detailTexture[i] == null) |
180 | detailTexture[i] = new Bitmap(256, 256, PixelFormat.Format24bppRgb); | ||
181 | using (Graphics gfx = Graphics.FromImage(detailTexture[i])) | ||
182 | { | 191 | { |
183 | using (SolidBrush brush = new SolidBrush(DEFAULT_TERRAIN_COLOR[i])) | 192 | // m_log.DebugFormat( |
184 | gfx.FillRectangle(brush, 0, 0, 256, 256); | 193 | // "[TERRAIN SPLAT]: Generating solid colour for missing texture {0}", i); |
185 | } | ||
186 | } | ||
187 | } | ||
188 | |||
189 | #region Layer Map | ||
190 | |||
191 | float[] layermap = new float[256 * 256]; | ||
192 | |||
193 | for (int y = 0; y < 256; y++) | ||
194 | { | ||
195 | for (int x = 0; x < 256; x++) | ||
196 | { | ||
197 | float height = heightmap[y * 256 + x]; | ||
198 | 194 | ||
199 | float pctX = (float)x / 255f; | 195 | // Create a solid color texture for this layer |
200 | float pctY = (float)y / 255f; | 196 | detailTexture[i] = new Bitmap(256, 256, PixelFormat.Format24bppRgb); |
201 | 197 | using (Graphics gfx = Graphics.FromImage(detailTexture[i])) | |
202 | // Use bilinear interpolation between the four corners of start height and | 198 | { |
203 | // height range to select the current values at this position | 199 | using (SolidBrush brush = new SolidBrush(DEFAULT_TERRAIN_COLOR[i])) |
204 | float startHeight = ImageUtils.Bilinear( | 200 | gfx.FillRectangle(brush, 0, 0, 256, 256); |
205 | startHeights[0], | 201 | } |
206 | startHeights[2], | 202 | } |
207 | startHeights[1], | ||
208 | startHeights[3], | ||
209 | pctX, pctY); | ||
210 | startHeight = Utils.Clamp(startHeight, 0f, 255f); | ||
211 | |||
212 | float heightRange = ImageUtils.Bilinear( | ||
213 | heightRanges[0], | ||
214 | heightRanges[2], | ||
215 | heightRanges[1], | ||
216 | heightRanges[3], | ||
217 | pctX, pctY); | ||
218 | heightRange = Utils.Clamp(heightRange, 0f, 255f); | ||
219 | |||
220 | // Generate two frequencies of perlin noise based on our global position | ||
221 | // The magic values were taken from http://opensimulator.org/wiki/Terrain_Splatting | ||
222 | Vector3 vec = new Vector3 | ||
223 | ( | ||
224 | ((float)regionPosition.X + x) * 0.20319f, | ||
225 | ((float)regionPosition.Y + y) * 0.20319f, | ||
226 | height * 0.25f | ||
227 | ); | ||
228 | |||
229 | float lowFreq = Perlin.noise2(vec.X * 0.222222f, vec.Y * 0.222222f) * 6.5f; | ||
230 | float highFreq = Perlin.turbulence2(vec.X, vec.Y, 2f) * 2.25f; | ||
231 | float noise = (lowFreq + highFreq) * 2f; | ||
232 | |||
233 | // Combine the current height, generated noise, start height, and height range parameters, then scale all of it | ||
234 | float layer = ((height + noise - startHeight) / heightRange) * 4f; | ||
235 | if (Single.IsNaN(layer)) layer = 0f; | ||
236 | layermap[y * 256 + x] = Utils.Clamp(layer, 0f, 3f); | ||
237 | } | 203 | } |
238 | } | 204 | |
239 | 205 | #region Layer Map | |
240 | #endregion Layer Map | 206 | |
241 | 207 | float[] layermap = new float[256 * 256]; | |
242 | #region Texture Compositing | 208 | |
243 | |||
244 | Bitmap output = new Bitmap(256, 256, PixelFormat.Format24bppRgb); | ||
245 | BitmapData outputData = output.LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb); | ||
246 | |||
247 | unsafe | ||
248 | { | ||
249 | // Get handles to all of the texture data arrays | ||
250 | BitmapData[] datas = new BitmapData[] | ||
251 | { | ||
252 | detailTexture[0].LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, detailTexture[0].PixelFormat), | ||
253 | detailTexture[1].LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, detailTexture[1].PixelFormat), | ||
254 | detailTexture[2].LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, detailTexture[2].PixelFormat), | ||
255 | detailTexture[3].LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, detailTexture[3].PixelFormat) | ||
256 | }; | ||
257 | |||
258 | int[] comps = new int[] | ||
259 | { | ||
260 | (datas[0].PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3, | ||
261 | (datas[1].PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3, | ||
262 | (datas[2].PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3, | ||
263 | (datas[3].PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3 | ||
264 | }; | ||
265 | |||
266 | for (int y = 0; y < 256; y++) | 209 | for (int y = 0; y < 256; y++) |
267 | { | 210 | { |
268 | for (int x = 0; x < 256; x++) | 211 | for (int x = 0; x < 256; x++) |
269 | { | 212 | { |
270 | float layer = layermap[y * 256 + x]; | 213 | float height = heightmap[y * 256 + x]; |
271 | 214 | ||
272 | // Select two textures | 215 | float pctX = (float)x / 255f; |
273 | int l0 = (int)Math.Floor(layer); | 216 | float pctY = (float)y / 255f; |
274 | int l1 = Math.Min(l0 + 1, 3); | 217 | |
275 | 218 | // Use bilinear interpolation between the four corners of start height and | |
276 | byte* ptrA = (byte*)datas[l0].Scan0 + y * datas[l0].Stride + x * comps[l0]; | 219 | // height range to select the current values at this position |
277 | byte* ptrB = (byte*)datas[l1].Scan0 + y * datas[l1].Stride + x * comps[l1]; | 220 | float startHeight = ImageUtils.Bilinear( |
278 | byte* ptrO = (byte*)outputData.Scan0 + y * outputData.Stride + x * 3; | 221 | startHeights[0], |
279 | 222 | startHeights[2], | |
280 | float aB = *(ptrA + 0); | 223 | startHeights[1], |
281 | float aG = *(ptrA + 1); | 224 | startHeights[3], |
282 | float aR = *(ptrA + 2); | 225 | pctX, pctY); |
283 | 226 | startHeight = Utils.Clamp(startHeight, 0f, 255f); | |
284 | float bB = *(ptrB + 0); | 227 | |
285 | float bG = *(ptrB + 1); | 228 | float heightRange = ImageUtils.Bilinear( |
286 | float bR = *(ptrB + 2); | 229 | heightRanges[0], |
287 | 230 | heightRanges[2], | |
288 | float layerDiff = layer - l0; | 231 | heightRanges[1], |
289 | 232 | heightRanges[3], | |
290 | // Interpolate between the two selected textures | 233 | pctX, pctY); |
291 | *(ptrO + 0) = (byte)Math.Floor(aB + layerDiff * (bB - aB)); | 234 | heightRange = Utils.Clamp(heightRange, 0f, 255f); |
292 | *(ptrO + 1) = (byte)Math.Floor(aG + layerDiff * (bG - aG)); | 235 | |
293 | *(ptrO + 2) = (byte)Math.Floor(aR + layerDiff * (bR - aR)); | 236 | // Generate two frequencies of perlin noise based on our global position |
237 | // The magic values were taken from http://opensimulator.org/wiki/Terrain_Splatting | ||
238 | Vector3 vec = new Vector3 | ||
239 | ( | ||
240 | ((float)regionPosition.X + x) * 0.20319f, | ||
241 | ((float)regionPosition.Y + y) * 0.20319f, | ||
242 | height * 0.25f | ||
243 | ); | ||
244 | |||
245 | float lowFreq = Perlin.noise2(vec.X * 0.222222f, vec.Y * 0.222222f) * 6.5f; | ||
246 | float highFreq = Perlin.turbulence2(vec.X, vec.Y, 2f) * 2.25f; | ||
247 | float noise = (lowFreq + highFreq) * 2f; | ||
248 | |||
249 | // Combine the current height, generated noise, start height, and height range parameters, then scale all of it | ||
250 | float layer = ((height + noise - startHeight) / heightRange) * 4f; | ||
251 | if (Single.IsNaN(layer)) layer = 0f; | ||
252 | layermap[y * 256 + x] = Utils.Clamp(layer, 0f, 3f); | ||
294 | } | 253 | } |
295 | } | 254 | } |
296 | 255 | ||
256 | #endregion Layer Map | ||
257 | |||
258 | #region Texture Compositing | ||
259 | |||
260 | output = new Bitmap(256, 256, PixelFormat.Format24bppRgb); | ||
261 | outputData = output.LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb); | ||
262 | |||
263 | unsafe | ||
264 | { | ||
265 | // Get handles to all of the texture data arrays | ||
266 | BitmapData[] datas = new BitmapData[] | ||
267 | { | ||
268 | detailTexture[0].LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, detailTexture[0].PixelFormat), | ||
269 | detailTexture[1].LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, detailTexture[1].PixelFormat), | ||
270 | detailTexture[2].LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, detailTexture[2].PixelFormat), | ||
271 | detailTexture[3].LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, detailTexture[3].PixelFormat) | ||
272 | }; | ||
273 | |||
274 | int[] comps = new int[] | ||
275 | { | ||
276 | (datas[0].PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3, | ||
277 | (datas[1].PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3, | ||
278 | (datas[2].PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3, | ||
279 | (datas[3].PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3 | ||
280 | }; | ||
281 | |||
282 | for (int y = 0; y < 256; y++) | ||
283 | { | ||
284 | for (int x = 0; x < 256; x++) | ||
285 | { | ||
286 | float layer = layermap[y * 256 + x]; | ||
287 | |||
288 | // Select two textures | ||
289 | int l0 = (int)Math.Floor(layer); | ||
290 | int l1 = Math.Min(l0 + 1, 3); | ||
291 | |||
292 | byte* ptrA = (byte*)datas[l0].Scan0 + y * datas[l0].Stride + x * comps[l0]; | ||
293 | byte* ptrB = (byte*)datas[l1].Scan0 + y * datas[l1].Stride + x * comps[l1]; | ||
294 | byte* ptrO = (byte*)outputData.Scan0 + y * outputData.Stride + x * 3; | ||
295 | |||
296 | float aB = *(ptrA + 0); | ||
297 | float aG = *(ptrA + 1); | ||
298 | float aR = *(ptrA + 2); | ||
299 | |||
300 | float bB = *(ptrB + 0); | ||
301 | float bG = *(ptrB + 1); | ||
302 | float bR = *(ptrB + 2); | ||
303 | |||
304 | float layerDiff = layer - l0; | ||
305 | |||
306 | // Interpolate between the two selected textures | ||
307 | *(ptrO + 0) = (byte)Math.Floor(aB + layerDiff * (bB - aB)); | ||
308 | *(ptrO + 1) = (byte)Math.Floor(aG + layerDiff * (bG - aG)); | ||
309 | *(ptrO + 2) = (byte)Math.Floor(aR + layerDiff * (bR - aR)); | ||
310 | } | ||
311 | } | ||
312 | |||
313 | for (int i = 0; i < 4; i++) | ||
314 | detailTexture[i].UnlockBits(datas[i]); | ||
315 | } | ||
316 | } | ||
317 | finally | ||
318 | { | ||
297 | for (int i = 0; i < 4; i++) | 319 | for (int i = 0; i < 4; i++) |
298 | detailTexture[i].UnlockBits(datas[i]); | 320 | if (detailTexture[i] != null) |
321 | detailTexture[i].Dispose(); | ||
299 | } | 322 | } |
300 | 323 | ||
301 | output.UnlockBits(outputData); | 324 | output.UnlockBits(outputData); |
diff --git a/OpenSim/Region/CoreModules/World/Warp3DMap/MapImageModule.cs b/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs index e6f2855..3c48d07 100644 --- a/OpenSim/Region/CoreModules/World/Warp3DMap/MapImageModule.cs +++ b/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs | |||
@@ -54,8 +54,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
54 | private static readonly UUID TEXTURE_METADATA_MAGIC = new UUID("802dc0e0-f080-4931-8b57-d1be8611c4f3"); | 54 | private static readonly UUID TEXTURE_METADATA_MAGIC = new UUID("802dc0e0-f080-4931-8b57-d1be8611c4f3"); |
55 | private static readonly Color4 WATER_COLOR = new Color4(29, 72, 96, 216); | 55 | private static readonly Color4 WATER_COLOR = new Color4(29, 72, 96, 216); |
56 | 56 | ||
57 | private static readonly ILog m_log = | 57 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
58 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
59 | 58 | ||
60 | private Scene m_scene; | 59 | private Scene m_scene; |
61 | private IRendering m_primMesher; | 60 | private IRendering m_primMesher; |
@@ -164,7 +163,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
164 | } | 163 | } |
165 | catch | 164 | catch |
166 | { | 165 | { |
167 | m_log.Warn("[MAPTILE]: Failed to load StartupConfig"); | 166 | m_log.Warn("[WARP 3D IMAGE MODULE]: Failed to load StartupConfig"); |
168 | } | 167 | } |
169 | 168 | ||
170 | m_colors.Clear(); | 169 | m_colors.Clear(); |
@@ -218,7 +217,10 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
218 | Bitmap bitmap = renderer.Scene.getImage(); | 217 | Bitmap bitmap = renderer.Scene.getImage(); |
219 | 218 | ||
220 | if (m_useAntiAliasing) | 219 | if (m_useAntiAliasing) |
221 | bitmap = ImageUtils.ResizeImage(bitmap, viewport.Width, viewport.Height); | 220 | { |
221 | using (Bitmap origBitmap = bitmap) | ||
222 | bitmap = ImageUtils.ResizeImage(origBitmap, viewport.Width, viewport.Height); | ||
223 | } | ||
222 | 224 | ||
223 | return bitmap; | 225 | return bitmap; |
224 | } | 226 | } |
@@ -233,7 +235,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
233 | catch (Exception e) | 235 | catch (Exception e) |
234 | { | 236 | { |
235 | // JPEG2000 encoder failed | 237 | // JPEG2000 encoder failed |
236 | m_log.Error("[MAPTILE]: Failed generating terrain map: " + e); | 238 | m_log.Error("[WARP 3D IMAGE MODULE]: Failed generating terrain map: ", e); |
237 | } | 239 | } |
238 | 240 | ||
239 | return null; | 241 | return null; |
@@ -332,8 +334,17 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
332 | uint globalX, globalY; | 334 | uint globalX, globalY; |
333 | Utils.LongToUInts(m_scene.RegionInfo.RegionHandle, out globalX, out globalY); | 335 | Utils.LongToUInts(m_scene.RegionInfo.RegionHandle, out globalX, out globalY); |
334 | 336 | ||
335 | Bitmap image = TerrainSplat.Splat(heightmap, textureIDs, startHeights, heightRanges, new Vector3d(globalX, globalY, 0.0), m_scene.AssetService, textureTerrain); | 337 | warp_Texture texture; |
336 | warp_Texture texture = new warp_Texture(image); | 338 | |
339 | using ( | ||
340 | Bitmap image | ||
341 | = TerrainSplat.Splat( | ||
342 | heightmap, textureIDs, startHeights, heightRanges, | ||
343 | new Vector3d(globalX, globalY, 0.0), m_scene.AssetService, textureTerrain)) | ||
344 | { | ||
345 | texture = new warp_Texture(image); | ||
346 | } | ||
347 | |||
337 | warp_Material material = new warp_Material(texture); | 348 | warp_Material material = new warp_Material(texture); |
338 | material.setReflectivity(50); | 349 | material.setReflectivity(50); |
339 | renderer.Scene.addMaterial("TerrainColor", material); | 350 | renderer.Scene.addMaterial("TerrainColor", material); |
@@ -560,42 +571,46 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
560 | { | 571 | { |
561 | try | 572 | try |
562 | { | 573 | { |
563 | Bitmap bitmap = (Bitmap)J2kImage.FromStream(stream); | 574 | int pixelBytes; |
564 | width = bitmap.Width; | ||
565 | height = bitmap.Height; | ||
566 | 575 | ||
567 | BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, bitmap.PixelFormat); | 576 | using (Bitmap bitmap = (Bitmap)J2kImage.FromStream(stream)) |
568 | int pixelBytes = (bitmap.PixelFormat == PixelFormat.Format24bppRgb) ? 3 : 4; | ||
569 | |||
570 | // Sum up the individual channels | ||
571 | unsafe | ||
572 | { | 577 | { |
573 | if (pixelBytes == 4) | 578 | width = bitmap.Width; |
579 | height = bitmap.Height; | ||
580 | |||
581 | BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, bitmap.PixelFormat); | ||
582 | pixelBytes = (bitmap.PixelFormat == PixelFormat.Format24bppRgb) ? 3 : 4; | ||
583 | |||
584 | // Sum up the individual channels | ||
585 | unsafe | ||
574 | { | 586 | { |
575 | for (int y = 0; y < height; y++) | 587 | if (pixelBytes == 4) |
576 | { | 588 | { |
577 | byte* row = (byte*)bitmapData.Scan0 + (y * bitmapData.Stride); | 589 | for (int y = 0; y < height; y++) |
578 | |||
579 | for (int x = 0; x < width; x++) | ||
580 | { | 590 | { |
581 | b += row[x * pixelBytes + 0]; | 591 | byte* row = (byte*)bitmapData.Scan0 + (y * bitmapData.Stride); |
582 | g += row[x * pixelBytes + 1]; | 592 | |
583 | r += row[x * pixelBytes + 2]; | 593 | for (int x = 0; x < width; x++) |
584 | a += row[x * pixelBytes + 3]; | 594 | { |
595 | b += row[x * pixelBytes + 0]; | ||
596 | g += row[x * pixelBytes + 1]; | ||
597 | r += row[x * pixelBytes + 2]; | ||
598 | a += row[x * pixelBytes + 3]; | ||
599 | } | ||
585 | } | 600 | } |
586 | } | 601 | } |
587 | } | 602 | else |
588 | else | ||
589 | { | ||
590 | for (int y = 0; y < height; y++) | ||
591 | { | 603 | { |
592 | byte* row = (byte*)bitmapData.Scan0 + (y * bitmapData.Stride); | 604 | for (int y = 0; y < height; y++) |
593 | |||
594 | for (int x = 0; x < width; x++) | ||
595 | { | 605 | { |
596 | b += row[x * pixelBytes + 0]; | 606 | byte* row = (byte*)bitmapData.Scan0 + (y * bitmapData.Stride); |
597 | g += row[x * pixelBytes + 1]; | 607 | |
598 | r += row[x * pixelBytes + 2]; | 608 | for (int x = 0; x < width; x++) |
609 | { | ||
610 | b += row[x * pixelBytes + 0]; | ||
611 | g += row[x * pixelBytes + 1]; | ||
612 | r += row[x * pixelBytes + 2]; | ||
613 | } | ||
599 | } | 614 | } |
600 | } | 615 | } |
601 | } | 616 | } |
@@ -617,7 +632,10 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap | |||
617 | } | 632 | } |
618 | catch (Exception ex) | 633 | catch (Exception ex) |
619 | { | 634 | { |
620 | m_log.WarnFormat("[MAPTILE]: Error decoding JPEG2000 texture {0} ({1} bytes): {2}", textureID, j2kData.Length, ex.Message); | 635 | m_log.WarnFormat( |
636 | "[WARP 3D IMAGE MODULE]: Error decoding JPEG2000 texture {0} ({1} bytes): {2}", | ||
637 | textureID, j2kData.Length, ex.Message); | ||
638 | |||
621 | width = 0; | 639 | width = 0; |
622 | height = 0; | 640 | height = 0; |
623 | return new Color4(0.5f, 0.5f, 0.5f, 1.0f); | 641 | return new Color4(0.5f, 0.5f, 0.5f, 1.0f); |
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index 1dedcce..309856f 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs | |||
@@ -193,14 +193,15 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
193 | { | 193 | { |
194 | //m_log.DebugFormat("[WORLD MAP]: OnRegisterCaps: agentID {0} caps {1}", agentID, caps); | 194 | //m_log.DebugFormat("[WORLD MAP]: OnRegisterCaps: agentID {0} caps {1}", agentID, caps); |
195 | string capsBase = "/CAPS/" + caps.CapsObjectPath; | 195 | string capsBase = "/CAPS/" + caps.CapsObjectPath; |
196 | caps.RegisterHandler("MapLayer", | 196 | caps.RegisterHandler( |
197 | new RestStreamHandler("POST", capsBase + m_mapLayerPath, | 197 | "MapLayer", |
198 | delegate(string request, string path, string param, | 198 | new RestStreamHandler( |
199 | IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) | 199 | "POST", |
200 | { | 200 | capsBase + m_mapLayerPath, |
201 | return MapLayerRequest(request, path, param, | 201 | (request, path, param, httpRequest, httpResponse) |
202 | agentID, caps); | 202 | => MapLayerRequest(request, path, param, agentID, caps), |
203 | })); | 203 | "MapLayer", |
204 | agentID.ToString())); | ||
204 | } | 205 | } |
205 | 206 | ||
206 | /// <summary> | 207 | /// <summary> |
@@ -675,7 +676,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
675 | { | 676 | { |
676 | if (Environment.TickCount > (m_blacklistedregions[regionhandle] + blacklistTimeout)) | 677 | if (Environment.TickCount > (m_blacklistedregions[regionhandle] + blacklistTimeout)) |
677 | { | 678 | { |
678 | m_log.DebugFormat("[WORLDMAP]: Unblock blacklisted region {0}", regionhandle); | 679 | m_log.DebugFormat("[WORLD MAP]: Unblock blacklisted region {0}", regionhandle); |
679 | 680 | ||
680 | m_blacklistedregions.Remove(regionhandle); | 681 | m_blacklistedregions.Remove(regionhandle); |
681 | } | 682 | } |
@@ -730,7 +731,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
730 | { | 731 | { |
731 | if (Environment.TickCount > (m_blacklistedurls[httpserver] + blacklistTimeout)) | 732 | if (Environment.TickCount > (m_blacklistedurls[httpserver] + blacklistTimeout)) |
732 | { | 733 | { |
733 | m_log.DebugFormat("[WORLDMAP]: Unblock blacklisted URL {0}", httpserver); | 734 | m_log.DebugFormat("[WORLD MAP]: Unblock blacklisted URL {0}", httpserver); |
734 | 735 | ||
735 | m_blacklistedurls.Remove(httpserver); | 736 | m_blacklistedurls.Remove(httpserver); |
736 | } | 737 | } |
@@ -1427,14 +1428,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
1427 | if (terrain == null) | 1428 | if (terrain == null) |
1428 | return; | 1429 | return; |
1429 | 1430 | ||
1431 | m_log.DebugFormat("[WORLD MAP]: Generating map image for {0}", m_scene.RegionInfo.RegionName); | ||
1432 | |||
1430 | byte[] data = terrain.WriteJpeg2000Image(); | 1433 | byte[] data = terrain.WriteJpeg2000Image(); |
1431 | if (data == null) | 1434 | if (data == null) |
1432 | return; | 1435 | return; |
1433 | 1436 | ||
1434 | byte[] overlay = GenerateOverlay(); | 1437 | byte[] overlay = GenerateOverlay(); |
1435 | 1438 | ||
1436 | m_log.Debug("[WORLDMAP]: STORING MAPTILE IMAGE"); | ||
1437 | |||
1438 | UUID terrainImageID = UUID.Random(); | 1439 | UUID terrainImageID = UUID.Random(); |
1439 | UUID parcelImageID = UUID.Zero; | 1440 | UUID parcelImageID = UUID.Zero; |
1440 | 1441 | ||
@@ -1449,7 +1450,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
1449 | asset.Flags = AssetFlags.Maptile; | 1450 | asset.Flags = AssetFlags.Maptile; |
1450 | 1451 | ||
1451 | // Store the new one | 1452 | // Store the new one |
1452 | m_log.DebugFormat("[WORLDMAP]: Storing map tile {0}", asset.ID); | 1453 | m_log.DebugFormat("[WORLD MAP]: Storing map tile {0} for {1}", asset.ID, m_scene.RegionInfo.RegionName); |
1454 | |||
1453 | m_scene.AssetService.Store(asset); | 1455 | m_scene.AssetService.Store(asset); |
1454 | 1456 | ||
1455 | if (overlay != null) | 1457 | if (overlay != null) |