diff options
author | Melanie Thielker | 2014-06-21 00:39:55 +0200 |
---|---|---|
committer | Melanie Thielker | 2014-06-21 00:39:55 +0200 |
commit | 159fcbf150b7da0e229b29aa7b94793484543d12 (patch) | |
tree | b8c0ff3b4c758a3fba8315b556c923ef4c02a185 /OpenSim/Region/CoreModules | |
parent | Merge commit '68c8633ba18f0a11cfc0ed04d1d0c7c59e6cec76' (diff) | |
parent | Merge branch 'master' into careminster (diff) | |
download | opensim-SC-159fcbf150b7da0e229b29aa7b94793484543d12.zip opensim-SC-159fcbf150b7da0e229b29aa7b94793484543d12.tar.gz opensim-SC-159fcbf150b7da0e229b29aa7b94793484543d12.tar.bz2 opensim-SC-159fcbf150b7da0e229b29aa7b94793484543d12.tar.xz |
Merge branch 'master' of ssh://3dhosting.de/var/git/careminster
Conflicts:
OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
Diffstat (limited to 'OpenSim/Region/CoreModules')
84 files changed, 6355 insertions, 1389 deletions
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs index da1ff2e..1e14f45 100644 --- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs +++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs | |||
@@ -33,6 +33,7 @@ using OpenSim.Framework; | |||
33 | 33 | ||
34 | using OpenSim.Region.Framework.Scenes; | 34 | using OpenSim.Region.Framework.Scenes; |
35 | using OpenSim.Services.Interfaces; | 35 | using OpenSim.Services.Interfaces; |
36 | using OpenSim.Region.Framework.Interfaces; | ||
36 | 37 | ||
37 | namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | 38 | namespace OpenSim.Region.CoreModules.Agent.AssetTransaction |
38 | { | 39 | { |
@@ -119,6 +120,14 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
119 | } | 120 | } |
120 | else | 121 | else |
121 | { | 122 | { |
123 | // Check if the xfer is a terrain xfer | ||
124 | IEstateModule estateModule = m_Scene.RequestModuleInterface<IEstateModule>(); | ||
125 | if (estateModule != null) | ||
126 | { | ||
127 | if (estateModule.IsTerrainXfer(xferID)) | ||
128 | return; | ||
129 | } | ||
130 | |||
122 | m_log.ErrorFormat( | 131 | m_log.ErrorFormat( |
123 | "[AGENT ASSET TRANSACTIONS]: Could not find uploader for xfer id {0}, packet id {1}, data length {2}", | 132 | "[AGENT ASSET TRANSACTIONS]: Could not find uploader for xfer id {0}, packet id {1}, data length {2}", |
124 | xferID, packetID, data.Length); | 133 | xferID, packetID, data.Length); |
diff --git a/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs b/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs index 3764685..d9b0eff 100644 --- a/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs +++ b/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs | |||
@@ -166,7 +166,7 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender | |||
166 | 166 | ||
167 | // Do Decode! | 167 | // Do Decode! |
168 | if (decode) | 168 | if (decode) |
169 | Decode(assetID, j2kData); | 169 | Util.FireAndForget(delegate { Decode(assetID, j2kData); }); |
170 | } | 170 | } |
171 | } | 171 | } |
172 | 172 | ||
diff --git a/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs b/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs index f43305f..9b0e1f4 100644 --- a/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/CenomeAssetCache.cs | |||
@@ -194,10 +194,12 @@ namespace OpenSim.Region.CoreModules.Asset | |||
194 | 194 | ||
195 | #region IImprovedAssetCache Members | 195 | #region IImprovedAssetCache Members |
196 | 196 | ||
197 | |||
198 | public bool Check(string id) | 197 | public bool Check(string id) |
199 | { | 198 | { |
200 | return false; | 199 | AssetBase asset; |
200 | |||
201 | // XXX:This is probably not an efficient implementation. | ||
202 | return m_cache.TryGetValue(id, out asset); | ||
201 | } | 203 | } |
202 | 204 | ||
203 | /// <summary> | 205 | /// <summary> |
diff --git a/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs b/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs index 58ce61a..f720748 100644 --- a/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/CoreAssetCache.cs | |||
@@ -114,7 +114,8 @@ namespace OpenSim.Region.CoreModules.Asset | |||
114 | // | 114 | // |
115 | public bool Check(string id) | 115 | public bool Check(string id) |
116 | { | 116 | { |
117 | return false; | 117 | // XXX This is probably not an efficient implementation. |
118 | return Get(id) != null; | ||
118 | } | 119 | } |
119 | 120 | ||
120 | public void Cache(AssetBase asset) | 121 | public void Cache(AssetBase asset) |
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs index d510d82..b270de9 100644 --- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs | |||
@@ -31,17 +31,16 @@ | |||
31 | using System; | 31 | using System; |
32 | using System.IO; | 32 | using System.IO; |
33 | using System.Collections.Generic; | 33 | using System.Collections.Generic; |
34 | using System.Linq; | ||
34 | using System.Reflection; | 35 | using System.Reflection; |
35 | using System.Runtime.Serialization; | 36 | using System.Runtime.Serialization; |
36 | using System.Runtime.Serialization.Formatters.Binary; | 37 | using System.Runtime.Serialization.Formatters.Binary; |
37 | using System.Threading; | 38 | using System.Threading; |
38 | using System.Timers; | 39 | using System.Timers; |
39 | |||
40 | using log4net; | 40 | using log4net; |
41 | using Nini.Config; | 41 | using Nini.Config; |
42 | using Mono.Addins; | 42 | using Mono.Addins; |
43 | using OpenMetaverse; | 43 | using OpenMetaverse; |
44 | |||
45 | using OpenSim.Framework; | 44 | using OpenSim.Framework; |
46 | using OpenSim.Framework.Console; | 45 | using OpenSim.Framework.Console; |
47 | using OpenSim.Region.Framework.Interfaces; | 46 | using OpenSim.Region.Framework.Interfaces; |
@@ -76,8 +75,6 @@ namespace OpenSim.Region.CoreModules.Asset | |||
76 | private static ulong m_RequestsForInprogress; | 75 | private static ulong m_RequestsForInprogress; |
77 | private static ulong m_DiskHits; | 76 | private static ulong m_DiskHits; |
78 | private static ulong m_MemoryHits; | 77 | private static ulong m_MemoryHits; |
79 | private static double m_HitRateMemory; | ||
80 | private static double m_HitRateFile; | ||
81 | 78 | ||
82 | #if WAIT_ON_INPROGRESS_REQUESTS | 79 | #if WAIT_ON_INPROGRESS_REQUESTS |
83 | private Dictionary<string, ManualResetEvent> m_CurrentlyWriting = new Dictionary<string, ManualResetEvent>(); | 80 | private Dictionary<string, ManualResetEvent> m_CurrentlyWriting = new Dictionary<string, ManualResetEvent>(); |
@@ -251,71 +248,68 @@ namespace OpenSim.Region.CoreModules.Asset | |||
251 | 248 | ||
252 | private void UpdateFileCache(string key, AssetBase asset) | 249 | private void UpdateFileCache(string key, AssetBase asset) |
253 | { | 250 | { |
254 | // TODO: Spawn this off to some seperate thread to do the actual writing | 251 | string filename = GetFileName(key); |
255 | if (asset != null) | ||
256 | { | ||
257 | string filename = GetFileName(key); | ||
258 | 252 | ||
259 | try | 253 | try |
254 | { | ||
255 | // If the file is already cached, don't cache it, just touch it so access time is updated | ||
256 | if (File.Exists(filename)) | ||
260 | { | 257 | { |
261 | // If the file is already cached, don't cache it, just touch it so access time is updated | 258 | // We don't really want to know about sharing |
262 | if (File.Exists(filename)) | 259 | // violations here. If the file is locked, then |
260 | // the other thread has updated the time for us. | ||
261 | try | ||
263 | { | 262 | { |
264 | // We don't really want to know about sharing | 263 | lock (m_CurrentlyWriting) |
265 | // violations here. If the file is locked, then | ||
266 | // the other thread has updated the time for us. | ||
267 | try | ||
268 | { | 264 | { |
269 | lock (m_CurrentlyWriting) | 265 | if (!m_CurrentlyWriting.Contains(filename)) |
270 | { | 266 | File.SetLastAccessTime(filename, DateTime.Now); |
271 | if (!m_CurrentlyWriting.Contains(filename)) | ||
272 | File.SetLastAccessTime(filename, DateTime.Now); | ||
273 | } | ||
274 | } | 267 | } |
275 | catch | 268 | } |
269 | catch | ||
270 | { | ||
271 | } | ||
272 | } | ||
273 | else | ||
274 | { | ||
275 | // Once we start writing, make sure we flag that we're writing | ||
276 | // that object to the cache so that we don't try to write the | ||
277 | // same file multiple times. | ||
278 | lock (m_CurrentlyWriting) | ||
279 | { | ||
280 | #if WAIT_ON_INPROGRESS_REQUESTS | ||
281 | if (m_CurrentlyWriting.ContainsKey(filename)) | ||
276 | { | 282 | { |
283 | return; | ||
277 | } | 284 | } |
278 | } else { | 285 | else |
279 | |||
280 | // Once we start writing, make sure we flag that we're writing | ||
281 | // that object to the cache so that we don't try to write the | ||
282 | // same file multiple times. | ||
283 | lock (m_CurrentlyWriting) | ||
284 | { | 286 | { |
285 | #if WAIT_ON_INPROGRESS_REQUESTS | 287 | m_CurrentlyWriting.Add(filename, new ManualResetEvent(false)); |
286 | if (m_CurrentlyWriting.ContainsKey(filename)) | 288 | } |
287 | { | ||
288 | return; | ||
289 | } | ||
290 | else | ||
291 | { | ||
292 | m_CurrentlyWriting.Add(filename, new ManualResetEvent(false)); | ||
293 | } | ||
294 | 289 | ||
295 | #else | 290 | #else |
296 | if (m_CurrentlyWriting.Contains(filename)) | 291 | if (m_CurrentlyWriting.Contains(filename)) |
297 | { | 292 | { |
298 | return; | 293 | return; |
299 | } | ||
300 | else | ||
301 | { | ||
302 | m_CurrentlyWriting.Add(filename); | ||
303 | } | ||
304 | #endif | ||
305 | |||
306 | } | 294 | } |
295 | else | ||
296 | { | ||
297 | m_CurrentlyWriting.Add(filename); | ||
298 | } | ||
299 | #endif | ||
307 | 300 | ||
308 | Util.FireAndForget( | ||
309 | delegate { WriteFileCache(filename, asset); }); | ||
310 | } | 301 | } |
311 | } | 302 | |
312 | catch (Exception e) | 303 | Util.FireAndForget( |
313 | { | 304 | delegate { WriteFileCache(filename, asset); }); |
314 | m_log.ErrorFormat( | ||
315 | "[FLOTSAM ASSET CACHE]: Failed to update cache for asset {0}. Exception {1} {2}", | ||
316 | asset.ID, e.Message, e.StackTrace); | ||
317 | } | 305 | } |
318 | } | 306 | } |
307 | catch (Exception e) | ||
308 | { | ||
309 | m_log.ErrorFormat( | ||
310 | "[FLOTSAM ASSET CACHE]: Failed to update cache for asset {0}. Exception {1} {2}", | ||
311 | asset.ID, e.Message, e.StackTrace); | ||
312 | } | ||
319 | } | 313 | } |
320 | 314 | ||
321 | public void Cache(AssetBase asset) | 315 | public void Cache(AssetBase asset) |
@@ -350,15 +344,9 @@ namespace OpenSim.Region.CoreModules.Asset | |||
350 | 344 | ||
351 | private bool CheckFromMemoryCache(string id) | 345 | private bool CheckFromMemoryCache(string id) |
352 | { | 346 | { |
353 | AssetBase asset = null; | 347 | return m_MemoryCache.Contains(id); |
354 | |||
355 | if (m_MemoryCache.TryGetValue(id, out asset)) | ||
356 | return true; | ||
357 | |||
358 | return false; | ||
359 | } | 348 | } |
360 | 349 | ||
361 | |||
362 | /// <summary> | 350 | /// <summary> |
363 | /// Try to get an asset from the file cache. | 351 | /// Try to get an asset from the file cache. |
364 | /// </summary> | 352 | /// </summary> |
@@ -396,15 +384,16 @@ namespace OpenSim.Region.CoreModules.Asset | |||
396 | 384 | ||
397 | if (File.Exists(filename)) | 385 | if (File.Exists(filename)) |
398 | { | 386 | { |
399 | FileStream stream = null; | ||
400 | try | 387 | try |
401 | { | 388 | { |
402 | stream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read); | 389 | using (FileStream stream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read)) |
403 | BinaryFormatter bformatter = new BinaryFormatter(); | 390 | { |
391 | BinaryFormatter bformatter = new BinaryFormatter(); | ||
404 | 392 | ||
405 | asset = (AssetBase)bformatter.Deserialize(stream); | 393 | asset = (AssetBase)bformatter.Deserialize(stream); |
406 | 394 | ||
407 | m_DiskHits++; | 395 | m_DiskHits++; |
396 | } | ||
408 | } | 397 | } |
409 | catch (System.Runtime.Serialization.SerializationException e) | 398 | catch (System.Runtime.Serialization.SerializationException e) |
410 | { | 399 | { |
@@ -423,12 +412,6 @@ namespace OpenSim.Region.CoreModules.Asset | |||
423 | m_log.WarnFormat( | 412 | m_log.WarnFormat( |
424 | "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}", | 413 | "[FLOTSAM ASSET CACHE]: Failed to get file {0} for asset {1}. Exception {2} {3}", |
425 | filename, id, e.Message, e.StackTrace); | 414 | filename, id, e.Message, e.StackTrace); |
426 | |||
427 | } | ||
428 | finally | ||
429 | { | ||
430 | if (stream != null) | ||
431 | stream.Close(); | ||
432 | } | 415 | } |
433 | } | 416 | } |
434 | 417 | ||
@@ -440,36 +423,19 @@ namespace OpenSim.Region.CoreModules.Asset | |||
440 | bool found = false; | 423 | bool found = false; |
441 | 424 | ||
442 | string filename = GetFileName(id); | 425 | string filename = GetFileName(id); |
426 | |||
443 | if (File.Exists(filename)) | 427 | if (File.Exists(filename)) |
444 | { | 428 | { |
445 | // actually check if we can open it, and so update expire | ||
446 | FileStream stream = null; | ||
447 | try | 429 | try |
448 | { | 430 | { |
449 | stream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read); | 431 | using (FileStream stream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read)) |
450 | if (stream != null) | ||
451 | { | 432 | { |
452 | found = true; | 433 | if (stream != null) |
453 | stream.Close(); | 434 | found = true; |
454 | } | 435 | } |
455 | |||
456 | } | ||
457 | catch (System.Runtime.Serialization.SerializationException e) | ||
458 | { | ||
459 | found = false; | ||
460 | m_log.ErrorFormat( | ||
461 | "[FLOTSAM ASSET CACHE]: Failed to check file {0} for asset {1}. Exception {2} {3}", | ||
462 | filename, id, e.Message, e.StackTrace); | ||
463 | |||
464 | // If there was a problem deserializing the asset, the asset may | ||
465 | // either be corrupted OR was serialized under an old format | ||
466 | // {different version of AssetBase} -- we should attempt to | ||
467 | // delete it and re-cache | ||
468 | File.Delete(filename); | ||
469 | } | 436 | } |
470 | catch (Exception e) | 437 | catch (Exception e) |
471 | { | 438 | { |
472 | found = false; | ||
473 | m_log.ErrorFormat( | 439 | m_log.ErrorFormat( |
474 | "[FLOTSAM ASSET CACHE]: Failed to check file {0} for asset {1}. Exception {2} {3}", | 440 | "[FLOTSAM ASSET CACHE]: Failed to check file {0} for asset {1}. Exception {2} {3}", |
475 | filename, id, e.Message, e.StackTrace); | 441 | filename, id, e.Message, e.StackTrace); |
@@ -498,18 +464,9 @@ namespace OpenSim.Region.CoreModules.Asset | |||
498 | 464 | ||
499 | if (((m_LogLevel >= 1)) && (m_HitRateDisplay != 0) && (m_Requests % m_HitRateDisplay == 0)) | 465 | if (((m_LogLevel >= 1)) && (m_HitRateDisplay != 0) && (m_Requests % m_HitRateDisplay == 0)) |
500 | { | 466 | { |
501 | m_HitRateFile = (double)m_DiskHits / m_Requests * 100.0; | ||
502 | |||
503 | m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Cache Get :: {0} :: {1}", id, asset == null ? "Miss" : "Hit"); | 467 | m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Cache Get :: {0} :: {1}", id, asset == null ? "Miss" : "Hit"); |
504 | m_log.InfoFormat("[FLOTSAM ASSET CACHE]: File Hit Rate {0}% for {1} requests", m_HitRateFile.ToString("0.00"), m_Requests); | ||
505 | 468 | ||
506 | if (m_MemoryCacheEnabled) | 469 | GenerateCacheHitReport().ForEach(l => m_log.InfoFormat("[FLOTSAM ASSET CACHE]: {0}", l)); |
507 | { | ||
508 | m_HitRateMemory = (double)m_MemoryHits / m_Requests * 100.0; | ||
509 | m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Memory Hit Rate {0}% for {1} requests", m_HitRateMemory.ToString("0.00"), m_Requests); | ||
510 | } | ||
511 | |||
512 | m_log.InfoFormat("[FLOTSAM ASSET CACHE]: {0} unnessesary requests due to requests for assets that are currently downloading.", m_RequestsForInprogress); | ||
513 | } | 470 | } |
514 | 471 | ||
515 | return asset; | 472 | return asset; |
@@ -530,11 +487,6 @@ namespace OpenSim.Region.CoreModules.Asset | |||
530 | return Get(id); | 487 | return Get(id); |
531 | } | 488 | } |
532 | 489 | ||
533 | public AssetBase CheckCached(string id) | ||
534 | { | ||
535 | return Get(id); | ||
536 | } | ||
537 | |||
538 | public void Expire(string id) | 490 | public void Expire(string id) |
539 | { | 491 | { |
540 | if (m_LogLevel >= 2) | 492 | if (m_LogLevel >= 2) |
@@ -819,7 +771,7 @@ namespace OpenSim.Region.CoreModules.Asset | |||
819 | UuidGatherer gatherer = new UuidGatherer(m_AssetService); | 771 | UuidGatherer gatherer = new UuidGatherer(m_AssetService); |
820 | 772 | ||
821 | HashSet<UUID> uniqueUuids = new HashSet<UUID>(); | 773 | HashSet<UUID> uniqueUuids = new HashSet<UUID>(); |
822 | Dictionary<UUID, AssetType> assets = new Dictionary<UUID, AssetType>(); | 774 | Dictionary<UUID, sbyte> assets = new Dictionary<UUID, sbyte>(); |
823 | 775 | ||
824 | foreach (Scene s in m_Scenes) | 776 | foreach (Scene s in m_Scenes) |
825 | { | 777 | { |
@@ -842,7 +794,7 @@ namespace OpenSim.Region.CoreModules.Asset | |||
842 | else if (storeUncached) | 794 | else if (storeUncached) |
843 | { | 795 | { |
844 | AssetBase cachedAsset = m_AssetService.Get(assetID.ToString()); | 796 | AssetBase cachedAsset = m_AssetService.Get(assetID.ToString()); |
845 | if (cachedAsset == null && assets[assetID] != AssetType.Unknown) | 797 | if (cachedAsset == null && assets[assetID] != (sbyte)AssetType.Unknown) |
846 | m_log.DebugFormat( | 798 | m_log.DebugFormat( |
847 | "[FLOTSAM ASSET CACHE]: Could not find asset {0}, type {1} referenced by object {2} at {3} in scene {4} when pre-caching all scene assets", | 799 | "[FLOTSAM ASSET CACHE]: Could not find asset {0}, type {1} referenced by object {2} at {3} in scene {4} when pre-caching all scene assets", |
848 | assetID, assets[assetID], e.Name, e.AbsolutePosition, s.Name); | 800 | assetID, assets[assetID], e.Name, e.AbsolutePosition, s.Name); |
@@ -891,45 +843,77 @@ namespace OpenSim.Region.CoreModules.Asset | |||
891 | } | 843 | } |
892 | } | 844 | } |
893 | 845 | ||
846 | private List<string> GenerateCacheHitReport() | ||
847 | { | ||
848 | List<string> outputLines = new List<string>(); | ||
849 | |||
850 | double fileHitRate = (double)m_DiskHits / m_Requests * 100.0; | ||
851 | outputLines.Add( | ||
852 | string.Format("File Hit Rate: {0}% for {1} requests", fileHitRate.ToString("0.00"), m_Requests)); | ||
853 | |||
854 | if (m_MemoryCacheEnabled) | ||
855 | { | ||
856 | double memHitRate = (double)m_MemoryHits / m_Requests * 100.0; | ||
857 | |||
858 | outputLines.Add( | ||
859 | string.Format("Memory Hit Rate: {0}% for {1} requests", memHitRate.ToString("0.00"), m_Requests)); | ||
860 | } | ||
861 | |||
862 | outputLines.Add( | ||
863 | string.Format( | ||
864 | "Unnecessary requests due to requests for assets that are currently downloading: {0}", | ||
865 | m_RequestsForInprogress)); | ||
866 | |||
867 | return outputLines; | ||
868 | } | ||
869 | |||
894 | #region Console Commands | 870 | #region Console Commands |
895 | private void HandleConsoleCommand(string module, string[] cmdparams) | 871 | private void HandleConsoleCommand(string module, string[] cmdparams) |
896 | { | 872 | { |
873 | ICommandConsole con = MainConsole.Instance; | ||
874 | |||
897 | if (cmdparams.Length >= 2) | 875 | if (cmdparams.Length >= 2) |
898 | { | 876 | { |
899 | string cmd = cmdparams[1]; | 877 | string cmd = cmdparams[1]; |
878 | |||
900 | switch (cmd) | 879 | switch (cmd) |
901 | { | 880 | { |
902 | case "status": | 881 | case "status": |
903 | if (m_MemoryCacheEnabled) | 882 | if (m_MemoryCacheEnabled) |
904 | m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Memory Cache : {0} assets", m_MemoryCache.Count); | 883 | con.OutputFormat("Memory Cache: {0} assets", m_MemoryCache.Count); |
905 | else | 884 | else |
906 | m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Memory cache disabled"); | 885 | con.OutputFormat("Memory cache disabled"); |
907 | 886 | ||
908 | if (m_FileCacheEnabled) | 887 | if (m_FileCacheEnabled) |
909 | { | 888 | { |
910 | int fileCount = GetFileCacheCount(m_CacheDirectory); | 889 | int fileCount = GetFileCacheCount(m_CacheDirectory); |
911 | m_log.InfoFormat("[FLOTSAM ASSET CACHE]: File Cache : {0} assets", fileCount); | 890 | con.OutputFormat("File Cache: {0} assets", fileCount); |
891 | } | ||
892 | else | ||
893 | { | ||
894 | con.Output("File cache disabled"); | ||
895 | } | ||
896 | |||
897 | GenerateCacheHitReport().ForEach(l => con.Output(l)); | ||
898 | |||
899 | if (m_FileCacheEnabled) | ||
900 | { | ||
901 | con.Output("Deep scans have previously been performed on the following regions:"); | ||
912 | 902 | ||
913 | foreach (string s in Directory.GetFiles(m_CacheDirectory, "*.fac")) | 903 | foreach (string s in Directory.GetFiles(m_CacheDirectory, "*.fac")) |
914 | { | 904 | { |
915 | m_log.Info("[FLOTSAM ASSET CACHE]: Deep scans have previously been performed on the following regions:"); | ||
916 | |||
917 | string RegionID = s.Remove(0,s.IndexOf("_")).Replace(".fac",""); | 905 | string RegionID = s.Remove(0,s.IndexOf("_")).Replace(".fac",""); |
918 | DateTime RegionDeepScanTMStamp = File.GetLastWriteTime(s); | 906 | DateTime RegionDeepScanTMStamp = File.GetLastWriteTime(s); |
919 | m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Region: {0}, {1}", RegionID, RegionDeepScanTMStamp.ToString("MM/dd/yyyy hh:mm:ss")); | 907 | con.OutputFormat("Region: {0}, {1}", RegionID, RegionDeepScanTMStamp.ToString("MM/dd/yyyy hh:mm:ss")); |
920 | } | 908 | } |
921 | } | 909 | } |
922 | else | ||
923 | { | ||
924 | m_log.InfoFormat("[FLOTSAM ASSET CACHE]: File cache disabled"); | ||
925 | } | ||
926 | 910 | ||
927 | break; | 911 | break; |
928 | 912 | ||
929 | case "clear": | 913 | case "clear": |
930 | if (cmdparams.Length < 2) | 914 | if (cmdparams.Length < 2) |
931 | { | 915 | { |
932 | m_log.Warn("[FLOTSAM ASSET CACHE]: Usage is fcache clear [file] [memory]"); | 916 | con.Output("Usage is fcache clear [file] [memory]"); |
933 | break; | 917 | break; |
934 | } | 918 | } |
935 | 919 | ||
@@ -953,11 +937,11 @@ namespace OpenSim.Region.CoreModules.Asset | |||
953 | if (m_MemoryCacheEnabled) | 937 | if (m_MemoryCacheEnabled) |
954 | { | 938 | { |
955 | m_MemoryCache.Clear(); | 939 | m_MemoryCache.Clear(); |
956 | m_log.Info("[FLOTSAM ASSET CACHE]: Memory cache cleared."); | 940 | con.Output("Memory cache cleared."); |
957 | } | 941 | } |
958 | else | 942 | else |
959 | { | 943 | { |
960 | m_log.Info("[FLOTSAM ASSET CACHE]: Memory cache not enabled."); | 944 | con.Output("Memory cache not enabled."); |
961 | } | 945 | } |
962 | } | 946 | } |
963 | 947 | ||
@@ -966,24 +950,22 @@ namespace OpenSim.Region.CoreModules.Asset | |||
966 | if (m_FileCacheEnabled) | 950 | if (m_FileCacheEnabled) |
967 | { | 951 | { |
968 | ClearFileCache(); | 952 | ClearFileCache(); |
969 | m_log.Info("[FLOTSAM ASSET CACHE]: File cache cleared."); | 953 | con.Output("File cache cleared."); |
970 | } | 954 | } |
971 | else | 955 | else |
972 | { | 956 | { |
973 | m_log.Info("[FLOTSAM ASSET CACHE]: File cache not enabled."); | 957 | con.Output("File cache not enabled."); |
974 | } | 958 | } |
975 | } | 959 | } |
976 | 960 | ||
977 | break; | 961 | break; |
978 | 962 | ||
979 | case "assets": | 963 | case "assets": |
980 | m_log.Info("[FLOTSAM ASSET CACHE]: Ensuring assets are cached for all scenes."); | 964 | con.Output("Ensuring assets are cached for all scenes."); |
981 | 965 | ||
982 | Util.FireAndForget(delegate { | 966 | Util.FireAndForget(delegate { |
983 | int assetReferenceTotal = TouchAllSceneAssets(true); | 967 | int assetReferenceTotal = TouchAllSceneAssets(true); |
984 | m_log.InfoFormat( | 968 | con.OutputFormat("Completed check with {0} assets.", assetReferenceTotal); |
985 | "[FLOTSAM ASSET CACHE]: Completed check with {0} assets.", | ||
986 | assetReferenceTotal); | ||
987 | }); | 969 | }); |
988 | 970 | ||
989 | break; | 971 | break; |
@@ -991,7 +973,7 @@ namespace OpenSim.Region.CoreModules.Asset | |||
991 | case "expire": | 973 | case "expire": |
992 | if (cmdparams.Length < 3) | 974 | if (cmdparams.Length < 3) |
993 | { | 975 | { |
994 | m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Invalid parameters for Expire, please specify a valid date & time", cmd); | 976 | con.OutputFormat("Invalid parameters for Expire, please specify a valid date & time", cmd); |
995 | break; | 977 | break; |
996 | } | 978 | } |
997 | 979 | ||
@@ -1009,28 +991,27 @@ namespace OpenSim.Region.CoreModules.Asset | |||
1009 | 991 | ||
1010 | if (!DateTime.TryParse(s_expirationDate, out expirationDate)) | 992 | if (!DateTime.TryParse(s_expirationDate, out expirationDate)) |
1011 | { | 993 | { |
1012 | m_log.InfoFormat("[FLOTSAM ASSET CACHE]: {0} is not a valid date & time", cmd); | 994 | con.OutputFormat("{0} is not a valid date & time", cmd); |
1013 | break; | 995 | break; |
1014 | } | 996 | } |
1015 | 997 | ||
1016 | if (m_FileCacheEnabled) | 998 | if (m_FileCacheEnabled) |
1017 | CleanExpiredFiles(m_CacheDirectory, expirationDate); | 999 | CleanExpiredFiles(m_CacheDirectory, expirationDate); |
1018 | else | 1000 | else |
1019 | m_log.InfoFormat("[FLOTSAM ASSET CACHE]: File cache not active, not clearing."); | 1001 | con.OutputFormat("File cache not active, not clearing."); |
1020 | 1002 | ||
1021 | break; | 1003 | break; |
1022 | default: | 1004 | default: |
1023 | m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Unknown command {0}", cmd); | 1005 | con.OutputFormat("Unknown command {0}", cmd); |
1024 | break; | 1006 | break; |
1025 | } | 1007 | } |
1026 | } | 1008 | } |
1027 | else if (cmdparams.Length == 1) | 1009 | else if (cmdparams.Length == 1) |
1028 | { | 1010 | { |
1029 | m_log.InfoFormat("[FLOTSAM ASSET CACHE]: fcache status - Display cache status"); | 1011 | con.Output("fcache assets - Attempt a deep cache of all assets in all scenes"); |
1030 | m_log.InfoFormat("[FLOTSAM ASSET CACHE]: fcache clearmem - Remove all assets cached in memory"); | 1012 | con.Output("fcache expire <datetime> - Purge assets older then the specified date & time"); |
1031 | m_log.InfoFormat("[FLOTSAM ASSET CACHE]: fcache clearfile - Remove all assets cached on disk"); | 1013 | con.Output("fcache clear [file] [memory] - Remove cached assets"); |
1032 | m_log.InfoFormat("[FLOTSAM ASSET CACHE]: fcache cachescenes - Attempt a deep cache of all assets in all scenes"); | 1014 | con.Output("fcache status - Display cache status"); |
1033 | m_log.InfoFormat("[FLOTSAM ASSET CACHE]: fcache <datetime> - Purge assets older then the specified date & time"); | ||
1034 | } | 1015 | } |
1035 | } | 1016 | } |
1036 | 1017 | ||
@@ -1050,11 +1031,6 @@ namespace OpenSim.Region.CoreModules.Asset | |||
1050 | return asset.Data; | 1031 | return asset.Data; |
1051 | } | 1032 | } |
1052 | 1033 | ||
1053 | public bool CheckData(string id) | ||
1054 | { | ||
1055 | return Check(id); ; | ||
1056 | } | ||
1057 | |||
1058 | public bool Get(string id, object sender, AssetRetrieved handler) | 1034 | public bool Get(string id, object sender, AssetRetrieved handler) |
1059 | { | 1035 | { |
1060 | AssetBase asset = Get(id); | 1036 | AssetBase asset = Get(id); |
diff --git a/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs b/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs index ce9b546..5f76ac2 100644 --- a/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/GlynnTuckerAssetCache.cs | |||
@@ -117,7 +117,7 @@ namespace OpenSim.Region.CoreModules.Asset | |||
117 | 117 | ||
118 | public bool Check(string id) | 118 | public bool Check(string id) |
119 | { | 119 | { |
120 | return false; | 120 | return m_Cache.Contains(id); |
121 | } | 121 | } |
122 | 122 | ||
123 | public void Cache(AssetBase asset) | 123 | public void Cache(AssetBase asset) |
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 6495f3f..d47ca4b 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | |||
@@ -29,6 +29,7 @@ using System; | |||
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Reflection; | 30 | using System.Reflection; |
31 | using System.IO; | 31 | using System.IO; |
32 | using System.Threading; | ||
32 | using System.Xml; | 33 | using System.Xml; |
33 | using log4net; | 34 | using log4net; |
34 | using Mono.Addins; | 35 | using Mono.Addins; |
@@ -51,6 +52,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
51 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 52 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
52 | 53 | ||
53 | public int DebugLevel { get; set; } | 54 | public int DebugLevel { get; set; } |
55 | |||
56 | /// <summary> | ||
57 | /// Period to sleep per 100 prims in order to avoid CPU spikes when an avatar with many attachments logs in/changes | ||
58 | /// outfit or many avatars with a medium levels of attachments login/change outfit simultaneously. | ||
59 | /// </summary> | ||
60 | /// <remarks> | ||
61 | /// A value of 0 will apply no pause. The pause is specified in milliseconds. | ||
62 | /// </remarks> | ||
63 | public int ThrottlePer100PrimsRezzed { get; set; } | ||
54 | 64 | ||
55 | private Scene m_scene; | 65 | private Scene m_scene; |
56 | private IInventoryAccessModule m_invAccessModule; | 66 | private IInventoryAccessModule m_invAccessModule; |
@@ -67,18 +77,26 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
67 | { | 77 | { |
68 | IConfig config = source.Configs["Attachments"]; | 78 | IConfig config = source.Configs["Attachments"]; |
69 | if (config != null) | 79 | if (config != null) |
80 | { | ||
70 | Enabled = config.GetBoolean("Enabled", true); | 81 | Enabled = config.GetBoolean("Enabled", true); |
82 | |||
83 | ThrottlePer100PrimsRezzed = config.GetInt("ThrottlePer100PrimsRezzed", 0); | ||
84 | } | ||
71 | else | 85 | else |
86 | { | ||
72 | Enabled = true; | 87 | Enabled = true; |
88 | } | ||
73 | } | 89 | } |
74 | 90 | ||
75 | public void AddRegion(Scene scene) | 91 | public void AddRegion(Scene scene) |
76 | { | 92 | { |
77 | m_scene = scene; | 93 | m_scene = scene; |
78 | m_scene.RegisterModuleInterface<IAttachmentsModule>(this); | ||
79 | |||
80 | if (Enabled) | 94 | if (Enabled) |
81 | { | 95 | { |
96 | // Only register module with scene if it is enabled. All callers check for a null attachments module. | ||
97 | // Ideally, there should be a null attachments module for when this core attachments module has been | ||
98 | // disabled. Registering only when enabled allows for other attachments module implementations. | ||
99 | m_scene.RegisterModuleInterface<IAttachmentsModule>(this); | ||
82 | m_scene.EventManager.OnNewClient += SubscribeToClientEvents; | 100 | m_scene.EventManager.OnNewClient += SubscribeToClientEvents; |
83 | m_scene.EventManager.OnStartScript += (localID, itemID) => HandleScriptStateChange(localID, true); | 101 | m_scene.EventManager.OnStartScript += (localID, itemID) => HandleScriptStateChange(localID, true); |
84 | m_scene.EventManager.OnStopScript += (localID, itemID) => HandleScriptStateChange(localID, false); | 102 | m_scene.EventManager.OnStopScript += (localID, itemID) => HandleScriptStateChange(localID, false); |
@@ -86,24 +104,43 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
86 | MainConsole.Instance.Commands.AddCommand( | 104 | MainConsole.Instance.Commands.AddCommand( |
87 | "Debug", | 105 | "Debug", |
88 | false, | 106 | false, |
89 | "debug attachments", | 107 | "debug attachments log", |
90 | "debug attachments [0|1]", | 108 | "debug attachments log [0|1]", |
91 | "Turn on attachments debugging\n" | 109 | "Turn on attachments debug logging", |
92 | + " <= 0 - turns off debugging\n" | 110 | " <= 0 - turns off debug logging\n" |
93 | + " >= 1 - turns on attachment message logging\n", | 111 | + " >= 1 - turns on attachment message debug logging", |
94 | HandleDebugAttachments); | 112 | HandleDebugAttachmentsLog); |
113 | |||
114 | MainConsole.Instance.Commands.AddCommand( | ||
115 | "Debug", | ||
116 | false, | ||
117 | "debug attachments throttle", | ||
118 | "debug attachments throttle <ms>", | ||
119 | "Turn on attachments throttling.", | ||
120 | "This requires a millisecond value. " + | ||
121 | " == 0 - disable throttling.\n" | ||
122 | + " > 0 - sleeps for this number of milliseconds per 100 prims rezzed.", | ||
123 | HandleDebugAttachmentsThrottle); | ||
124 | |||
125 | MainConsole.Instance.Commands.AddCommand( | ||
126 | "Debug", | ||
127 | false, | ||
128 | "debug attachments status", | ||
129 | "debug attachments status", | ||
130 | "Show current attachments debug status", | ||
131 | HandleDebugAttachmentsStatus); | ||
95 | } | 132 | } |
96 | 133 | ||
97 | // TODO: Should probably be subscribing to CloseClient too, but this doesn't yet give us IClientAPI | 134 | // TODO: Should probably be subscribing to CloseClient too, but this doesn't yet give us IClientAPI |
98 | } | 135 | } |
99 | 136 | ||
100 | private void HandleDebugAttachments(string module, string[] args) | 137 | private void HandleDebugAttachmentsLog(string module, string[] args) |
101 | { | 138 | { |
102 | int debugLevel; | 139 | int debugLevel; |
103 | 140 | ||
104 | if (!(args.Length == 3 && int.TryParse(args[2], out debugLevel))) | 141 | if (!(args.Length == 4 && int.TryParse(args[3], out debugLevel))) |
105 | { | 142 | { |
106 | MainConsole.Instance.OutputFormat("Usage: debug attachments [0|1]"); | 143 | MainConsole.Instance.OutputFormat("Usage: debug attachments log [0|1]"); |
107 | } | 144 | } |
108 | else | 145 | else |
109 | { | 146 | { |
@@ -113,6 +150,29 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
113 | } | 150 | } |
114 | } | 151 | } |
115 | 152 | ||
153 | private void HandleDebugAttachmentsThrottle(string module, string[] args) | ||
154 | { | ||
155 | int ms; | ||
156 | |||
157 | if (args.Length == 4 && int.TryParse(args[3], out ms)) | ||
158 | { | ||
159 | ThrottlePer100PrimsRezzed = ms; | ||
160 | MainConsole.Instance.OutputFormat( | ||
161 | "Attachments rez throttle per 100 prims is now {0} in {1}", ThrottlePer100PrimsRezzed, m_scene.Name); | ||
162 | |||
163 | return; | ||
164 | } | ||
165 | |||
166 | MainConsole.Instance.OutputFormat("Usage: debug attachments throttle <ms>"); | ||
167 | } | ||
168 | |||
169 | private void HandleDebugAttachmentsStatus(string module, string[] args) | ||
170 | { | ||
171 | MainConsole.Instance.OutputFormat("Settings for {0}", m_scene.Name); | ||
172 | MainConsole.Instance.OutputFormat("Debug logging level: {0}", DebugLevel); | ||
173 | MainConsole.Instance.OutputFormat("Throttle per 100 prims: {0}ms", ThrottlePer100PrimsRezzed); | ||
174 | } | ||
175 | |||
116 | /// <summary> | 176 | /// <summary> |
117 | /// Listen for client triggered running state changes so that we can persist the script's object if necessary. | 177 | /// Listen for client triggered running state changes so that we can persist the script's object if necessary. |
118 | /// </summary> | 178 | /// </summary> |
@@ -273,7 +333,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
273 | List<AvatarAttachment> attachments = sp.Appearance.GetAttachments(); | 333 | List<AvatarAttachment> attachments = sp.Appearance.GetAttachments(); |
274 | foreach (AvatarAttachment attach in attachments) | 334 | foreach (AvatarAttachment attach in attachments) |
275 | { | 335 | { |
276 | uint p = (uint)attach.AttachPoint; | 336 | uint attachmentPt = (uint)attach.AttachPoint; |
277 | 337 | ||
278 | // m_log.DebugFormat( | 338 | // m_log.DebugFormat( |
279 | // "[ATTACHMENTS MODULE]: Doing initial rez of attachment with itemID {0}, assetID {1}, point {2} for {3} in {4}", | 339 | // "[ATTACHMENTS MODULE]: Doing initial rez of attachment with itemID {0}, assetID {1}, point {2} for {3} in {4}", |
@@ -302,13 +362,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
302 | // If we're an NPC then skip all the item checks and manipulations since we don't have an | 362 | // If we're an NPC then skip all the item checks and manipulations since we don't have an |
303 | // inventory right now. | 363 | // inventory right now. |
304 | RezSingleAttachmentFromInventoryInternal( | 364 | RezSingleAttachmentFromInventoryInternal( |
305 | sp, sp.PresenceType == PresenceType.Npc ? UUID.Zero : attach.ItemID, attach.AssetID, p, true, d); | 365 | sp, sp.PresenceType == PresenceType.Npc ? UUID.Zero : attach.ItemID, attach.AssetID, attachmentPt, true, d); |
306 | } | 366 | } |
307 | catch (Exception e) | 367 | catch (Exception e) |
308 | { | 368 | { |
309 | UUID agentId = (sp.ControllingClient == null) ? (UUID)null : sp.ControllingClient.AgentId; | 369 | UUID agentId = (sp.ControllingClient == null) ? default(UUID) : sp.ControllingClient.AgentId; |
310 | m_log.ErrorFormat("[ATTACHMENTS MODULE]: Unable to rez attachment with itemID {0}, assetID {1}, point {2} for {3}: {4}\n{5}", | 370 | m_log.ErrorFormat("[ATTACHMENTS MODULE]: Unable to rez attachment with itemID {0}, assetID {1}, point {2} for {3}: {4}\n{5}", |
311 | attach.ItemID, attach.AssetID, p, agentId, e.Message, e.StackTrace); | 371 | attach.ItemID, attach.AssetID, attachmentPt, agentId, e.Message, e.StackTrace); |
312 | } | 372 | } |
313 | } | 373 | } |
314 | } | 374 | } |
@@ -422,13 +482,28 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
422 | attachPos = Vector3.Zero; | 482 | attachPos = Vector3.Zero; |
423 | } | 483 | } |
424 | 484 | ||
425 | // AttachmentPt 0 (default) means the client chose to 'wear' the attachment. | 485 | // if the attachment point is the same as previous, make sure we get the saved |
486 | // position info. | ||
487 | if (attachmentPt != 0 && attachmentPt == group.RootPart.Shape.LastAttachPoint) | ||
488 | { | ||
489 | attachPos = group.RootPart.AttachedPos; | ||
490 | } | ||
491 | |||
492 | // AttachmentPt 0 means the client chose to 'wear' the attachment. | ||
426 | if (attachmentPt == (uint)AttachmentPoint.Default) | 493 | if (attachmentPt == (uint)AttachmentPoint.Default) |
427 | { | 494 | { |
428 | // Check object for stored attachment point | 495 | // Check object for stored attachment point |
429 | attachmentPt = group.AttachmentPoint; | 496 | attachmentPt = group.AttachmentPoint; |
430 | } | 497 | } |
431 | 498 | ||
499 | // if we didn't find an attach point, look for where it was last attached | ||
500 | if (attachmentPt == 0) | ||
501 | { | ||
502 | attachmentPt = (uint)group.RootPart.Shape.LastAttachPoint; | ||
503 | attachPos = group.RootPart.AttachedPos; | ||
504 | group.HasGroupChanged = true; | ||
505 | } | ||
506 | |||
432 | // if we still didn't find a suitable attachment point....... | 507 | // if we still didn't find a suitable attachment point....... |
433 | if (attachmentPt == 0) | 508 | if (attachmentPt == 0) |
434 | { | 509 | { |
@@ -610,6 +685,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
610 | if (changed && m_scene.AvatarFactory != null) | 685 | if (changed && m_scene.AvatarFactory != null) |
611 | m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); | 686 | m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); |
612 | 687 | ||
688 | so.RootPart.Shape.LastAttachPoint = (byte)so.AttachmentPoint; | ||
689 | |||
613 | sp.RemoveAttachment(so); | 690 | sp.RemoveAttachment(so); |
614 | so.FromItemID = UUID.Zero; | 691 | so.FromItemID = UUID.Zero; |
615 | 692 | ||
@@ -841,7 +918,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
841 | m_scene.ForEachClient( | 918 | m_scene.ForEachClient( |
842 | client => | 919 | client => |
843 | { if (client.AgentId != so.AttachedAvatar) | 920 | { if (client.AgentId != so.AttachedAvatar) |
844 | client.SendKillObject(m_scene.RegionInfo.RegionHandle, new List<uint>() { so.LocalId }); | 921 | client.SendKillObject(new List<uint>() { so.LocalId }); |
845 | }); | 922 | }); |
846 | } | 923 | } |
847 | 924 | ||
@@ -982,8 +1059,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
982 | 1059 | ||
983 | if (DebugLevel > 0) | 1060 | if (DebugLevel > 0) |
984 | m_log.DebugFormat( | 1061 | m_log.DebugFormat( |
985 | "[ATTACHMENTS MODULE]: Rezzed single object {0} for attachment to {1} on point {2} in {3}", | 1062 | "[ATTACHMENTS MODULE]: Rezzed single object {0} with {1} prims for attachment to {2} on point {3} in {4}", |
986 | objatt.Name, sp.Name, attachmentPt, m_scene.Name); | 1063 | objatt.Name, objatt.PrimCount, sp.Name, attachmentPt, m_scene.Name); |
987 | 1064 | ||
988 | // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller. | 1065 | // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller. |
989 | objatt.HasGroupChanged = false; | 1066 | objatt.HasGroupChanged = false; |
@@ -1020,7 +1097,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
1020 | } | 1097 | } |
1021 | 1098 | ||
1022 | if (tainted) | 1099 | if (tainted) |
1023 | objatt.HasGroupChanged = true; | 1100 | objatt.HasGroupChanged = true; |
1101 | |||
1102 | if (ThrottlePer100PrimsRezzed > 0) | ||
1103 | { | ||
1104 | int throttleMs = (int)Math.Round((float)objatt.PrimCount / 100 * ThrottlePer100PrimsRezzed); | ||
1105 | |||
1106 | if (DebugLevel > 0) | ||
1107 | m_log.DebugFormat( | ||
1108 | "[ATTACHMENTS MODULE]: Throttling by {0}ms after rez of {1} with {2} prims for attachment to {3} on point {4} in {5}", | ||
1109 | throttleMs, objatt.Name, objatt.PrimCount, sp.Name, attachmentPt, m_scene.Name); | ||
1110 | |||
1111 | Thread.Sleep(throttleMs); | ||
1112 | } | ||
1024 | 1113 | ||
1025 | return objatt; | 1114 | return objatt; |
1026 | } | 1115 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 1a38619..f023e77 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs | |||
@@ -38,6 +38,8 @@ using NUnit.Framework; | |||
38 | using OpenMetaverse; | 38 | using OpenMetaverse; |
39 | using OpenSim.Framework; | 39 | using OpenSim.Framework; |
40 | using OpenSim.Framework.Communications; | 40 | using OpenSim.Framework.Communications; |
41 | using OpenSim.Framework.Servers; | ||
42 | using OpenSim.Framework.Servers.HttpServer; | ||
41 | using OpenSim.Region.CoreModules.Avatar.Attachments; | 43 | using OpenSim.Region.CoreModules.Avatar.Attachments; |
42 | using OpenSim.Region.CoreModules.Framework; | 44 | using OpenSim.Region.CoreModules.Framework; |
43 | using OpenSim.Region.CoreModules.Framework.EntityTransfer; | 45 | using OpenSim.Region.CoreModules.Framework.EntityTransfer; |
@@ -717,7 +719,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
717 | SceneObjectGroup rezzedAtt = presence.GetAttachments()[0]; | 719 | SceneObjectGroup rezzedAtt = presence.GetAttachments()[0]; |
718 | 720 | ||
719 | m_numberOfAttachEventsFired = 0; | 721 | m_numberOfAttachEventsFired = 0; |
720 | scene.IncomingCloseAgent(presence.UUID, false); | 722 | scene.CloseAgent(presence.UUID, false); |
721 | 723 | ||
722 | // Check that we can't retrieve this attachment from the scene. | 724 | // Check that we can't retrieve this attachment from the scene. |
723 | Assert.That(scene.GetSceneObjectGroup(rezzedAtt.UUID), Is.Null); | 725 | Assert.That(scene.GetSceneObjectGroup(rezzedAtt.UUID), Is.Null); |
@@ -797,11 +799,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
797 | } | 799 | } |
798 | 800 | ||
799 | [Test] | 801 | [Test] |
800 | public void TestSameSimulatorNeighbouringRegionsTeleport() | 802 | public void TestSameSimulatorNeighbouringRegionsTeleportV1() |
801 | { | 803 | { |
802 | TestHelpers.InMethod(); | 804 | TestHelpers.InMethod(); |
803 | // TestHelpers.EnableLogging(); | 805 | // TestHelpers.EnableLogging(); |
804 | 806 | ||
807 | BaseHttpServer httpServer = new BaseHttpServer(99999); | ||
808 | MainServer.AddHttpServer(httpServer); | ||
809 | MainServer.Instance = httpServer; | ||
810 | |||
805 | AttachmentsModule attModA = new AttachmentsModule(); | 811 | AttachmentsModule attModA = new AttachmentsModule(); |
806 | AttachmentsModule attModB = new AttachmentsModule(); | 812 | AttachmentsModule attModB = new AttachmentsModule(); |
807 | EntityTransferModule etmA = new EntityTransferModule(); | 813 | EntityTransferModule etmA = new EntityTransferModule(); |
@@ -830,14 +836,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
830 | SceneHelpers.SetupSceneModules( | 836 | SceneHelpers.SetupSceneModules( |
831 | sceneB, config, new CapabilitiesModule(), etmB, attModB, new BasicInventoryAccessModule()); | 837 | sceneB, config, new CapabilitiesModule(), etmB, attModB, new BasicInventoryAccessModule()); |
832 | 838 | ||
839 | // FIXME: Hack - this is here temporarily to revert back to older entity transfer behaviour | ||
840 | lscm.ServiceVersion = "SIMULATION/0.1"; | ||
841 | |||
833 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(sceneA, 0x1); | 842 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(sceneA, 0x1); |
834 | 843 | ||
835 | AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID); | 844 | AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID); |
836 | TestClient tc = new TestClient(acd, sceneA, sh.SceneManager); | 845 | TestClient tc = new TestClient(acd, sceneA); |
837 | List<TestClient> destinationTestClients = new List<TestClient>(); | 846 | List<TestClient> destinationTestClients = new List<TestClient>(); |
838 | EntityTransferHelpers.SetUpInformClientOfNeighbour(tc, destinationTestClients); | 847 | EntityTransferHelpers.SetupInformClientOfNeighbourTriggersNeighbourClientCreate(tc, destinationTestClients); |
839 | 848 | ||
840 | ScenePresence beforeTeleportSp = SceneHelpers.AddScenePresence(sceneA, tc, acd, sh.SceneManager); | 849 | ScenePresence beforeTeleportSp = SceneHelpers.AddScenePresence(sceneA, tc, acd); |
841 | beforeTeleportSp.AbsolutePosition = new Vector3(30, 31, 32); | 850 | beforeTeleportSp.AbsolutePosition = new Vector3(30, 31, 32); |
842 | 851 | ||
843 | InventoryItemBase attItem = CreateAttachmentItem(sceneA, ua1.PrincipalID, "att", 0x10, 0x20); | 852 | InventoryItemBase attItem = CreateAttachmentItem(sceneA, ua1.PrincipalID, "att", 0x10, 0x20); |
@@ -895,5 +904,115 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
895 | // Check events | 904 | // Check events |
896 | Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(0)); | 905 | Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(0)); |
897 | } | 906 | } |
907 | |||
908 | [Test] | ||
909 | public void TestSameSimulatorNeighbouringRegionsTeleportV2() | ||
910 | { | ||
911 | TestHelpers.InMethod(); | ||
912 | // TestHelpers.EnableLogging(); | ||
913 | |||
914 | BaseHttpServer httpServer = new BaseHttpServer(99999); | ||
915 | MainServer.AddHttpServer(httpServer); | ||
916 | MainServer.Instance = httpServer; | ||
917 | |||
918 | AttachmentsModule attModA = new AttachmentsModule(); | ||
919 | AttachmentsModule attModB = new AttachmentsModule(); | ||
920 | EntityTransferModule etmA = new EntityTransferModule(); | ||
921 | EntityTransferModule etmB = new EntityTransferModule(); | ||
922 | LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule(); | ||
923 | |||
924 | IConfigSource config = new IniConfigSource(); | ||
925 | IConfig modulesConfig = config.AddConfig("Modules"); | ||
926 | modulesConfig.Set("EntityTransferModule", etmA.Name); | ||
927 | modulesConfig.Set("SimulationServices", lscm.Name); | ||
928 | |||
929 | modulesConfig.Set("InventoryAccessModule", "BasicInventoryAccessModule"); | ||
930 | |||
931 | SceneHelpers sh = new SceneHelpers(); | ||
932 | TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000); | ||
933 | TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1001, 1000); | ||
934 | |||
935 | SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm); | ||
936 | SceneHelpers.SetupSceneModules( | ||
937 | sceneA, config, new CapabilitiesModule(), etmA, attModA, new BasicInventoryAccessModule()); | ||
938 | SceneHelpers.SetupSceneModules( | ||
939 | sceneB, config, new CapabilitiesModule(), etmB, attModB, new BasicInventoryAccessModule()); | ||
940 | |||
941 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(sceneA, 0x1); | ||
942 | |||
943 | AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID); | ||
944 | TestClient tc = new TestClient(acd, sceneA); | ||
945 | List<TestClient> destinationTestClients = new List<TestClient>(); | ||
946 | EntityTransferHelpers.SetupInformClientOfNeighbourTriggersNeighbourClientCreate(tc, destinationTestClients); | ||
947 | |||
948 | ScenePresence beforeTeleportSp = SceneHelpers.AddScenePresence(sceneA, tc, acd); | ||
949 | beforeTeleportSp.AbsolutePosition = new Vector3(30, 31, 32); | ||
950 | |||
951 | Assert.That(destinationTestClients.Count, Is.EqualTo(1)); | ||
952 | Assert.That(destinationTestClients[0], Is.Not.Null); | ||
953 | |||
954 | InventoryItemBase attItem = CreateAttachmentItem(sceneA, ua1.PrincipalID, "att", 0x10, 0x20); | ||
955 | |||
956 | sceneA.AttachmentsModule.RezSingleAttachmentFromInventory( | ||
957 | beforeTeleportSp, attItem.ID, (uint)AttachmentPoint.Chest); | ||
958 | |||
959 | Vector3 teleportPosition = new Vector3(10, 11, 12); | ||
960 | Vector3 teleportLookAt = new Vector3(20, 21, 22); | ||
961 | |||
962 | // Here, we need to make clientA's receipt of SendRegionTeleport trigger clientB's CompleteMovement(). This | ||
963 | // is to operate the teleport V2 mechanism where the EntityTransferModule will first request the client to | ||
964 | // CompleteMovement to the region and then call UpdateAgent to the destination region to confirm the receipt | ||
965 | // Both these operations will occur on different threads and will wait for each other. | ||
966 | // We have to do this via ThreadPool directly since FireAndForget has been switched to sync for the V1 | ||
967 | // test protocol, where we are trying to avoid unpredictable async operations in regression tests. | ||
968 | tc.OnTestClientSendRegionTeleport | ||
969 | += (regionHandle, simAccess, regionExternalEndPoint, locationID, flags, capsURL) | ||
970 | => ThreadPool.UnsafeQueueUserWorkItem(o => destinationTestClients[0].CompleteMovement(), null); | ||
971 | |||
972 | m_numberOfAttachEventsFired = 0; | ||
973 | sceneA.RequestTeleportLocation( | ||
974 | beforeTeleportSp.ControllingClient, | ||
975 | sceneB.RegionInfo.RegionHandle, | ||
976 | teleportPosition, | ||
977 | teleportLookAt, | ||
978 | (uint)TeleportFlags.ViaLocation); | ||
979 | |||
980 | // Check attachments have made it into sceneB | ||
981 | ScenePresence afterTeleportSceneBSp = sceneB.GetScenePresence(ua1.PrincipalID); | ||
982 | |||
983 | // This is appearance data, as opposed to actually rezzed attachments | ||
984 | List<AvatarAttachment> sceneBAttachments = afterTeleportSceneBSp.Appearance.GetAttachments(); | ||
985 | Assert.That(sceneBAttachments.Count, Is.EqualTo(1)); | ||
986 | Assert.That(sceneBAttachments[0].AttachPoint, Is.EqualTo((int)AttachmentPoint.Chest)); | ||
987 | Assert.That(sceneBAttachments[0].ItemID, Is.EqualTo(attItem.ID)); | ||
988 | Assert.That(sceneBAttachments[0].AssetID, Is.EqualTo(attItem.AssetID)); | ||
989 | Assert.That(afterTeleportSceneBSp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); | ||
990 | |||
991 | // This is the actual attachment | ||
992 | List<SceneObjectGroup> actualSceneBAttachments = afterTeleportSceneBSp.GetAttachments(); | ||
993 | Assert.That(actualSceneBAttachments.Count, Is.EqualTo(1)); | ||
994 | SceneObjectGroup actualSceneBAtt = actualSceneBAttachments[0]; | ||
995 | Assert.That(actualSceneBAtt.Name, Is.EqualTo(attItem.Name)); | ||
996 | Assert.That(actualSceneBAtt.AttachmentPoint, Is.EqualTo((uint)AttachmentPoint.Chest)); | ||
997 | |||
998 | Assert.That(sceneB.GetSceneObjectGroups().Count, Is.EqualTo(1)); | ||
999 | |||
1000 | // Check attachments have been removed from sceneA | ||
1001 | ScenePresence afterTeleportSceneASp = sceneA.GetScenePresence(ua1.PrincipalID); | ||
1002 | |||
1003 | // Since this is appearance data, it is still present on the child avatar! | ||
1004 | List<AvatarAttachment> sceneAAttachments = afterTeleportSceneASp.Appearance.GetAttachments(); | ||
1005 | Assert.That(sceneAAttachments.Count, Is.EqualTo(1)); | ||
1006 | Assert.That(afterTeleportSceneASp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); | ||
1007 | |||
1008 | // This is the actual attachment, which should no longer exist | ||
1009 | List<SceneObjectGroup> actualSceneAAttachments = afterTeleportSceneASp.GetAttachments(); | ||
1010 | Assert.That(actualSceneAAttachments.Count, Is.EqualTo(0)); | ||
1011 | |||
1012 | Assert.That(sceneA.GetSceneObjectGroups().Count, Is.EqualTo(0)); | ||
1013 | |||
1014 | // Check events | ||
1015 | Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(0)); | ||
1016 | } | ||
898 | } | 1017 | } |
899 | } | 1018 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index bc79944..09cc998 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | |||
@@ -55,6 +55,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
55 | 55 | ||
56 | private int m_savetime = 5; // seconds to wait before saving changed appearance | 56 | private int m_savetime = 5; // seconds to wait before saving changed appearance |
57 | private int m_sendtime = 2; // seconds to wait before sending changed appearance | 57 | private int m_sendtime = 2; // seconds to wait before sending changed appearance |
58 | private bool m_reusetextures = false; | ||
58 | 59 | ||
59 | private int m_checkTime = 500; // milliseconds to wait between checks for appearance updates | 60 | private int m_checkTime = 500; // milliseconds to wait between checks for appearance updates |
60 | private System.Timers.Timer m_updateTimer = new System.Timers.Timer(); | 61 | private System.Timers.Timer m_updateTimer = new System.Timers.Timer(); |
@@ -73,6 +74,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
73 | { | 74 | { |
74 | m_savetime = Convert.ToInt32(appearanceConfig.GetString("DelayBeforeAppearanceSave",Convert.ToString(m_savetime))); | 75 | m_savetime = Convert.ToInt32(appearanceConfig.GetString("DelayBeforeAppearanceSave",Convert.ToString(m_savetime))); |
75 | m_sendtime = Convert.ToInt32(appearanceConfig.GetString("DelayBeforeAppearanceSend",Convert.ToString(m_sendtime))); | 76 | m_sendtime = Convert.ToInt32(appearanceConfig.GetString("DelayBeforeAppearanceSend",Convert.ToString(m_sendtime))); |
77 | m_reusetextures = appearanceConfig.GetBoolean("ReuseTextures",m_reusetextures); | ||
78 | |||
76 | // m_log.InfoFormat("[AVFACTORY] configured for {0} save and {1} send",m_savetime,m_sendtime); | 79 | // m_log.InfoFormat("[AVFACTORY] configured for {0} save and {1} send",m_savetime,m_sendtime); |
77 | } | 80 | } |
78 | 81 | ||
@@ -131,6 +134,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
131 | client.OnRequestWearables += Client_OnRequestWearables; | 134 | client.OnRequestWearables += Client_OnRequestWearables; |
132 | client.OnSetAppearance += Client_OnSetAppearance; | 135 | client.OnSetAppearance += Client_OnSetAppearance; |
133 | client.OnAvatarNowWearing += Client_OnAvatarNowWearing; | 136 | client.OnAvatarNowWearing += Client_OnAvatarNowWearing; |
137 | client.OnCachedTextureRequest += Client_OnCachedTextureRequest; | ||
134 | } | 138 | } |
135 | 139 | ||
136 | #endregion | 140 | #endregion |
@@ -1068,6 +1072,61 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
1068 | QueueAppearanceSave(client.AgentId); | 1072 | QueueAppearanceSave(client.AgentId); |
1069 | } | 1073 | } |
1070 | } | 1074 | } |
1075 | |||
1076 | /// <summary> | ||
1077 | /// Respond to the cached textures request from the client | ||
1078 | /// </summary> | ||
1079 | /// <param name="client"></param> | ||
1080 | /// <param name="serial"></param> | ||
1081 | /// <param name="cachedTextureRequest"></param> | ||
1082 | private void Client_OnCachedTextureRequest(IClientAPI client, int serial, List<CachedTextureRequestArg> cachedTextureRequest) | ||
1083 | { | ||
1084 | // m_log.WarnFormat("[AVFACTORY]: Client_OnCachedTextureRequest called for {0} ({1})", client.Name, client.AgentId); | ||
1085 | ScenePresence sp = m_scene.GetScenePresence(client.AgentId); | ||
1086 | |||
1087 | List<CachedTextureResponseArg> cachedTextureResponse = new List<CachedTextureResponseArg>(); | ||
1088 | foreach (CachedTextureRequestArg request in cachedTextureRequest) | ||
1089 | { | ||
1090 | UUID texture = UUID.Zero; | ||
1091 | int index = request.BakedTextureIndex; | ||
1092 | |||
1093 | if (m_reusetextures) | ||
1094 | { | ||
1095 | // this is the most insanely dumb way to do this... however it seems to | ||
1096 | // actually work. if the appearance has been reset because wearables have | ||
1097 | // changed then the texture entries are zero'd out until the bakes are | ||
1098 | // uploaded. on login, if the textures exist in the cache (eg if you logged | ||
1099 | // into the simulator recently, then the appearance will pull those and send | ||
1100 | // them back in the packet and you won't have to rebake. if the textures aren't | ||
1101 | // in the cache then the intial makeroot() call in scenepresence will zero | ||
1102 | // them out. | ||
1103 | // | ||
1104 | // a better solution (though how much better is an open question) is to | ||
1105 | // store the hashes in the appearance and compare them. Thats's coming. | ||
1106 | |||
1107 | Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[index]; | ||
1108 | if (face != null) | ||
1109 | texture = face.TextureID; | ||
1110 | |||
1111 | // m_log.WarnFormat("[AVFACTORY]: reuse texture {0} for index {1}",texture,index); | ||
1112 | } | ||
1113 | |||
1114 | CachedTextureResponseArg response = new CachedTextureResponseArg(); | ||
1115 | response.BakedTextureIndex = index; | ||
1116 | response.BakedTextureID = texture; | ||
1117 | response.HostName = null; | ||
1118 | |||
1119 | cachedTextureResponse.Add(response); | ||
1120 | } | ||
1121 | |||
1122 | // m_log.WarnFormat("[AVFACTORY]: serial is {0}",serial); | ||
1123 | // The serial number appears to be used to match requests and responses | ||
1124 | // in the texture transaction. We just send back the serial number | ||
1125 | // that was provided in the request. The viewer bumps this for us. | ||
1126 | client.SendCachedTextureResponse(sp, serial, cachedTextureResponse); | ||
1127 | } | ||
1128 | |||
1129 | |||
1071 | #endregion | 1130 | #endregion |
1072 | 1131 | ||
1073 | public void WriteBakedTexturesReport(IScenePresence sp, ReportOutputAction outputAction) | 1132 | public void WriteBakedTexturesReport(IScenePresence sp, ReportOutputAction outputAction) |
diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs index 174642d..5cbfec6 100644 --- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs | |||
@@ -32,6 +32,7 @@ using log4net; | |||
32 | using Nini.Config; | 32 | using Nini.Config; |
33 | using Mono.Addins; | 33 | using Mono.Addins; |
34 | using OpenMetaverse; | 34 | using OpenMetaverse; |
35 | using OpenMetaverse.StructuredData; | ||
35 | using OpenSim.Framework; | 36 | using OpenSim.Framework; |
36 | using OpenSim.Region.Framework.Interfaces; | 37 | using OpenSim.Region.Framework.Interfaces; |
37 | using OpenSim.Region.Framework.Scenes; | 38 | using OpenSim.Region.Framework.Scenes; |
@@ -103,6 +104,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat | |||
103 | 104 | ||
104 | public virtual void RegionLoaded(Scene scene) | 105 | public virtual void RegionLoaded(Scene scene) |
105 | { | 106 | { |
107 | if (!m_enabled) | ||
108 | return; | ||
109 | |||
110 | ISimulatorFeaturesModule featuresModule = scene.RequestModuleInterface<ISimulatorFeaturesModule>(); | ||
111 | |||
112 | if (featuresModule != null) | ||
113 | featuresModule.OnSimulatorFeaturesRequest += OnSimulatorFeaturesRequest; | ||
114 | |||
106 | } | 115 | } |
107 | 116 | ||
108 | public virtual void RemoveRegion(Scene scene) | 117 | public virtual void RemoveRegion(Scene scene) |
@@ -372,21 +381,24 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat | |||
372 | UUID fromAgentID, UUID ownerID, string fromName, ChatTypeEnum type, | 381 | UUID fromAgentID, UUID ownerID, string fromName, ChatTypeEnum type, |
373 | string message, ChatSourceType src, bool ignoreDistance) | 382 | string message, ChatSourceType src, bool ignoreDistance) |
374 | { | 383 | { |
375 | // don't send chat to child agents | 384 | if (presence.LifecycleState != ScenePresenceState.Running) |
376 | if (presence.IsChildAgent) return false; | 385 | return false; |
377 | |||
378 | Vector3 fromRegionPos = fromPos + regionPos; | ||
379 | Vector3 toRegionPos = presence.AbsolutePosition + | ||
380 | new Vector3(presence.Scene.RegionInfo.RegionLocX * Constants.RegionSize, | ||
381 | presence.Scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); | ||
382 | 386 | ||
383 | int dis = (int)Util.GetDistanceTo(toRegionPos, fromRegionPos); | 387 | if (!ignoreDistance) |
384 | |||
385 | if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance || | ||
386 | type == ChatTypeEnum.Say && dis > m_saydistance || | ||
387 | type == ChatTypeEnum.Shout && dis > m_shoutdistance) | ||
388 | { | 388 | { |
389 | return false; | 389 | Vector3 fromRegionPos = fromPos + regionPos; |
390 | Vector3 toRegionPos = presence.AbsolutePosition + | ||
391 | new Vector3(presence.Scene.RegionInfo.RegionLocX * Constants.RegionSize, | ||
392 | presence.Scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); | ||
393 | |||
394 | int dis = (int)Util.GetDistanceTo(toRegionPos, fromRegionPos); | ||
395 | |||
396 | if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance || | ||
397 | type == ChatTypeEnum.Say && dis > m_saydistance || | ||
398 | type == ChatTypeEnum.Shout && dis > m_shoutdistance) | ||
399 | { | ||
400 | return false; | ||
401 | } | ||
390 | } | 402 | } |
391 | 403 | ||
392 | // TODO: should change so the message is sent through the avatar rather than direct to the ClientView | 404 | // TODO: should change so the message is sent through the avatar rather than direct to the ClientView |
@@ -426,5 +438,32 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat | |||
426 | Timers.Remove(target); | 438 | Timers.Remove(target); |
427 | Timer.Dispose(); | 439 | Timer.Dispose(); |
428 | } | 440 | } |
441 | #region SimulatorFeaturesRequest | ||
442 | |||
443 | static OSDInteger m_SayRange, m_WhisperRange, m_ShoutRange; | ||
444 | |||
445 | private void OnSimulatorFeaturesRequest(UUID agentID, ref OSDMap features) | ||
446 | { | ||
447 | OSD extras = new OSDMap(); | ||
448 | if (features.ContainsKey("OpenSimExtras")) | ||
449 | extras = features["OpenSimExtras"]; | ||
450 | else | ||
451 | features["OpenSimExtras"] = extras; | ||
452 | |||
453 | if (m_SayRange == null) | ||
454 | { | ||
455 | // Do this only once | ||
456 | m_SayRange = new OSDInteger(m_saydistance); | ||
457 | m_WhisperRange = new OSDInteger(m_whisperdistance); | ||
458 | m_ShoutRange = new OSDInteger(m_shoutdistance); | ||
459 | } | ||
460 | |||
461 | ((OSDMap)extras)["say-range"] = m_SayRange; | ||
462 | ((OSDMap)extras)["whisper-range"] = m_WhisperRange; | ||
463 | ((OSDMap)extras)["shout-range"] = m_ShoutRange; | ||
464 | |||
465 | } | ||
466 | |||
467 | #endregion | ||
429 | } | 468 | } |
430 | } | 469 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index 8056030..b693f2d 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs | |||
@@ -371,7 +371,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
371 | foreach (string fid in outstanding) | 371 | foreach (string fid in outstanding) |
372 | { | 372 | { |
373 | UUID fromAgentID; | 373 | UUID fromAgentID; |
374 | string firstname = "Unknown", lastname = "User"; | 374 | string firstname = "Unknown", lastname = "UserFMSFOIN"; |
375 | if (!GetAgentInfo(client.Scene.RegionInfo.ScopeID, fid, out fromAgentID, out firstname, out lastname)) | 375 | if (!GetAgentInfo(client.Scene.RegionInfo.ScopeID, fid, out fromAgentID, out firstname, out lastname)) |
376 | { | 376 | { |
377 | m_log.DebugFormat("[FRIENDS MODULE]: skipping malformed friend {0}", fid); | 377 | m_log.DebugFormat("[FRIENDS MODULE]: skipping malformed friend {0}", fid); |
@@ -397,7 +397,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
397 | 397 | ||
398 | protected virtual bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last) | 398 | protected virtual bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last) |
399 | { | 399 | { |
400 | first = "Unknown"; last = "User"; | 400 | first = "Unknown"; last = "UserFMGAI"; |
401 | if (!UUID.TryParse(fid, out agentID)) | 401 | if (!UUID.TryParse(fid, out agentID)) |
402 | return false; | 402 | return false; |
403 | 403 | ||
@@ -498,6 +498,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
498 | 498 | ||
499 | protected virtual void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online) | 499 | protected virtual void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online) |
500 | { | 500 | { |
501 | //m_log.DebugFormat("[FRIENDS]: Entering StatusNotify for {0}", userID); | ||
502 | |||
501 | List<string> friendStringIds = friendList.ConvertAll<string>(friend => friend.Friend); | 503 | List<string> friendStringIds = friendList.ConvertAll<string>(friend => friend.Friend); |
502 | List<string> remoteFriendStringIds = new List<string>(); | 504 | List<string> remoteFriendStringIds = new List<string>(); |
503 | foreach (string friendStringId in friendStringIds) | 505 | foreach (string friendStringId in friendStringIds) |
@@ -523,12 +525,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
523 | foreach (PresenceInfo friendSession in friendSessions) | 525 | foreach (PresenceInfo friendSession in friendSessions) |
524 | { | 526 | { |
525 | // let's guard against sessions-gone-bad | 527 | // let's guard against sessions-gone-bad |
526 | if (friendSession.RegionID != UUID.Zero) | 528 | if (friendSession != null && friendSession.RegionID != UUID.Zero) |
527 | { | 529 | { |
530 | //m_log.DebugFormat("[FRIENDS]: Get region {0}", friendSession.RegionID); | ||
528 | GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); | 531 | GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); |
529 | //m_log.DebugFormat("[FRIENDS]: Remote Notify to region {0}", region.RegionName); | 532 | if (region != null) |
530 | m_FriendsSimConnector.StatusNotify(region, userID, friendSession.UserID, online); | 533 | { |
534 | m_FriendsSimConnector.StatusNotify(region, userID, friendSession.UserID, online); | ||
535 | } | ||
531 | } | 536 | } |
537 | //else | ||
538 | // m_log.DebugFormat("[FRIENDS]: friend session is null or the region is UUID.Zero"); | ||
532 | } | 539 | } |
533 | } | 540 | } |
534 | 541 | ||
@@ -685,7 +692,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
685 | // | 692 | // |
686 | 693 | ||
687 | // Try local | 694 | // Try local |
688 | if (LocalFriendshipTerminated(exfriendID)) | 695 | if (LocalFriendshipTerminated(client.AgentId, exfriendID)) |
689 | return; | 696 | return; |
690 | 697 | ||
691 | PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { exfriendID.ToString() }); | 698 | PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { exfriendID.ToString() }); |
@@ -827,13 +834,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
827 | return false; | 834 | return false; |
828 | } | 835 | } |
829 | 836 | ||
830 | public bool LocalFriendshipTerminated(UUID exfriendID) | 837 | public bool LocalFriendshipTerminated(UUID userID, UUID exfriendID) |
831 | { | 838 | { |
832 | IClientAPI friendClient = LocateClientObject(exfriendID); | 839 | IClientAPI friendClient = LocateClientObject(exfriendID); |
833 | if (friendClient != null) | 840 | if (friendClient != null) |
834 | { | 841 | { |
835 | // the friend in this sim as root agent | 842 | // the friend in this sim as root agent |
836 | friendClient.SendTerminateFriend(exfriendID); | 843 | friendClient.SendTerminateFriend(userID); |
837 | // update local cache | 844 | // update local cache |
838 | RecacheFriends(friendClient); | 845 | RecacheFriends(friendClient); |
839 | // we're done | 846 | // we're done |
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsRequestHandler.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsRequestHandler.cs index 637beef..ff87ece 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsRequestHandler.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsRequestHandler.cs | |||
@@ -42,19 +42,27 @@ using log4net; | |||
42 | 42 | ||
43 | namespace OpenSim.Region.CoreModules.Avatar.Friends | 43 | namespace OpenSim.Region.CoreModules.Avatar.Friends |
44 | { | 44 | { |
45 | public class FriendsRequestHandler : BaseStreamHandler | 45 | public class FriendsRequestHandler : BaseStreamHandlerBasicDOSProtector |
46 | { | 46 | { |
47 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 47 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
48 | 48 | ||
49 | private FriendsModule m_FriendsModule; | 49 | private FriendsModule m_FriendsModule; |
50 | 50 | ||
51 | public FriendsRequestHandler(FriendsModule fmodule) | 51 | public FriendsRequestHandler(FriendsModule fmodule) |
52 | : base("POST", "/friends") | 52 | : base("POST", "/friends", new BasicDosProtectorOptions() |
53 | { | ||
54 | AllowXForwardedFor = true, | ||
55 | ForgetTimeSpan = TimeSpan.FromMinutes(2), | ||
56 | MaxRequestsInTimeframe = 20, | ||
57 | ReportingName = "FRIENDSDOSPROTECTOR", | ||
58 | RequestTimeSpan = TimeSpan.FromSeconds(5), | ||
59 | ThrottledAction = BasicDOSProtector.ThrottleAction.DoThrottledMethod | ||
60 | }) | ||
53 | { | 61 | { |
54 | m_FriendsModule = fmodule; | 62 | m_FriendsModule = fmodule; |
55 | } | 63 | } |
56 | 64 | ||
57 | public override byte[] Handle( | 65 | protected override byte[] ProcessRequest( |
58 | string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) | 66 | string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) |
59 | { | 67 | { |
60 | StreamReader sr = new StreamReader(requestData); | 68 | StreamReader sr = new StreamReader(requestData); |
@@ -193,7 +201,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
193 | if (!UUID.TryParse(request["ToID"].ToString(), out toID)) | 201 | if (!UUID.TryParse(request["ToID"].ToString(), out toID)) |
194 | return FailureResult(); | 202 | return FailureResult(); |
195 | 203 | ||
196 | if (m_FriendsModule.LocalFriendshipTerminated(toID)) | 204 | if (m_FriendsModule.LocalFriendshipTerminated(fromID, toID)) |
197 | return SuccessResult(); | 205 | return SuccessResult(); |
198 | 206 | ||
199 | return FailureResult(); | 207 | return FailureResult(); |
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs index bf5c0bb..d00945e 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs | |||
@@ -183,6 +183,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
183 | if (Util.ParseUniversalUserIdentifier(finfo.Friend, out id, out url, out first, out last, out tmp)) | 183 | if (Util.ParseUniversalUserIdentifier(finfo.Friend, out id, out url, out first, out last, out tmp)) |
184 | { | 184 | { |
185 | IUserManagement uMan = m_Scenes[0].RequestModuleInterface<IUserManagement>(); | 185 | IUserManagement uMan = m_Scenes[0].RequestModuleInterface<IUserManagement>(); |
186 | m_log.DebugFormat("[HGFRIENDS MODULE]: caching {0}", finfo.Friend); | ||
186 | uMan.AddUser(id, url + ";" + first + " " + last); | 187 | uMan.AddUser(id, url + ";" + first + " " + last); |
187 | } | 188 | } |
188 | } | 189 | } |
@@ -251,7 +252,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
251 | 252 | ||
252 | protected override void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online) | 253 | protected override void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online) |
253 | { | 254 | { |
254 | // m_log.DebugFormat("[HGFRIENDS MODULE]: Entering StatusNotify for {0}", userID); | 255 | //m_log.DebugFormat("[HGFRIENDS MODULE]: Entering StatusNotify for {0}", userID); |
255 | 256 | ||
256 | // First, let's divide the friends on a per-domain basis | 257 | // First, let's divide the friends on a per-domain basis |
257 | Dictionary<string, List<FriendInfo>> friendsPerDomain = new Dictionary<string, List<FriendInfo>>(); | 258 | Dictionary<string, List<FriendInfo>> friendsPerDomain = new Dictionary<string, List<FriendInfo>>(); |
@@ -293,7 +294,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
293 | 294 | ||
294 | protected override bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last) | 295 | protected override bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last) |
295 | { | 296 | { |
296 | first = "Unknown"; last = "User"; | 297 | first = "Unknown"; last = "UserHGGAI"; |
297 | if (base.GetAgentInfo(scopeID, fid, out agentID, out first, out last)) | 298 | if (base.GetAgentInfo(scopeID, fid, out agentID, out first, out last)) |
298 | return true; | 299 | return true; |
299 | 300 | ||
@@ -349,7 +350,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
349 | 350 | ||
350 | public override FriendInfo[] GetFriendsFromService(IClientAPI client) | 351 | public override FriendInfo[] GetFriendsFromService(IClientAPI client) |
351 | { | 352 | { |
352 | // m_log.DebugFormat("[HGFRIENDS MODULE]: Entering GetFriendsFromService for {0}", client.Name); | 353 | // m_log.DebugFormat("[HGFRIENDS MODULE]: Entering GetFriendsFromService for {0}", client.Name); |
353 | Boolean agentIsLocal = true; | 354 | Boolean agentIsLocal = true; |
354 | if (UserManagementModule != null) | 355 | if (UserManagementModule != null) |
355 | agentIsLocal = UserManagementModule.IsLocalGridUser(client.AgentId); | 356 | agentIsLocal = UserManagementModule.IsLocalGridUser(client.AgentId); |
@@ -362,13 +363,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
362 | AgentCircuitData agentClientCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode); | 363 | AgentCircuitData agentClientCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode); |
363 | if (agentClientCircuit != null) | 364 | if (agentClientCircuit != null) |
364 | { | 365 | { |
365 | //[XXX] string agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit); | 366 | // Note that this is calling a different interface than base; this one calls with a string param! |
366 | |||
367 | finfos = FriendsService.GetFriends(client.AgentId.ToString()); | 367 | finfos = FriendsService.GetFriends(client.AgentId.ToString()); |
368 | m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, client.AgentId.ToString()); | 368 | m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, client.AgentId.ToString()); |
369 | } | 369 | } |
370 | 370 | ||
371 | // m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting GetFriendsFromService for {0}", client.Name); | 371 | // m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting GetFriendsFromService for {0}", client.Name); |
372 | 372 | ||
373 | return finfos; | 373 | return finfos; |
374 | } | 374 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs index fa8c3f3..adb838c 100644 --- a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs | |||
@@ -26,27 +26,25 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | ||
30 | using Nini.Config; | ||
31 | using OpenMetaverse; | ||
32 | using OpenSim.Framework; | ||
33 | using OpenSim.Region.Framework.Scenes; | ||
34 | using OpenSim.Region.Framework.Interfaces; | ||
35 | using System; | ||
36 | using System.Reflection; | ||
37 | using System.Collections; | 29 | using System.Collections; |
30 | using System.Collections.Generic; | ||
38 | using System.Collections.Specialized; | 31 | using System.Collections.Specialized; |
39 | using System.Reflection; | ||
40 | using System.IO; | 32 | using System.IO; |
33 | using System.Reflection; | ||
41 | using System.Web; | 34 | using System.Web; |
42 | using System.Xml; | 35 | using System.Xml; |
43 | using log4net; | 36 | using log4net; |
44 | using Mono.Addins; | 37 | using Mono.Addins; |
38 | using Nini.Config; | ||
39 | using OpenMetaverse; | ||
45 | using OpenMetaverse.Messages.Linden; | 40 | using OpenMetaverse.Messages.Linden; |
46 | using OpenMetaverse.StructuredData; | 41 | using OpenMetaverse.StructuredData; |
42 | using OpenSim.Framework; | ||
47 | using OpenSim.Framework.Capabilities; | 43 | using OpenSim.Framework.Capabilities; |
48 | using OpenSim.Framework.Servers; | 44 | using OpenSim.Framework.Servers; |
49 | using OpenSim.Framework.Servers.HttpServer; | 45 | using OpenSim.Framework.Servers.HttpServer; |
46 | using OpenSim.Region.Framework.Scenes; | ||
47 | using OpenSim.Region.Framework.Interfaces; | ||
50 | using Caps = OpenSim.Framework.Capabilities.Caps; | 48 | using Caps = OpenSim.Framework.Capabilities.Caps; |
51 | using OSDArray = OpenMetaverse.StructuredData.OSDArray; | 49 | using OSDArray = OpenMetaverse.StructuredData.OSDArray; |
52 | using OSDMap = OpenMetaverse.StructuredData.OSDMap; | 50 | using OSDMap = OpenMetaverse.StructuredData.OSDMap; |
@@ -127,9 +125,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods | |||
127 | { | 125 | { |
128 | string uri = "/CAPS/" + UUID.Random(); | 126 | string uri = "/CAPS/" + UUID.Random(); |
129 | 127 | ||
130 | caps.RegisterHandler("UntrustedSimulatorMessage", | 128 | caps.RegisterHandler( |
131 | new RestStreamHandler("POST", uri, | 129 | "UntrustedSimulatorMessage", |
132 | HandleUntrustedSimulatorMessage)); | 130 | new RestStreamHandler("POST", uri, HandleUntrustedSimulatorMessage, "UntrustedSimulatorMessage", null)); |
133 | } | 131 | } |
134 | 132 | ||
135 | private string HandleUntrustedSimulatorMessage(string request, | 133 | private string HandleUntrustedSimulatorMessage(string request, |
@@ -278,7 +276,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods | |||
278 | if (sp.IsChildAgent) | 276 | if (sp.IsChildAgent) |
279 | return; | 277 | return; |
280 | sp.ControllingClient.Kick(reason); | 278 | sp.ControllingClient.Kick(reason); |
281 | sp.Scene.IncomingCloseAgent(sp.UUID, true); | 279 | sp.Scene.CloseAgent(sp.UUID, true); |
282 | } | 280 | } |
283 | 281 | ||
284 | private void OnIncomingInstantMessage(GridInstantMessage msg) | 282 | private void OnIncomingInstantMessage(GridInstantMessage msg) |
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs index 1627f6c..b321adb 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs | |||
@@ -392,7 +392,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
392 | gim.fromAgentName = fromAgentName; | 392 | gim.fromAgentName = fromAgentName; |
393 | gim.fromGroup = fromGroup; | 393 | gim.fromGroup = fromGroup; |
394 | gim.imSessionID = imSessionID.Guid; | 394 | gim.imSessionID = imSessionID.Guid; |
395 | gim.RegionID = UUID.Zero.Guid; // RegionID.Guid; | 395 | gim.RegionID = RegionID.Guid; |
396 | gim.timestamp = timestamp; | 396 | gim.timestamp = timestamp; |
397 | gim.toAgentID = toAgentID.Guid; | 397 | gim.toAgentID = toAgentID.Guid; |
398 | gim.message = message; | 398 | gim.message = message; |
@@ -728,7 +728,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage | |||
728 | gim["position_x"] = msg.Position.X.ToString(); | 728 | gim["position_x"] = msg.Position.X.ToString(); |
729 | gim["position_y"] = msg.Position.Y.ToString(); | 729 | gim["position_y"] = msg.Position.Y.ToString(); |
730 | gim["position_z"] = msg.Position.Z.ToString(); | 730 | gim["position_z"] = msg.Position.Z.ToString(); |
731 | gim["region_id"] = msg.RegionID.ToString(); | 731 | gim["region_id"] = new UUID(msg.RegionID).ToString(); |
732 | gim["binary_bucket"] = Convert.ToBase64String(msg.binaryBucket,Base64FormattingOptions.None); | 732 | gim["binary_bucket"] = Convert.ToBase64String(msg.binaryBucket,Base64FormattingOptions.None); |
733 | if (m_MessageKey != String.Empty) | 733 | if (m_MessageKey != String.Empty) |
734 | gim["message_key"] = m_MessageKey; | 734 | gim["message_key"] = m_MessageKey; |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs index 659b178..5a8544e 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs | |||
@@ -67,10 +67,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
67 | /// </summary> | 67 | /// </summary> |
68 | protected bool m_merge; | 68 | protected bool m_merge; |
69 | 69 | ||
70 | /// <value> | 70 | protected IInventoryService m_InventoryService; |
71 | /// We only use this to request modules | 71 | protected IAssetService m_AssetService; |
72 | /// </value> | 72 | protected IUserAccountService m_UserAccountService; |
73 | protected Scene m_scene; | ||
74 | 73 | ||
75 | /// <value> | 74 | /// <value> |
76 | /// The stream from which the inventory archive will be loaded. | 75 | /// The stream from which the inventory archive will be loaded. |
@@ -118,9 +117,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
118 | protected Dictionary<UUID, UUID> m_creatorIdForAssetId = new Dictionary<UUID, UUID>(); | 117 | protected Dictionary<UUID, UUID> m_creatorIdForAssetId = new Dictionary<UUID, UUID>(); |
119 | 118 | ||
120 | public InventoryArchiveReadRequest( | 119 | public InventoryArchiveReadRequest( |
121 | Scene scene, UserAccount userInfo, string invPath, string loadPath, bool merge) | 120 | IInventoryService inv, IAssetService assets, IUserAccountService uacc, UserAccount userInfo, string invPath, string loadPath, bool merge) |
122 | : this( | 121 | : this( |
123 | scene, | 122 | inv, |
123 | assets, | ||
124 | uacc, | ||
124 | userInfo, | 125 | userInfo, |
125 | invPath, | 126 | invPath, |
126 | new GZipStream(ArchiveHelpers.GetStream(loadPath), CompressionMode.Decompress), | 127 | new GZipStream(ArchiveHelpers.GetStream(loadPath), CompressionMode.Decompress), |
@@ -129,9 +130,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
129 | } | 130 | } |
130 | 131 | ||
131 | public InventoryArchiveReadRequest( | 132 | public InventoryArchiveReadRequest( |
132 | Scene scene, UserAccount userInfo, string invPath, Stream loadStream, bool merge) | 133 | IInventoryService inv, IAssetService assets, IUserAccountService uacc, UserAccount userInfo, string invPath, Stream loadStream, bool merge) |
133 | { | 134 | { |
134 | m_scene = scene; | 135 | m_InventoryService = inv; |
136 | m_AssetService = assets; | ||
137 | m_UserAccountService = uacc; | ||
135 | m_merge = merge; | 138 | m_merge = merge; |
136 | m_userInfo = userInfo; | 139 | m_userInfo = userInfo; |
137 | m_invPath = invPath; | 140 | m_invPath = invPath; |
@@ -162,7 +165,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
162 | 165 | ||
163 | List<InventoryFolderBase> folderCandidates | 166 | List<InventoryFolderBase> folderCandidates |
164 | = InventoryArchiveUtils.FindFoldersByPath( | 167 | = InventoryArchiveUtils.FindFoldersByPath( |
165 | m_scene.InventoryService, m_userInfo.PrincipalID, m_invPath); | 168 | m_InventoryService, m_userInfo.PrincipalID, m_invPath); |
166 | 169 | ||
167 | if (folderCandidates.Count == 0) | 170 | if (folderCandidates.Count == 0) |
168 | { | 171 | { |
@@ -297,7 +300,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
297 | string plainPath = ArchiveConstants.ExtractPlainPathFromIarPath(archivePath); | 300 | string plainPath = ArchiveConstants.ExtractPlainPathFromIarPath(archivePath); |
298 | List<InventoryFolderBase> folderCandidates | 301 | List<InventoryFolderBase> folderCandidates |
299 | = InventoryArchiveUtils.FindFoldersByPath( | 302 | = InventoryArchiveUtils.FindFoldersByPath( |
300 | m_scene.InventoryService, m_userInfo.PrincipalID, plainPath); | 303 | m_InventoryService, m_userInfo.PrincipalID, plainPath); |
301 | 304 | ||
302 | if (folderCandidates.Count != 0) | 305 | if (folderCandidates.Count != 0) |
303 | { | 306 | { |
@@ -380,7 +383,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
380 | = new InventoryFolderBase( | 383 | = new InventoryFolderBase( |
381 | newFolderId, newFolderName, m_userInfo.PrincipalID, | 384 | newFolderId, newFolderName, m_userInfo.PrincipalID, |
382 | (short)AssetType.Unknown, destFolder.ID, 1); | 385 | (short)AssetType.Unknown, destFolder.ID, 1); |
383 | m_scene.InventoryService.AddFolder(destFolder); | 386 | m_InventoryService.AddFolder(destFolder); |
384 | 387 | ||
385 | // Record that we have now created this folder | 388 | // Record that we have now created this folder |
386 | iarPathExisting += rawDirsToCreate[i] + "/"; | 389 | iarPathExisting += rawDirsToCreate[i] + "/"; |
@@ -406,7 +409,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
406 | // Don't use the item ID that's in the file | 409 | // Don't use the item ID that's in the file |
407 | item.ID = UUID.Random(); | 410 | item.ID = UUID.Random(); |
408 | 411 | ||
409 | UUID ospResolvedId = OspResolver.ResolveOspa(item.CreatorId, m_scene.UserAccountService); | 412 | UUID ospResolvedId = OspResolver.ResolveOspa(item.CreatorId, m_UserAccountService); |
410 | if (UUID.Zero != ospResolvedId) // The user exists in this grid | 413 | if (UUID.Zero != ospResolvedId) // The user exists in this grid |
411 | { | 414 | { |
412 | // m_log.DebugFormat("[INVENTORY ARCHIVER]: Found creator {0} via OSPA resolution", ospResolvedId); | 415 | // m_log.DebugFormat("[INVENTORY ARCHIVER]: Found creator {0} via OSPA resolution", ospResolvedId); |
@@ -418,7 +421,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
418 | item.CreatorId = ospResolvedId.ToString(); | 421 | item.CreatorId = ospResolvedId.ToString(); |
419 | item.CreatorData = string.Empty; | 422 | item.CreatorData = string.Empty; |
420 | } | 423 | } |
421 | else if (item.CreatorData == null || item.CreatorData == String.Empty) | 424 | else if (string.IsNullOrEmpty(item.CreatorData)) |
422 | { | 425 | { |
423 | item.CreatorId = m_userInfo.PrincipalID.ToString(); | 426 | item.CreatorId = m_userInfo.PrincipalID.ToString(); |
424 | // item.CreatorIdAsUuid = new UUID(item.CreatorId); | 427 | // item.CreatorIdAsUuid = new UUID(item.CreatorId); |
@@ -436,7 +439,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
436 | // relying on native tar tools. | 439 | // relying on native tar tools. |
437 | m_creatorIdForAssetId[item.AssetID] = item.CreatorIdAsUuid; | 440 | m_creatorIdForAssetId[item.AssetID] = item.CreatorIdAsUuid; |
438 | 441 | ||
439 | m_scene.AddInventoryItem(item); | 442 | if (!m_InventoryService.AddItem(item)) |
443 | m_log.WarnFormat("[INVENTORY ARCHIVER]: Unable to save item {0} in folder {1}", item.Name, item.Folder); | ||
440 | 444 | ||
441 | return item; | 445 | return item; |
442 | } | 446 | } |
@@ -518,7 +522,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
518 | 522 | ||
519 | foreach (SceneObjectGroup sog in sceneObjects) | 523 | foreach (SceneObjectGroup sog in sceneObjects) |
520 | foreach (SceneObjectPart sop in sog.Parts) | 524 | foreach (SceneObjectPart sop in sog.Parts) |
521 | if (sop.CreatorData == null || sop.CreatorData == "") | 525 | if (string.IsNullOrEmpty(sop.CreatorData)) |
522 | sop.CreatorID = m_creatorIdForAssetId[assetId]; | 526 | sop.CreatorID = m_creatorIdForAssetId[assetId]; |
523 | 527 | ||
524 | if (coa != null) | 528 | if (coa != null) |
@@ -533,7 +537,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
533 | AssetBase asset = new AssetBase(assetId, "From IAR", assetType, UUID.Zero.ToString()); | 537 | AssetBase asset = new AssetBase(assetId, "From IAR", assetType, UUID.Zero.ToString()); |
534 | asset.Data = data; | 538 | asset.Data = data; |
535 | 539 | ||
536 | m_scene.AssetService.Store(asset); | 540 | m_AssetService.Store(asset); |
537 | 541 | ||
538 | return true; | 542 | return true; |
539 | } | 543 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs index 4ec8ae7..4292719 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs | |||
@@ -78,7 +78,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
78 | /// <value> | 78 | /// <value> |
79 | /// Used to collect the uuids of the assets that we need to save into the archive | 79 | /// Used to collect the uuids of the assets that we need to save into the archive |
80 | /// </value> | 80 | /// </value> |
81 | protected Dictionary<UUID, AssetType> m_assetUuids = new Dictionary<UUID, AssetType>(); | 81 | protected Dictionary<UUID, sbyte> m_assetUuids = new Dictionary<UUID, sbyte>(); |
82 | 82 | ||
83 | /// <value> | 83 | /// <value> |
84 | /// Used to collect the uuids of the users that we need to save into the archive | 84 | /// Used to collect the uuids of the users that we need to save into the archive |
@@ -187,7 +187,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
187 | 187 | ||
188 | // Don't chase down link asset items as they actually point to their target item IDs rather than an asset | 188 | // Don't chase down link asset items as they actually point to their target item IDs rather than an asset |
189 | if (SaveAssets && itemAssetType != AssetType.Link && itemAssetType != AssetType.LinkFolder) | 189 | if (SaveAssets && itemAssetType != AssetType.Link && itemAssetType != AssetType.LinkFolder) |
190 | m_assetGatherer.GatherAssetUuids(inventoryItem.AssetID, (AssetType)inventoryItem.AssetType, m_assetUuids); | 190 | m_assetGatherer.GatherAssetUuids(inventoryItem.AssetID, (sbyte)inventoryItem.AssetType, m_assetUuids); |
191 | } | 191 | } |
192 | 192 | ||
193 | /// <summary> | 193 | /// <summary> |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs index f4f9e2d..ea660bd 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs | |||
@@ -294,7 +294,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
294 | 294 | ||
295 | try | 295 | try |
296 | { | 296 | { |
297 | request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadStream, merge); | 297 | request = new InventoryArchiveReadRequest(m_aScene.InventoryService, m_aScene.AssetService, m_aScene.UserAccountService, userInfo, invPath, loadStream, merge); |
298 | } | 298 | } |
299 | catch (EntryPointNotFoundException e) | 299 | catch (EntryPointNotFoundException e) |
300 | { | 300 | { |
@@ -342,7 +342,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
342 | 342 | ||
343 | try | 343 | try |
344 | { | 344 | { |
345 | request = new InventoryArchiveReadRequest(m_aScene, userInfo, invPath, loadPath, merge); | 345 | request = new InventoryArchiveReadRequest(m_aScene.InventoryService, m_aScene.AssetService, m_aScene.UserAccountService, userInfo, invPath, loadPath, merge); |
346 | } | 346 | } |
347 | catch (EntryPointNotFoundException e) | 347 | catch (EntryPointNotFoundException e) |
348 | { | 348 | { |
@@ -538,7 +538,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver | |||
538 | } | 538 | } |
539 | catch (Exception e) | 539 | catch (Exception e) |
540 | { | 540 | { |
541 | m_log.ErrorFormat("[INVENTORY ARCHIVER]: Could not authenticate password, {0}", e.Message); | 541 | m_log.ErrorFormat("[INVENTORY ARCHIVER]: Could not authenticate password, {0}", e); |
542 | return null; | 542 | return null; |
543 | } | 543 | } |
544 | */ | 544 | */ |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs index 95f562e..08f199a 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs | |||
@@ -229,7 +229,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
229 | 229 | ||
230 | { | 230 | { |
231 | // Test replication of path1 | 231 | // Test replication of path1 |
232 | new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false) | 232 | new InventoryArchiveReadRequest(scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, null, (Stream)null, false) |
233 | .ReplicateArchivePathToUserInventory( | 233 | .ReplicateArchivePathToUserInventory( |
234 | iarPath1, scene.InventoryService.GetRootFolder(ua1.PrincipalID), | 234 | iarPath1, scene.InventoryService.GetRootFolder(ua1.PrincipalID), |
235 | foldersCreated, nodesLoaded); | 235 | foldersCreated, nodesLoaded); |
@@ -246,7 +246,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
246 | 246 | ||
247 | { | 247 | { |
248 | // Test replication of path2 | 248 | // Test replication of path2 |
249 | new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false) | 249 | new InventoryArchiveReadRequest(scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, null, (Stream)null, false) |
250 | .ReplicateArchivePathToUserInventory( | 250 | .ReplicateArchivePathToUserInventory( |
251 | iarPath2, scene.InventoryService.GetRootFolder(ua1.PrincipalID), | 251 | iarPath2, scene.InventoryService.GetRootFolder(ua1.PrincipalID), |
252 | foldersCreated, nodesLoaded); | 252 | foldersCreated, nodesLoaded); |
@@ -291,8 +291,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
291 | string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random()); | 291 | string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random()); |
292 | 292 | ||
293 | string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName }); | 293 | string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName }); |
294 | 294 | ||
295 | new InventoryArchiveReadRequest(scene, ua1, null, (Stream)null, false) | 295 | new InventoryArchiveReadRequest(scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, null, (Stream)null, false) |
296 | .ReplicateArchivePathToUserInventory( | 296 | .ReplicateArchivePathToUserInventory( |
297 | itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID), | 297 | itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID), |
298 | new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>()); | 298 | new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>()); |
@@ -342,8 +342,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
342 | string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random()); | 342 | string folder2ArchiveName = InventoryArchiveWriteRequest.CreateArchiveFolderName(folder2Name, UUID.Random()); |
343 | 343 | ||
344 | string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName }); | 344 | string itemArchivePath = string.Join("", new string[] { folder1ArchiveName, folder2ArchiveName }); |
345 | 345 | ||
346 | new InventoryArchiveReadRequest(scene, ua1, folder1ExistingName, (Stream)null, true) | 346 | new InventoryArchiveReadRequest(scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, folder1ExistingName, (Stream)null, true) |
347 | .ReplicateArchivePathToUserInventory( | 347 | .ReplicateArchivePathToUserInventory( |
348 | itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID), | 348 | itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID), |
349 | new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>()); | 349 | new Dictionary<string, InventoryFolderBase>(), new HashSet<InventoryNodeBase>()); |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveSaveTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveSaveTests.cs index 5e7e24c..b85739e 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveSaveTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveSaveTests.cs | |||
@@ -86,7 +86,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests | |||
86 | Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH)); | 86 | Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH)); |
87 | 87 | ||
88 | InventoryArchiveReadRequest iarr | 88 | InventoryArchiveReadRequest iarr |
89 | = new InventoryArchiveReadRequest(null, null, null, (Stream)null, false); | 89 | = new InventoryArchiveReadRequest(null, null, null, null, null, (Stream)null, false); |
90 | iarr.LoadControlFile(filePath, data); | 90 | iarr.LoadControlFile(filePath, data); |
91 | 91 | ||
92 | Assert.That(iarr.ControlFileLoaded, Is.True); | 92 | Assert.That(iarr.ControlFileLoaded, Is.True); |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs index f122d00..03aaaac 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs | |||
@@ -47,10 +47,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
47 | 47 | ||
48 | /// <summary> | 48 | /// <summary> |
49 | private List<Scene> m_Scenelist = new List<Scene>(); | 49 | private List<Scene> m_Scenelist = new List<Scene>(); |
50 | // private Dictionary<UUID, Scene> m_AgentRegions = | ||
51 | // new Dictionary<UUID, Scene>(); | ||
52 | 50 | ||
53 | private IMessageTransferModule m_TransferModule = null; | 51 | private IMessageTransferModule m_TransferModule; |
54 | private bool m_Enabled = true; | 52 | private bool m_Enabled = true; |
55 | 53 | ||
56 | #region Region Module interface | 54 | #region Region Module interface |
@@ -81,9 +79,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
81 | // scene.RegisterModuleInterface<IInventoryTransferModule>(this); | 79 | // scene.RegisterModuleInterface<IInventoryTransferModule>(this); |
82 | 80 | ||
83 | scene.EventManager.OnNewClient += OnNewClient; | 81 | scene.EventManager.OnNewClient += OnNewClient; |
84 | // scene.EventManager.OnClientClosed += ClientLoggedOut; | ||
85 | scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; | 82 | scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; |
86 | // scene.EventManager.OnSetRootAgentScene += OnSetRootAgentScene; | ||
87 | } | 83 | } |
88 | 84 | ||
89 | public void RegionLoaded(Scene scene) | 85 | public void RegionLoaded(Scene scene) |
@@ -96,11 +92,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
96 | m_log.Error("[INVENTORY TRANSFER]: No Message transfer module found, transfers will be local only"); | 92 | m_log.Error("[INVENTORY TRANSFER]: No Message transfer module found, transfers will be local only"); |
97 | m_Enabled = false; | 93 | m_Enabled = false; |
98 | 94 | ||
99 | m_Scenelist.Clear(); | 95 | // m_Scenelist.Clear(); |
100 | scene.EventManager.OnNewClient -= OnNewClient; | 96 | // scene.EventManager.OnNewClient -= OnNewClient; |
101 | // scene.EventManager.OnClientClosed -= ClientLoggedOut; | ||
102 | scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage; | 97 | scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage; |
103 | // scene.EventManager.OnSetRootAgentScene -= OnSetRootAgentScene; | ||
104 | } | 98 | } |
105 | } | 99 | } |
106 | } | 100 | } |
@@ -108,9 +102,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
108 | public void RemoveRegion(Scene scene) | 102 | public void RemoveRegion(Scene scene) |
109 | { | 103 | { |
110 | scene.EventManager.OnNewClient -= OnNewClient; | 104 | scene.EventManager.OnNewClient -= OnNewClient; |
111 | // scene.EventManager.OnClientClosed -= ClientLoggedOut; | ||
112 | scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage; | 105 | scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage; |
113 | // scene.EventManager.OnSetRootAgentScene -= OnSetRootAgentScene; | ||
114 | m_Scenelist.Remove(scene); | 106 | m_Scenelist.Remove(scene); |
115 | } | 107 | } |
116 | 108 | ||
@@ -139,11 +131,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
139 | // Inventory giving is conducted via instant message | 131 | // Inventory giving is conducted via instant message |
140 | client.OnInstantMessage += OnInstantMessage; | 132 | client.OnInstantMessage += OnInstantMessage; |
141 | } | 133 | } |
142 | |||
143 | // protected void OnSetRootAgentScene(UUID id, Scene scene) | ||
144 | // { | ||
145 | // m_AgentRegions[id] = scene; | ||
146 | // } | ||
147 | 134 | ||
148 | private Scene FindClientScene(UUID agentId) | 135 | private Scene FindClientScene(UUID agentId) |
149 | { | 136 | { |
@@ -162,8 +149,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
162 | private void OnInstantMessage(IClientAPI client, GridInstantMessage im) | 149 | private void OnInstantMessage(IClientAPI client, GridInstantMessage im) |
163 | { | 150 | { |
164 | // m_log.DebugFormat( | 151 | // m_log.DebugFormat( |
165 | // "[INVENTORY TRANSFER]: {0} IM type received from {1}", | 152 | // "[INVENTORY TRANSFER]: {0} IM type received from client {1}. From={2} ({3}), To={4}", |
166 | // (InstantMessageDialog)im.dialog, client.Name); | 153 | // (InstantMessageDialog)im.dialog, client.Name, |
154 | // im.fromAgentID, im.fromAgentName, im.toAgentID); | ||
167 | 155 | ||
168 | Scene scene = FindClientScene(client.AgentId); | 156 | Scene scene = FindClientScene(client.AgentId); |
169 | 157 | ||
@@ -188,9 +176,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
188 | { | 176 | { |
189 | UUID folderID = new UUID(im.binaryBucket, 1); | 177 | UUID folderID = new UUID(im.binaryBucket, 1); |
190 | 178 | ||
191 | m_log.DebugFormat("[INVENTORY TRANSFER]: Inserting original folder {0} "+ | 179 | m_log.DebugFormat( |
192 | "into agent {1}'s inventory", | 180 | "[INVENTORY TRANSFER]: Inserting original folder {0} into agent {1}'s inventory", |
193 | folderID, new UUID(im.toAgentID)); | 181 | folderID, new UUID(im.toAgentID)); |
194 | 182 | ||
195 | InventoryFolderBase folderCopy | 183 | InventoryFolderBase folderCopy |
196 | = scene.GiveInventoryFolder(recipientID, client.AgentId, folderID, UUID.Zero); | 184 | = scene.GiveInventoryFolder(recipientID, client.AgentId, folderID, UUID.Zero); |
@@ -213,7 +201,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
213 | user.ControllingClient.SendBulkUpdateInventory(folderCopy); | 201 | user.ControllingClient.SendBulkUpdateInventory(folderCopy); |
214 | 202 | ||
215 | // HACK!! | 203 | // HACK!! |
216 | // Insert the ID of the copied item into the IM so that we know which item to move to trash if it | 204 | // Insert the ID of the copied folder into the IM so that we know which item to move to trash if it |
217 | // is rejected. | 205 | // is rejected. |
218 | // XXX: This is probably a misuse of the session ID slot. | 206 | // XXX: This is probably a misuse of the session ID slot. |
219 | im.imSessionID = copyID.Guid; | 207 | im.imSessionID = copyID.Guid; |
@@ -425,7 +413,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
425 | { | 413 | { |
426 | folder = new InventoryFolderBase(inventoryID, client.AgentId); | 414 | folder = new InventoryFolderBase(inventoryID, client.AgentId); |
427 | folder = invService.GetFolder(folder); | 415 | folder = invService.GetFolder(folder); |
428 | 416 | ||
429 | if (folder != null & trashFolder != null) | 417 | if (folder != null & trashFolder != null) |
430 | { | 418 | { |
431 | previousParentFolderID = folder.ParentID; | 419 | previousParentFolderID = folder.ParentID; |
@@ -477,76 +465,23 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer | |||
477 | } | 465 | } |
478 | } | 466 | } |
479 | 467 | ||
480 | // public bool NeedSceneCacheClear(UUID agentID, Scene scene) | ||
481 | // { | ||
482 | // if (!m_AgentRegions.ContainsKey(agentID)) | ||
483 | // { | ||
484 | // // Since we can get here two ways, we need to scan | ||
485 | // // the scenes here. This is somewhat more expensive | ||
486 | // // but helps avoid a nasty bug | ||
487 | // // | ||
488 | // | ||
489 | // foreach (Scene s in m_Scenelist) | ||
490 | // { | ||
491 | // ScenePresence presence; | ||
492 | // | ||
493 | // if (s.TryGetScenePresence(agentID, out presence)) | ||
494 | // { | ||
495 | // // If the agent is in this scene, then we | ||
496 | // // are being called twice in a single | ||
497 | // // teleport. This is wasteful of cycles | ||
498 | // // but harmless due to this 2nd level check | ||
499 | // // | ||
500 | // // If the agent is found in another scene | ||
501 | // // then the list wasn't current | ||
502 | // // | ||
503 | // // If the agent is totally unknown, then what | ||
504 | // // are we even doing here?? | ||
505 | // // | ||
506 | // if (s == scene) | ||
507 | // { | ||
508 | // //m_log.Debug("[INVTRANSFERMOD]: s == scene. Returning true in " + scene.RegionInfo.RegionName); | ||
509 | // return true; | ||
510 | // } | ||
511 | // else | ||
512 | // { | ||
513 | // //m_log.Debug("[INVTRANSFERMOD]: s != scene. Returning false in " + scene.RegionInfo.RegionName); | ||
514 | // return false; | ||
515 | // } | ||
516 | // } | ||
517 | // } | ||
518 | // //m_log.Debug("[INVTRANSFERMOD]: agent not in scene. Returning true in " + scene.RegionInfo.RegionName); | ||
519 | // return true; | ||
520 | // } | ||
521 | // | ||
522 | // // The agent is left in current Scene, so we must be | ||
523 | // // going to another instance | ||
524 | // // | ||
525 | // if (m_AgentRegions[agentID] == scene) | ||
526 | // { | ||
527 | // //m_log.Debug("[INVTRANSFERMOD]: m_AgentRegions[agentID] == scene. Returning true in " + scene.RegionInfo.RegionName); | ||
528 | // m_AgentRegions.Remove(agentID); | ||
529 | // return true; | ||
530 | // } | ||
531 | // | ||
532 | // // Another region has claimed the agent | ||
533 | // // | ||
534 | // //m_log.Debug("[INVTRANSFERMOD]: last resort. Returning false in " + scene.RegionInfo.RegionName); | ||
535 | // return false; | ||
536 | // } | ||
537 | // | ||
538 | // public void ClientLoggedOut(UUID agentID, Scene scene) | ||
539 | // { | ||
540 | // if (m_AgentRegions.ContainsKey(agentID)) | ||
541 | // m_AgentRegions.Remove(agentID); | ||
542 | // } | ||
543 | |||
544 | /// <summary> | 468 | /// <summary> |
545 | /// | 469 | /// |
546 | /// </summary> | 470 | /// </summary> |
547 | /// <param name="msg"></param> | 471 | /// <param name="im"></param> |
548 | private void OnGridInstantMessage(GridInstantMessage im) | 472 | private void OnGridInstantMessage(GridInstantMessage im) |
549 | { | 473 | { |
474 | // Check if it's a type of message that we should handle | ||
475 | if (!((im.dialog == (byte) InstantMessageDialog.InventoryOffered) | ||
476 | || (im.dialog == (byte) InstantMessageDialog.InventoryAccepted) | ||
477 | || (im.dialog == (byte) InstantMessageDialog.InventoryDeclined) | ||
478 | || (im.dialog == (byte) InstantMessageDialog.TaskInventoryDeclined))) | ||
479 | return; | ||
480 | |||
481 | m_log.DebugFormat( | ||
482 | "[INVENTORY TRANSFER]: {0} IM type received from grid. From={1} ({2}), To={3}", | ||
483 | (InstantMessageDialog)im.dialog, im.fromAgentID, im.fromAgentName, im.toAgentID); | ||
484 | |||
550 | // Check if this is ours to handle | 485 | // Check if this is ours to handle |
551 | // | 486 | // |
552 | Scene scene = FindClientScene(new UUID(im.toAgentID)); | 487 | Scene scene = FindClientScene(new UUID(im.toAgentID)); |
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/Tests/InventoryTransferModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/Tests/InventoryTransferModuleTests.cs new file mode 100644 index 0000000..162a0c3 --- /dev/null +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/Tests/InventoryTransferModuleTests.cs | |||
@@ -0,0 +1,449 @@ | |||
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 log4net.Config; | ||
32 | using Nini.Config; | ||
33 | using NUnit.Framework; | ||
34 | using OpenMetaverse; | ||
35 | using OpenMetaverse.Assets; | ||
36 | using OpenSim.Framework; | ||
37 | using OpenSim.Region.CoreModules.Avatar.Inventory.Transfer; | ||
38 | using OpenSim.Region.Framework.Interfaces; | ||
39 | using OpenSim.Region.Framework.Scenes; | ||
40 | using OpenSim.Services.Interfaces; | ||
41 | using OpenSim.Tests.Common; | ||
42 | using OpenSim.Tests.Common.Mock; | ||
43 | |||
44 | namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer.Tests | ||
45 | { | ||
46 | [TestFixture] | ||
47 | public class InventoryTransferModuleTests : OpenSimTestCase | ||
48 | { | ||
49 | protected TestScene m_scene; | ||
50 | |||
51 | [SetUp] | ||
52 | public override void SetUp() | ||
53 | { | ||
54 | base.SetUp(); | ||
55 | |||
56 | IConfigSource config = new IniConfigSource(); | ||
57 | config.AddConfig("Messaging"); | ||
58 | config.Configs["Messaging"].Set("InventoryTransferModule", "InventoryTransferModule"); | ||
59 | |||
60 | m_scene = new SceneHelpers().SetupScene(); | ||
61 | SceneHelpers.SetupSceneModules(m_scene, config, new InventoryTransferModule()); | ||
62 | } | ||
63 | |||
64 | [Test] | ||
65 | public void TestAcceptGivenItem() | ||
66 | { | ||
67 | // TestHelpers.EnableLogging(); | ||
68 | |||
69 | UUID initialSessionId = TestHelpers.ParseTail(0x10); | ||
70 | UUID itemId = TestHelpers.ParseTail(0x100); | ||
71 | UUID assetId = TestHelpers.ParseTail(0x200); | ||
72 | |||
73 | UserAccount ua1 | ||
74 | = UserAccountHelpers.CreateUserWithInventory(m_scene, "User", "One", TestHelpers.ParseTail(0x1), "pw"); | ||
75 | UserAccount ua2 | ||
76 | = UserAccountHelpers.CreateUserWithInventory(m_scene, "User", "Two", TestHelpers.ParseTail(0x2), "pw"); | ||
77 | |||
78 | ScenePresence giverSp = SceneHelpers.AddScenePresence(m_scene, ua1); | ||
79 | TestClient giverClient = (TestClient)giverSp.ControllingClient; | ||
80 | |||
81 | ScenePresence receiverSp = SceneHelpers.AddScenePresence(m_scene, ua2); | ||
82 | TestClient receiverClient = (TestClient)receiverSp.ControllingClient; | ||
83 | |||
84 | // Create the object to test give | ||
85 | InventoryItemBase originalItem | ||
86 | = UserInventoryHelpers.CreateInventoryItem( | ||
87 | m_scene, "givenObj", itemId, assetId, giverSp.UUID, InventoryType.Object); | ||
88 | |||
89 | byte[] giveImBinaryBucket = new byte[17]; | ||
90 | byte[] itemIdBytes = itemId.GetBytes(); | ||
91 | Array.Copy(itemIdBytes, 0, giveImBinaryBucket, 1, itemIdBytes.Length); | ||
92 | |||
93 | GridInstantMessage giveIm | ||
94 | = new GridInstantMessage( | ||
95 | m_scene, | ||
96 | giverSp.UUID, | ||
97 | giverSp.Name, | ||
98 | receiverSp.UUID, | ||
99 | (byte)InstantMessageDialog.InventoryOffered, | ||
100 | false, | ||
101 | "inventory offered msg", | ||
102 | initialSessionId, | ||
103 | false, | ||
104 | Vector3.Zero, | ||
105 | giveImBinaryBucket, | ||
106 | true); | ||
107 | |||
108 | giverClient.HandleImprovedInstantMessage(giveIm); | ||
109 | |||
110 | // These details might not all be correct. | ||
111 | GridInstantMessage acceptIm | ||
112 | = new GridInstantMessage( | ||
113 | m_scene, | ||
114 | receiverSp.UUID, | ||
115 | receiverSp.Name, | ||
116 | giverSp.UUID, | ||
117 | (byte)InstantMessageDialog.InventoryAccepted, | ||
118 | false, | ||
119 | "inventory accepted msg", | ||
120 | initialSessionId, | ||
121 | false, | ||
122 | Vector3.Zero, | ||
123 | null, | ||
124 | true); | ||
125 | |||
126 | receiverClient.HandleImprovedInstantMessage(acceptIm); | ||
127 | |||
128 | // Test for item remaining in the giver's inventory (here we assume a copy item) | ||
129 | // TODO: Test no-copy items. | ||
130 | InventoryItemBase originalItemAfterGive | ||
131 | = UserInventoryHelpers.GetInventoryItem(m_scene.InventoryService, giverSp.UUID, "Objects/givenObj"); | ||
132 | |||
133 | Assert.That(originalItemAfterGive, Is.Not.Null); | ||
134 | Assert.That(originalItemAfterGive.ID, Is.EqualTo(originalItem.ID)); | ||
135 | |||
136 | // Test for item successfully making it into the receiver's inventory | ||
137 | InventoryItemBase receivedItem | ||
138 | = UserInventoryHelpers.GetInventoryItem(m_scene.InventoryService, receiverSp.UUID, "Objects/givenObj"); | ||
139 | |||
140 | Assert.That(receivedItem, Is.Not.Null); | ||
141 | Assert.That(receivedItem.ID, Is.Not.EqualTo(originalItem.ID)); | ||
142 | |||
143 | // Test that on a delete, item still exists and is accessible for the giver. | ||
144 | m_scene.InventoryService.DeleteItems(receiverSp.UUID, new List<UUID>() { receivedItem.ID }); | ||
145 | |||
146 | InventoryItemBase originalItemAfterDelete | ||
147 | = UserInventoryHelpers.GetInventoryItem(m_scene.InventoryService, giverSp.UUID, "Objects/givenObj"); | ||
148 | |||
149 | Assert.That(originalItemAfterDelete, Is.Not.Null); | ||
150 | |||
151 | // TODO: Test scenario where giver deletes their item first. | ||
152 | } | ||
153 | |||
154 | /// <summary> | ||
155 | /// Test user rejection of a given item. | ||
156 | /// </summary> | ||
157 | /// <remarks> | ||
158 | /// A rejected item still ends up in the user's trash folder. | ||
159 | /// </remarks> | ||
160 | [Test] | ||
161 | public void TestRejectGivenItem() | ||
162 | { | ||
163 | // TestHelpers.EnableLogging(); | ||
164 | |||
165 | UUID initialSessionId = TestHelpers.ParseTail(0x10); | ||
166 | UUID itemId = TestHelpers.ParseTail(0x100); | ||
167 | UUID assetId = TestHelpers.ParseTail(0x200); | ||
168 | |||
169 | UserAccount ua1 | ||
170 | = UserAccountHelpers.CreateUserWithInventory(m_scene, "User", "One", TestHelpers.ParseTail(0x1), "pw"); | ||
171 | UserAccount ua2 | ||
172 | = UserAccountHelpers.CreateUserWithInventory(m_scene, "User", "Two", TestHelpers.ParseTail(0x2), "pw"); | ||
173 | |||
174 | ScenePresence giverSp = SceneHelpers.AddScenePresence(m_scene, ua1); | ||
175 | TestClient giverClient = (TestClient)giverSp.ControllingClient; | ||
176 | |||
177 | ScenePresence receiverSp = SceneHelpers.AddScenePresence(m_scene, ua2); | ||
178 | TestClient receiverClient = (TestClient)receiverSp.ControllingClient; | ||
179 | |||
180 | // Create the object to test give | ||
181 | InventoryItemBase originalItem | ||
182 | = UserInventoryHelpers.CreateInventoryItem( | ||
183 | m_scene, "givenObj", itemId, assetId, giverSp.UUID, InventoryType.Object); | ||
184 | |||
185 | GridInstantMessage receivedIm = null; | ||
186 | receiverClient.OnReceivedInstantMessage += im => receivedIm = im; | ||
187 | |||
188 | byte[] giveImBinaryBucket = new byte[17]; | ||
189 | byte[] itemIdBytes = itemId.GetBytes(); | ||
190 | Array.Copy(itemIdBytes, 0, giveImBinaryBucket, 1, itemIdBytes.Length); | ||
191 | |||
192 | GridInstantMessage giveIm | ||
193 | = new GridInstantMessage( | ||
194 | m_scene, | ||
195 | giverSp.UUID, | ||
196 | giverSp.Name, | ||
197 | receiverSp.UUID, | ||
198 | (byte)InstantMessageDialog.InventoryOffered, | ||
199 | false, | ||
200 | "inventory offered msg", | ||
201 | initialSessionId, | ||
202 | false, | ||
203 | Vector3.Zero, | ||
204 | giveImBinaryBucket, | ||
205 | true); | ||
206 | |||
207 | giverClient.HandleImprovedInstantMessage(giveIm); | ||
208 | |||
209 | // These details might not all be correct. | ||
210 | // Session ID is now the created item ID (!) | ||
211 | GridInstantMessage rejectIm | ||
212 | = new GridInstantMessage( | ||
213 | m_scene, | ||
214 | receiverSp.UUID, | ||
215 | receiverSp.Name, | ||
216 | giverSp.UUID, | ||
217 | (byte)InstantMessageDialog.InventoryDeclined, | ||
218 | false, | ||
219 | "inventory declined msg", | ||
220 | new UUID(receivedIm.imSessionID), | ||
221 | false, | ||
222 | Vector3.Zero, | ||
223 | null, | ||
224 | true); | ||
225 | |||
226 | receiverClient.HandleImprovedInstantMessage(rejectIm); | ||
227 | |||
228 | // Test for item remaining in the giver's inventory (here we assume a copy item) | ||
229 | // TODO: Test no-copy items. | ||
230 | InventoryItemBase originalItemAfterGive | ||
231 | = UserInventoryHelpers.GetInventoryItem(m_scene.InventoryService, giverSp.UUID, "Objects/givenObj"); | ||
232 | |||
233 | Assert.That(originalItemAfterGive, Is.Not.Null); | ||
234 | Assert.That(originalItemAfterGive.ID, Is.EqualTo(originalItem.ID)); | ||
235 | |||
236 | // Test for item successfully making it into the receiver's inventory | ||
237 | InventoryItemBase receivedItem | ||
238 | = UserInventoryHelpers.GetInventoryItem(m_scene.InventoryService, receiverSp.UUID, "Trash/givenObj"); | ||
239 | |||
240 | InventoryFolderBase trashFolder | ||
241 | = m_scene.InventoryService.GetFolderForType(receiverSp.UUID, AssetType.TrashFolder); | ||
242 | |||
243 | Assert.That(receivedItem, Is.Not.Null); | ||
244 | Assert.That(receivedItem.ID, Is.Not.EqualTo(originalItem.ID)); | ||
245 | Assert.That(receivedItem.Folder, Is.EqualTo(trashFolder.ID)); | ||
246 | |||
247 | // Test that on a delete, item still exists and is accessible for the giver. | ||
248 | m_scene.InventoryService.PurgeFolder(trashFolder); | ||
249 | |||
250 | InventoryItemBase originalItemAfterDelete | ||
251 | = UserInventoryHelpers.GetInventoryItem(m_scene.InventoryService, giverSp.UUID, "Objects/givenObj"); | ||
252 | |||
253 | Assert.That(originalItemAfterDelete, Is.Not.Null); | ||
254 | } | ||
255 | |||
256 | [Test] | ||
257 | public void TestAcceptGivenFolder() | ||
258 | { | ||
259 | TestHelpers.InMethod(); | ||
260 | // TestHelpers.EnableLogging(); | ||
261 | |||
262 | UUID initialSessionId = TestHelpers.ParseTail(0x10); | ||
263 | UUID folderId = TestHelpers.ParseTail(0x100); | ||
264 | |||
265 | UserAccount ua1 | ||
266 | = UserAccountHelpers.CreateUserWithInventory(m_scene, "User", "One", TestHelpers.ParseTail(0x1), "pw"); | ||
267 | UserAccount ua2 | ||
268 | = UserAccountHelpers.CreateUserWithInventory(m_scene, "User", "Two", TestHelpers.ParseTail(0x2), "pw"); | ||
269 | |||
270 | ScenePresence giverSp = SceneHelpers.AddScenePresence(m_scene, ua1); | ||
271 | TestClient giverClient = (TestClient)giverSp.ControllingClient; | ||
272 | |||
273 | ScenePresence receiverSp = SceneHelpers.AddScenePresence(m_scene, ua2); | ||
274 | TestClient receiverClient = (TestClient)receiverSp.ControllingClient; | ||
275 | |||
276 | InventoryFolderBase originalFolder | ||
277 | = UserInventoryHelpers.CreateInventoryFolder( | ||
278 | m_scene.InventoryService, giverSp.UUID, folderId, "f1", true); | ||
279 | |||
280 | byte[] giveImBinaryBucket = new byte[17]; | ||
281 | giveImBinaryBucket[0] = (byte)AssetType.Folder; | ||
282 | byte[] itemIdBytes = folderId.GetBytes(); | ||
283 | Array.Copy(itemIdBytes, 0, giveImBinaryBucket, 1, itemIdBytes.Length); | ||
284 | |||
285 | GridInstantMessage giveIm | ||
286 | = new GridInstantMessage( | ||
287 | m_scene, | ||
288 | giverSp.UUID, | ||
289 | giverSp.Name, | ||
290 | receiverSp.UUID, | ||
291 | (byte)InstantMessageDialog.InventoryOffered, | ||
292 | false, | ||
293 | "inventory offered msg", | ||
294 | initialSessionId, | ||
295 | false, | ||
296 | Vector3.Zero, | ||
297 | giveImBinaryBucket, | ||
298 | true); | ||
299 | |||
300 | giverClient.HandleImprovedInstantMessage(giveIm); | ||
301 | |||
302 | // These details might not all be correct. | ||
303 | GridInstantMessage acceptIm | ||
304 | = new GridInstantMessage( | ||
305 | m_scene, | ||
306 | receiverSp.UUID, | ||
307 | receiverSp.Name, | ||
308 | giverSp.UUID, | ||
309 | (byte)InstantMessageDialog.InventoryAccepted, | ||
310 | false, | ||
311 | "inventory accepted msg", | ||
312 | initialSessionId, | ||
313 | false, | ||
314 | Vector3.Zero, | ||
315 | null, | ||
316 | true); | ||
317 | |||
318 | receiverClient.HandleImprovedInstantMessage(acceptIm); | ||
319 | |||
320 | // Test for item remaining in the giver's inventory (here we assume a copy item) | ||
321 | // TODO: Test no-copy items. | ||
322 | InventoryFolderBase originalFolderAfterGive | ||
323 | = UserInventoryHelpers.GetInventoryFolder(m_scene.InventoryService, giverSp.UUID, "f1"); | ||
324 | |||
325 | Assert.That(originalFolderAfterGive, Is.Not.Null); | ||
326 | Assert.That(originalFolderAfterGive.ID, Is.EqualTo(originalFolder.ID)); | ||
327 | |||
328 | // Test for item successfully making it into the receiver's inventory | ||
329 | InventoryFolderBase receivedFolder | ||
330 | = UserInventoryHelpers.GetInventoryFolder(m_scene.InventoryService, receiverSp.UUID, "f1"); | ||
331 | |||
332 | Assert.That(receivedFolder, Is.Not.Null); | ||
333 | Assert.That(receivedFolder.ID, Is.Not.EqualTo(originalFolder.ID)); | ||
334 | |||
335 | // Test that on a delete, item still exists and is accessible for the giver. | ||
336 | m_scene.InventoryService.DeleteFolders(receiverSp.UUID, new List<UUID>() { receivedFolder.ID }); | ||
337 | |||
338 | InventoryFolderBase originalFolderAfterDelete | ||
339 | = UserInventoryHelpers.GetInventoryFolder(m_scene.InventoryService, giverSp.UUID, "f1"); | ||
340 | |||
341 | Assert.That(originalFolderAfterDelete, Is.Not.Null); | ||
342 | |||
343 | // TODO: Test scenario where giver deletes their item first. | ||
344 | } | ||
345 | |||
346 | /// <summary> | ||
347 | /// Test user rejection of a given item. | ||
348 | /// </summary> | ||
349 | /// <remarks> | ||
350 | /// A rejected item still ends up in the user's trash folder. | ||
351 | /// </remarks> | ||
352 | [Test] | ||
353 | public void TestRejectGivenFolder() | ||
354 | { | ||
355 | TestHelpers.InMethod(); | ||
356 | // TestHelpers.EnableLogging(); | ||
357 | |||
358 | UUID initialSessionId = TestHelpers.ParseTail(0x10); | ||
359 | UUID folderId = TestHelpers.ParseTail(0x100); | ||
360 | |||
361 | UserAccount ua1 | ||
362 | = UserAccountHelpers.CreateUserWithInventory(m_scene, "User", "One", TestHelpers.ParseTail(0x1), "pw"); | ||
363 | UserAccount ua2 | ||
364 | = UserAccountHelpers.CreateUserWithInventory(m_scene, "User", "Two", TestHelpers.ParseTail(0x2), "pw"); | ||
365 | |||
366 | ScenePresence giverSp = SceneHelpers.AddScenePresence(m_scene, ua1); | ||
367 | TestClient giverClient = (TestClient)giverSp.ControllingClient; | ||
368 | |||
369 | ScenePresence receiverSp = SceneHelpers.AddScenePresence(m_scene, ua2); | ||
370 | TestClient receiverClient = (TestClient)receiverSp.ControllingClient; | ||
371 | |||
372 | // Create the folder to test give | ||
373 | InventoryFolderBase originalFolder | ||
374 | = UserInventoryHelpers.CreateInventoryFolder( | ||
375 | m_scene.InventoryService, giverSp.UUID, folderId, "f1", true); | ||
376 | |||
377 | GridInstantMessage receivedIm = null; | ||
378 | receiverClient.OnReceivedInstantMessage += im => receivedIm = im; | ||
379 | |||
380 | byte[] giveImBinaryBucket = new byte[17]; | ||
381 | giveImBinaryBucket[0] = (byte)AssetType.Folder; | ||
382 | byte[] itemIdBytes = folderId.GetBytes(); | ||
383 | Array.Copy(itemIdBytes, 0, giveImBinaryBucket, 1, itemIdBytes.Length); | ||
384 | |||
385 | GridInstantMessage giveIm | ||
386 | = new GridInstantMessage( | ||
387 | m_scene, | ||
388 | giverSp.UUID, | ||
389 | giverSp.Name, | ||
390 | receiverSp.UUID, | ||
391 | (byte)InstantMessageDialog.InventoryOffered, | ||
392 | false, | ||
393 | "inventory offered msg", | ||
394 | initialSessionId, | ||
395 | false, | ||
396 | Vector3.Zero, | ||
397 | giveImBinaryBucket, | ||
398 | true); | ||
399 | |||
400 | giverClient.HandleImprovedInstantMessage(giveIm); | ||
401 | |||
402 | // These details might not all be correct. | ||
403 | // Session ID is now the created item ID (!) | ||
404 | GridInstantMessage rejectIm | ||
405 | = new GridInstantMessage( | ||
406 | m_scene, | ||
407 | receiverSp.UUID, | ||
408 | receiverSp.Name, | ||
409 | giverSp.UUID, | ||
410 | (byte)InstantMessageDialog.InventoryDeclined, | ||
411 | false, | ||
412 | "inventory declined msg", | ||
413 | new UUID(receivedIm.imSessionID), | ||
414 | false, | ||
415 | Vector3.Zero, | ||
416 | null, | ||
417 | true); | ||
418 | |||
419 | receiverClient.HandleImprovedInstantMessage(rejectIm); | ||
420 | |||
421 | // Test for item remaining in the giver's inventory (here we assume a copy item) | ||
422 | // TODO: Test no-copy items. | ||
423 | InventoryFolderBase originalFolderAfterGive | ||
424 | = UserInventoryHelpers.GetInventoryFolder(m_scene.InventoryService, giverSp.UUID, "f1"); | ||
425 | |||
426 | Assert.That(originalFolderAfterGive, Is.Not.Null); | ||
427 | Assert.That(originalFolderAfterGive.ID, Is.EqualTo(originalFolder.ID)); | ||
428 | |||
429 | // Test for folder successfully making it into the receiver's inventory | ||
430 | InventoryFolderBase receivedFolder | ||
431 | = UserInventoryHelpers.GetInventoryFolder(m_scene.InventoryService, receiverSp.UUID, "Trash/f1"); | ||
432 | |||
433 | InventoryFolderBase trashFolder | ||
434 | = m_scene.InventoryService.GetFolderForType(receiverSp.UUID, AssetType.TrashFolder); | ||
435 | |||
436 | Assert.That(receivedFolder, Is.Not.Null); | ||
437 | Assert.That(receivedFolder.ID, Is.Not.EqualTo(originalFolder.ID)); | ||
438 | Assert.That(receivedFolder.ParentID, Is.EqualTo(trashFolder.ID)); | ||
439 | |||
440 | // Test that on a delete, item still exists and is accessible for the giver. | ||
441 | m_scene.InventoryService.PurgeFolder(trashFolder); | ||
442 | |||
443 | InventoryFolderBase originalFolderAfterDelete | ||
444 | = UserInventoryHelpers.GetInventoryFolder(m_scene.InventoryService, giverSp.UUID, "f1"); | ||
445 | |||
446 | Assert.That(originalFolderAfterDelete, Is.Not.Null); | ||
447 | } | ||
448 | } | ||
449 | } \ 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 0c64f19..c517a30 100644 --- a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs | |||
@@ -165,7 +165,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure | |||
165 | (uint)presence.AbsolutePosition.Y, | 165 | (uint)presence.AbsolutePosition.Y, |
166 | (uint)presence.AbsolutePosition.Z + 2); | 166 | (uint)presence.AbsolutePosition.Z + 2); |
167 | 167 | ||
168 | m_log.DebugFormat("TP invite with message {0}, type {1}", message, lureType); | 168 | m_log.DebugFormat("[LURE MODULE]: TP invite with message {0}, type {1}", message, lureType); |
169 | 169 | ||
170 | GridInstantMessage m; | 170 | GridInstantMessage m; |
171 | 171 | ||
diff --git a/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs index bf24030..2bb24ae 100644 --- a/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Profile/BasicProfileModule.cs | |||
@@ -57,6 +57,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Profile | |||
57 | 57 | ||
58 | public void Initialise(IConfigSource config) | 58 | public void Initialise(IConfigSource config) |
59 | { | 59 | { |
60 | if(config.Configs["UserProfiles"] != null) | ||
61 | return; | ||
62 | |||
60 | m_log.DebugFormat("[PROFILE MODULE]: Basic Profile Module enabled"); | 63 | m_log.DebugFormat("[PROFILE MODULE]: Basic Profile Module enabled"); |
61 | m_Enabled = true; | 64 | m_Enabled = true; |
62 | } | 65 | } |
diff --git a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs new file mode 100644 index 0000000..d359ebc --- /dev/null +++ b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs | |||
@@ -0,0 +1,1343 @@ | |||
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.IO; | ||
30 | using System.Text; | ||
31 | using System.Collections; | ||
32 | using System.Collections.Generic; | ||
33 | using System.Globalization; | ||
34 | using System.Net; | ||
35 | using System.Net.Sockets; | ||
36 | using System.Reflection; | ||
37 | using System.Xml; | ||
38 | using OpenMetaverse; | ||
39 | using OpenMetaverse.StructuredData; | ||
40 | using log4net; | ||
41 | using Nini.Config; | ||
42 | using Nwc.XmlRpc; | ||
43 | using OpenSim.Framework; | ||
44 | using OpenSim.Region.Framework.Interfaces; | ||
45 | using OpenSim.Region.Framework.Scenes; | ||
46 | using OpenSim.Services.Interfaces; | ||
47 | using Mono.Addins; | ||
48 | using OpenSim.Services.Connectors.Hypergrid; | ||
49 | |||
50 | namespace OpenSim.Region.OptionalModules.Avatar.UserProfiles | ||
51 | { | ||
52 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "UserProfilesModule")] | ||
53 | public class UserProfileModule : IProfileModule, INonSharedRegionModule | ||
54 | { | ||
55 | /// <summary> | ||
56 | /// Logging | ||
57 | /// </summary> | ||
58 | static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
59 | |||
60 | // The pair of Dictionaries are used to handle the switching of classified ads | ||
61 | // by maintaining a cache of classified id to creator id mappings and an interest | ||
62 | // count. The entries are removed when the interest count reaches 0. | ||
63 | Dictionary<UUID, UUID> m_classifiedCache = new Dictionary<UUID, UUID>(); | ||
64 | Dictionary<UUID, int> m_classifiedInterest = new Dictionary<UUID, int>(); | ||
65 | |||
66 | public Scene Scene | ||
67 | { | ||
68 | get; private set; | ||
69 | } | ||
70 | |||
71 | /// <summary> | ||
72 | /// Gets or sets the ConfigSource. | ||
73 | /// </summary> | ||
74 | /// <value> | ||
75 | /// The configuration | ||
76 | /// </value> | ||
77 | public IConfigSource Config { | ||
78 | get; | ||
79 | set; | ||
80 | } | ||
81 | |||
82 | /// <summary> | ||
83 | /// Gets or sets the URI to the profile server. | ||
84 | /// </summary> | ||
85 | /// <value> | ||
86 | /// The profile server URI. | ||
87 | /// </value> | ||
88 | public string ProfileServerUri { | ||
89 | get; | ||
90 | set; | ||
91 | } | ||
92 | |||
93 | IProfileModule ProfileModule | ||
94 | { | ||
95 | get; set; | ||
96 | } | ||
97 | |||
98 | IUserManagement UserManagementModule | ||
99 | { | ||
100 | get; set; | ||
101 | } | ||
102 | |||
103 | /// <summary> | ||
104 | /// Gets or sets a value indicating whether this | ||
105 | /// <see cref="OpenSim.Region.Coremodules.UserProfiles.UserProfileModule"/> is enabled. | ||
106 | /// </summary> | ||
107 | /// <value> | ||
108 | /// <c>true</c> if enabled; otherwise, <c>false</c>. | ||
109 | /// </value> | ||
110 | public bool Enabled { | ||
111 | get; | ||
112 | set; | ||
113 | } | ||
114 | |||
115 | #region IRegionModuleBase implementation | ||
116 | /// <summary> | ||
117 | /// This is called to initialize the region module. For shared modules, this is called exactly once, after | ||
118 | /// creating the single (shared) instance. For non-shared modules, this is called once on each instance, after | ||
119 | /// the instace for the region has been created. | ||
120 | /// </summary> | ||
121 | /// <param name='source'> | ||
122 | /// Source. | ||
123 | /// </param> | ||
124 | public void Initialise(IConfigSource source) | ||
125 | { | ||
126 | Config = source; | ||
127 | ReplaceableInterface = typeof(IProfileModule); | ||
128 | |||
129 | IConfig profileConfig = Config.Configs["UserProfiles"]; | ||
130 | |||
131 | if (profileConfig == null) | ||
132 | { | ||
133 | m_log.Debug("[PROFILES]: UserProfiles disabled, no configuration"); | ||
134 | Enabled = false; | ||
135 | return; | ||
136 | } | ||
137 | |||
138 | // If we find ProfileURL then we configure for FULL support | ||
139 | // else we setup for BASIC support | ||
140 | ProfileServerUri = profileConfig.GetString("ProfileServiceURL", ""); | ||
141 | if (ProfileServerUri == "") | ||
142 | { | ||
143 | Enabled = false; | ||
144 | return; | ||
145 | } | ||
146 | |||
147 | m_log.Debug("[PROFILES]: Full Profiles Enabled"); | ||
148 | ReplaceableInterface = null; | ||
149 | Enabled = true; | ||
150 | } | ||
151 | |||
152 | /// <summary> | ||
153 | /// Adds the region. | ||
154 | /// </summary> | ||
155 | /// <param name='scene'> | ||
156 | /// Scene. | ||
157 | /// </param> | ||
158 | public void AddRegion(Scene scene) | ||
159 | { | ||
160 | if(!Enabled) | ||
161 | return; | ||
162 | |||
163 | Scene = scene; | ||
164 | Scene.RegisterModuleInterface<IProfileModule>(this); | ||
165 | Scene.EventManager.OnNewClient += OnNewClient; | ||
166 | Scene.EventManager.OnMakeRootAgent += HandleOnMakeRootAgent; | ||
167 | |||
168 | UserManagementModule = Scene.RequestModuleInterface<IUserManagement>(); | ||
169 | } | ||
170 | |||
171 | void HandleOnMakeRootAgent (ScenePresence obj) | ||
172 | { | ||
173 | if(obj.PresenceType == PresenceType.Npc) | ||
174 | return; | ||
175 | |||
176 | Util.FireAndForget(delegate | ||
177 | { | ||
178 | GetImageAssets(((IScenePresence)obj).UUID); | ||
179 | }); | ||
180 | } | ||
181 | |||
182 | /// <summary> | ||
183 | /// Removes the region. | ||
184 | /// </summary> | ||
185 | /// <param name='scene'> | ||
186 | /// Scene. | ||
187 | /// </param> | ||
188 | public void RemoveRegion(Scene scene) | ||
189 | { | ||
190 | if(!Enabled) | ||
191 | return; | ||
192 | } | ||
193 | |||
194 | /// <summary> | ||
195 | /// This will be called once for every scene loaded. In a shared module this will be multiple times in one | ||
196 | /// instance, while a nonshared module instance will only be called once. This method is called after AddRegion | ||
197 | /// has been called in all modules for that scene, providing an opportunity to request another module's | ||
198 | /// interface, or hook an event from another module. | ||
199 | /// </summary> | ||
200 | /// <param name='scene'> | ||
201 | /// Scene. | ||
202 | /// </param> | ||
203 | public void RegionLoaded(Scene scene) | ||
204 | { | ||
205 | if(!Enabled) | ||
206 | return; | ||
207 | } | ||
208 | |||
209 | /// <summary> | ||
210 | /// If this returns non-null, it is the type of an interface that this module intends to register. This will | ||
211 | /// cause the loader to defer loading of this module until all other modules have been loaded. If no other | ||
212 | /// module has registered the interface by then, this module will be activated, else it will remain inactive, | ||
213 | /// letting the other module take over. This should return non-null ONLY in modules that are intended to be | ||
214 | /// easily replaceable, e.g. stub implementations that the developer expects to be replaced by third party | ||
215 | /// provided modules. | ||
216 | /// </summary> | ||
217 | /// <value> | ||
218 | /// The replaceable interface. | ||
219 | /// </value> | ||
220 | public Type ReplaceableInterface | ||
221 | { | ||
222 | get; private set; | ||
223 | } | ||
224 | |||
225 | /// <summary> | ||
226 | /// Called as the instance is closed. | ||
227 | /// </summary> | ||
228 | public void Close() | ||
229 | { | ||
230 | } | ||
231 | |||
232 | /// <value> | ||
233 | /// The name of the module | ||
234 | /// </value> | ||
235 | /// <summary> | ||
236 | /// Gets the module name. | ||
237 | /// </summary> | ||
238 | public string Name | ||
239 | { | ||
240 | get { return "UserProfileModule"; } | ||
241 | } | ||
242 | #endregion IRegionModuleBase implementation | ||
243 | |||
244 | #region Region Event Handlers | ||
245 | /// <summary> | ||
246 | /// Raises the new client event. | ||
247 | /// </summary> | ||
248 | /// <param name='client'> | ||
249 | /// Client. | ||
250 | /// </param> | ||
251 | void OnNewClient(IClientAPI client) | ||
252 | { | ||
253 | //Profile | ||
254 | client.OnRequestAvatarProperties += RequestAvatarProperties; | ||
255 | client.OnUpdateAvatarProperties += AvatarPropertiesUpdate; | ||
256 | client.OnAvatarInterestUpdate += AvatarInterestsUpdate; | ||
257 | |||
258 | // Classifieds | ||
259 | client.AddGenericPacketHandler("avatarclassifiedsrequest", ClassifiedsRequest); | ||
260 | client.OnClassifiedInfoUpdate += ClassifiedInfoUpdate; | ||
261 | client.OnClassifiedInfoRequest += ClassifiedInfoRequest; | ||
262 | client.OnClassifiedDelete += ClassifiedDelete; | ||
263 | |||
264 | // Picks | ||
265 | client.AddGenericPacketHandler("avatarpicksrequest", PicksRequest); | ||
266 | client.AddGenericPacketHandler("pickinforequest", PickInfoRequest); | ||
267 | client.OnPickInfoUpdate += PickInfoUpdate; | ||
268 | client.OnPickDelete += PickDelete; | ||
269 | |||
270 | // Notes | ||
271 | client.AddGenericPacketHandler("avatarnotesrequest", NotesRequest); | ||
272 | client.OnAvatarNotesUpdate += NotesUpdate; | ||
273 | } | ||
274 | #endregion Region Event Handlers | ||
275 | |||
276 | #region Classified | ||
277 | /// | ||
278 | /// <summary> | ||
279 | /// Handles the avatar classifieds request. | ||
280 | /// </summary> | ||
281 | /// <param name='sender'> | ||
282 | /// Sender. | ||
283 | /// </param> | ||
284 | /// <param name='method'> | ||
285 | /// Method. | ||
286 | /// </param> | ||
287 | /// <param name='args'> | ||
288 | /// Arguments. | ||
289 | /// </param> | ||
290 | public void ClassifiedsRequest(Object sender, string method, List<String> args) | ||
291 | { | ||
292 | if (!(sender is IClientAPI)) | ||
293 | return; | ||
294 | |||
295 | IClientAPI remoteClient = (IClientAPI)sender; | ||
296 | |||
297 | UUID targetID; | ||
298 | UUID.TryParse(args[0], out targetID); | ||
299 | |||
300 | // Can't handle NPC yet... | ||
301 | ScenePresence p = FindPresence(targetID); | ||
302 | |||
303 | if (null != p) | ||
304 | { | ||
305 | if (p.PresenceType == PresenceType.Npc) | ||
306 | return; | ||
307 | } | ||
308 | |||
309 | string serverURI = string.Empty; | ||
310 | GetUserProfileServerURI(targetID, out serverURI); | ||
311 | UUID creatorId = UUID.Zero; | ||
312 | Dictionary<UUID, string> classifieds = new Dictionary<UUID, string>(); | ||
313 | |||
314 | OSDMap parameters= new OSDMap(); | ||
315 | UUID.TryParse(args[0], out creatorId); | ||
316 | parameters.Add("creatorId", OSD.FromUUID(creatorId)); | ||
317 | OSD Params = (OSD)parameters; | ||
318 | if(!JsonRpcRequest(ref Params, "avatarclassifiedsrequest", serverURI, UUID.Random().ToString())) | ||
319 | { | ||
320 | remoteClient.SendAvatarClassifiedReply(new UUID(args[0]), classifieds); | ||
321 | return; | ||
322 | } | ||
323 | |||
324 | parameters = (OSDMap)Params; | ||
325 | |||
326 | OSDArray list = (OSDArray)parameters["result"]; | ||
327 | |||
328 | |||
329 | foreach(OSD map in list) | ||
330 | { | ||
331 | OSDMap m = (OSDMap)map; | ||
332 | UUID cid = m["classifieduuid"].AsUUID(); | ||
333 | string name = m["name"].AsString(); | ||
334 | |||
335 | classifieds[cid] = name; | ||
336 | |||
337 | lock (m_classifiedCache) | ||
338 | { | ||
339 | if (!m_classifiedCache.ContainsKey(cid)) | ||
340 | { | ||
341 | m_classifiedCache.Add(cid,creatorId); | ||
342 | m_classifiedInterest.Add(cid, 0); | ||
343 | } | ||
344 | |||
345 | m_classifiedInterest[cid]++; | ||
346 | } | ||
347 | } | ||
348 | |||
349 | remoteClient.SendAvatarClassifiedReply(new UUID(args[0]), classifieds); | ||
350 | } | ||
351 | |||
352 | public void ClassifiedInfoRequest(UUID queryClassifiedID, IClientAPI remoteClient) | ||
353 | { | ||
354 | UUID target = remoteClient.AgentId; | ||
355 | UserClassifiedAdd ad = new UserClassifiedAdd(); | ||
356 | ad.ClassifiedId = queryClassifiedID; | ||
357 | |||
358 | lock (m_classifiedCache) | ||
359 | { | ||
360 | if (m_classifiedCache.ContainsKey(queryClassifiedID)) | ||
361 | { | ||
362 | target = m_classifiedCache[queryClassifiedID]; | ||
363 | |||
364 | m_classifiedInterest[queryClassifiedID] --; | ||
365 | |||
366 | if (m_classifiedInterest[queryClassifiedID] == 0) | ||
367 | { | ||
368 | m_classifiedInterest.Remove(queryClassifiedID); | ||
369 | m_classifiedCache.Remove(queryClassifiedID); | ||
370 | } | ||
371 | } | ||
372 | } | ||
373 | |||
374 | string serverURI = string.Empty; | ||
375 | GetUserProfileServerURI(target, out serverURI); | ||
376 | |||
377 | object Ad = (object)ad; | ||
378 | if(!JsonRpcRequest(ref Ad, "classifieds_info_query", serverURI, UUID.Random().ToString())) | ||
379 | { | ||
380 | remoteClient.SendAgentAlertMessage( | ||
381 | "Error getting classified info", false); | ||
382 | return; | ||
383 | } | ||
384 | ad = (UserClassifiedAdd) Ad; | ||
385 | |||
386 | if(ad.CreatorId == UUID.Zero) | ||
387 | return; | ||
388 | |||
389 | Vector3 globalPos = new Vector3(); | ||
390 | Vector3.TryParse(ad.GlobalPos, out globalPos); | ||
391 | |||
392 | remoteClient.SendClassifiedInfoReply(ad.ClassifiedId, ad.CreatorId, (uint)ad.CreationDate, (uint)ad.ExpirationDate, | ||
393 | (uint)ad.Category, ad.Name, ad.Description, ad.ParcelId, (uint)ad.ParentEstate, | ||
394 | ad.SnapshotId, ad.SimName, globalPos, ad.ParcelName, ad.Flags, ad.Price); | ||
395 | |||
396 | } | ||
397 | |||
398 | /// <summary> | ||
399 | /// Classifieds info update. | ||
400 | /// </summary> | ||
401 | /// <param name='queryclassifiedID'> | ||
402 | /// Queryclassified I. | ||
403 | /// </param> | ||
404 | /// <param name='queryCategory'> | ||
405 | /// Query category. | ||
406 | /// </param> | ||
407 | /// <param name='queryName'> | ||
408 | /// Query name. | ||
409 | /// </param> | ||
410 | /// <param name='queryDescription'> | ||
411 | /// Query description. | ||
412 | /// </param> | ||
413 | /// <param name='queryParcelID'> | ||
414 | /// Query parcel I. | ||
415 | /// </param> | ||
416 | /// <param name='queryParentEstate'> | ||
417 | /// Query parent estate. | ||
418 | /// </param> | ||
419 | /// <param name='querySnapshotID'> | ||
420 | /// Query snapshot I. | ||
421 | /// </param> | ||
422 | /// <param name='queryGlobalPos'> | ||
423 | /// Query global position. | ||
424 | /// </param> | ||
425 | /// <param name='queryclassifiedFlags'> | ||
426 | /// Queryclassified flags. | ||
427 | /// </param> | ||
428 | /// <param name='queryclassifiedPrice'> | ||
429 | /// Queryclassified price. | ||
430 | /// </param> | ||
431 | /// <param name='remoteClient'> | ||
432 | /// Remote client. | ||
433 | /// </param> | ||
434 | public void ClassifiedInfoUpdate(UUID queryclassifiedID, uint queryCategory, string queryName, string queryDescription, UUID queryParcelID, | ||
435 | uint queryParentEstate, UUID querySnapshotID, Vector3 queryGlobalPos, byte queryclassifiedFlags, | ||
436 | int queryclassifiedPrice, IClientAPI remoteClient) | ||
437 | { | ||
438 | UserClassifiedAdd ad = new UserClassifiedAdd(); | ||
439 | |||
440 | Scene s = (Scene) remoteClient.Scene; | ||
441 | Vector3 pos = remoteClient.SceneAgent.AbsolutePosition; | ||
442 | ILandObject land = s.LandChannel.GetLandObject(pos.X, pos.Y); | ||
443 | ScenePresence p = FindPresence(remoteClient.AgentId); | ||
444 | |||
445 | string serverURI = string.Empty; | ||
446 | GetUserProfileServerURI(remoteClient.AgentId, out serverURI); | ||
447 | |||
448 | if (land == null) | ||
449 | { | ||
450 | ad.ParcelName = string.Empty; | ||
451 | } | ||
452 | else | ||
453 | { | ||
454 | ad.ParcelName = land.LandData.Name; | ||
455 | } | ||
456 | |||
457 | ad.CreatorId = remoteClient.AgentId; | ||
458 | ad.ClassifiedId = queryclassifiedID; | ||
459 | ad.Category = Convert.ToInt32(queryCategory); | ||
460 | ad.Name = queryName; | ||
461 | ad.Description = queryDescription; | ||
462 | ad.ParentEstate = Convert.ToInt32(queryParentEstate); | ||
463 | ad.SnapshotId = querySnapshotID; | ||
464 | ad.SimName = remoteClient.Scene.RegionInfo.RegionName; | ||
465 | ad.GlobalPos = queryGlobalPos.ToString (); | ||
466 | ad.Flags = queryclassifiedFlags; | ||
467 | ad.Price = queryclassifiedPrice; | ||
468 | ad.ParcelId = p.currentParcelUUID; | ||
469 | |||
470 | object Ad = ad; | ||
471 | |||
472 | OSD.SerializeMembers(Ad); | ||
473 | |||
474 | if(!JsonRpcRequest(ref Ad, "classified_update", serverURI, UUID.Random().ToString())) | ||
475 | { | ||
476 | remoteClient.SendAgentAlertMessage( | ||
477 | "Error updating classified", false); | ||
478 | } | ||
479 | } | ||
480 | |||
481 | /// <summary> | ||
482 | /// Classifieds delete. | ||
483 | /// </summary> | ||
484 | /// <param name='queryClassifiedID'> | ||
485 | /// Query classified I. | ||
486 | /// </param> | ||
487 | /// <param name='remoteClient'> | ||
488 | /// Remote client. | ||
489 | /// </param> | ||
490 | public void ClassifiedDelete(UUID queryClassifiedID, IClientAPI remoteClient) | ||
491 | { | ||
492 | string serverURI = string.Empty; | ||
493 | GetUserProfileServerURI(remoteClient.AgentId, out serverURI); | ||
494 | |||
495 | UUID classifiedId; | ||
496 | OSDMap parameters= new OSDMap(); | ||
497 | UUID.TryParse(queryClassifiedID.ToString(), out classifiedId); | ||
498 | parameters.Add("classifiedId", OSD.FromUUID(classifiedId)); | ||
499 | OSD Params = (OSD)parameters; | ||
500 | if(!JsonRpcRequest(ref Params, "classified_delete", serverURI, UUID.Random().ToString())) | ||
501 | { | ||
502 | remoteClient.SendAgentAlertMessage( | ||
503 | "Error classified delete", false); | ||
504 | } | ||
505 | |||
506 | parameters = (OSDMap)Params; | ||
507 | } | ||
508 | #endregion Classified | ||
509 | |||
510 | #region Picks | ||
511 | /// <summary> | ||
512 | /// Handles the avatar picks request. | ||
513 | /// </summary> | ||
514 | /// <param name='sender'> | ||
515 | /// Sender. | ||
516 | /// </param> | ||
517 | /// <param name='method'> | ||
518 | /// Method. | ||
519 | /// </param> | ||
520 | /// <param name='args'> | ||
521 | /// Arguments. | ||
522 | /// </param> | ||
523 | public void PicksRequest(Object sender, string method, List<String> args) | ||
524 | { | ||
525 | if (!(sender is IClientAPI)) | ||
526 | return; | ||
527 | |||
528 | IClientAPI remoteClient = (IClientAPI)sender; | ||
529 | |||
530 | UUID targetId; | ||
531 | UUID.TryParse(args[0], out targetId); | ||
532 | |||
533 | // Can't handle NPC yet... | ||
534 | ScenePresence p = FindPresence(targetId); | ||
535 | |||
536 | if (null != p) | ||
537 | { | ||
538 | if (p.PresenceType == PresenceType.Npc) | ||
539 | return; | ||
540 | } | ||
541 | |||
542 | string serverURI = string.Empty; | ||
543 | GetUserProfileServerURI(targetId, out serverURI); | ||
544 | |||
545 | Dictionary<UUID, string> picks = new Dictionary<UUID, string>(); | ||
546 | |||
547 | OSDMap parameters= new OSDMap(); | ||
548 | parameters.Add("creatorId", OSD.FromUUID(targetId)); | ||
549 | OSD Params = (OSD)parameters; | ||
550 | if(!JsonRpcRequest(ref Params, "avatarpicksrequest", serverURI, UUID.Random().ToString())) | ||
551 | { | ||
552 | remoteClient.SendAvatarPicksReply(new UUID(args[0]), picks); | ||
553 | return; | ||
554 | } | ||
555 | |||
556 | parameters = (OSDMap)Params; | ||
557 | |||
558 | OSDArray list = (OSDArray)parameters["result"]; | ||
559 | |||
560 | foreach(OSD map in list) | ||
561 | { | ||
562 | OSDMap m = (OSDMap)map; | ||
563 | UUID cid = m["pickuuid"].AsUUID(); | ||
564 | string name = m["name"].AsString(); | ||
565 | |||
566 | m_log.DebugFormat("[PROFILES]: PicksRequest {0}", name); | ||
567 | |||
568 | picks[cid] = name; | ||
569 | } | ||
570 | remoteClient.SendAvatarPicksReply(new UUID(args[0]), picks); | ||
571 | } | ||
572 | |||
573 | /// <summary> | ||
574 | /// Handles the pick info request. | ||
575 | /// </summary> | ||
576 | /// <param name='sender'> | ||
577 | /// Sender. | ||
578 | /// </param> | ||
579 | /// <param name='method'> | ||
580 | /// Method. | ||
581 | /// </param> | ||
582 | /// <param name='args'> | ||
583 | /// Arguments. | ||
584 | /// </param> | ||
585 | public void PickInfoRequest(Object sender, string method, List<String> args) | ||
586 | { | ||
587 | if (!(sender is IClientAPI)) | ||
588 | return; | ||
589 | |||
590 | UUID targetID; | ||
591 | UUID.TryParse(args[0], out targetID); | ||
592 | string serverURI = string.Empty; | ||
593 | GetUserProfileServerURI(targetID, out serverURI); | ||
594 | IClientAPI remoteClient = (IClientAPI)sender; | ||
595 | |||
596 | UserProfilePick pick = new UserProfilePick(); | ||
597 | UUID.TryParse(args[0], out pick.CreatorId); | ||
598 | UUID.TryParse(args[1], out pick.PickId); | ||
599 | |||
600 | |||
601 | object Pick = (object)pick; | ||
602 | if(!JsonRpcRequest(ref Pick, "pickinforequest", serverURI, UUID.Random().ToString())) | ||
603 | { | ||
604 | remoteClient.SendAgentAlertMessage( | ||
605 | "Error selecting pick", false); | ||
606 | } | ||
607 | pick = (UserProfilePick) Pick; | ||
608 | if(pick.SnapshotId == UUID.Zero) | ||
609 | { | ||
610 | // In case of a new UserPick, the data may not be ready and we would send wrong data, skip it... | ||
611 | m_log.DebugFormat("[PROFILES]: PickInfoRequest: SnapshotID is {0}", UUID.Zero.ToString()); | ||
612 | return; | ||
613 | } | ||
614 | |||
615 | Vector3 globalPos; | ||
616 | Vector3.TryParse(pick.GlobalPos,out globalPos); | ||
617 | |||
618 | m_log.DebugFormat("[PROFILES]: PickInfoRequest: {0} : {1}", pick.Name.ToString(), pick.SnapshotId.ToString()); | ||
619 | |||
620 | remoteClient.SendPickInfoReply(pick.PickId,pick.CreatorId,pick.TopPick,pick.ParcelId,pick.Name, | ||
621 | pick.Desc,pick.SnapshotId,pick.User,pick.OriginalName,pick.SimName, | ||
622 | globalPos,pick.SortOrder,pick.Enabled); | ||
623 | } | ||
624 | |||
625 | /// <summary> | ||
626 | /// Updates the userpicks | ||
627 | /// </summary> | ||
628 | /// <param name='remoteClient'> | ||
629 | /// Remote client. | ||
630 | /// </param> | ||
631 | /// <param name='pickID'> | ||
632 | /// Pick I. | ||
633 | /// </param> | ||
634 | /// <param name='creatorID'> | ||
635 | /// the creator of the pick | ||
636 | /// </param> | ||
637 | /// <param name='topPick'> | ||
638 | /// Top pick. | ||
639 | /// </param> | ||
640 | /// <param name='name'> | ||
641 | /// Name. | ||
642 | /// </param> | ||
643 | /// <param name='desc'> | ||
644 | /// Desc. | ||
645 | /// </param> | ||
646 | /// <param name='snapshotID'> | ||
647 | /// Snapshot I. | ||
648 | /// </param> | ||
649 | /// <param name='sortOrder'> | ||
650 | /// Sort order. | ||
651 | /// </param> | ||
652 | /// <param name='enabled'> | ||
653 | /// Enabled. | ||
654 | /// </param> | ||
655 | public void PickInfoUpdate(IClientAPI remoteClient, UUID pickID, UUID creatorID, bool topPick, string name, string desc, UUID snapshotID, int sortOrder, bool enabled) | ||
656 | { | ||
657 | |||
658 | m_log.DebugFormat("[PROFILES]: Start PickInfoUpdate Name: {0} PickId: {1} SnapshotId: {2}", name, pickID.ToString(), snapshotID.ToString()); | ||
659 | UserProfilePick pick = new UserProfilePick(); | ||
660 | string serverURI = string.Empty; | ||
661 | GetUserProfileServerURI(remoteClient.AgentId, out serverURI); | ||
662 | ScenePresence p = FindPresence(remoteClient.AgentId); | ||
663 | |||
664 | Vector3 avaPos = p.AbsolutePosition; | ||
665 | // Getting the global position for the Avatar | ||
666 | Vector3 posGlobal = new Vector3(remoteClient.Scene.RegionInfo.RegionLocX*Constants.RegionSize + avaPos.X, | ||
667 | remoteClient.Scene.RegionInfo.RegionLocY*Constants.RegionSize + avaPos.Y, | ||
668 | avaPos.Z); | ||
669 | |||
670 | string landOwnerName = string.Empty; | ||
671 | ILandObject land = p.Scene.LandChannel.GetLandObject(avaPos.X, avaPos.Y); | ||
672 | if(land.LandData.IsGroupOwned) | ||
673 | { | ||
674 | IGroupsModule groupMod = p.Scene.RequestModuleInterface<IGroupsModule>(); | ||
675 | UUID groupId = land.LandData.GroupID; | ||
676 | GroupRecord groupRecord = groupMod.GetGroupRecord(groupId); | ||
677 | landOwnerName = groupRecord.GroupName; | ||
678 | } | ||
679 | else | ||
680 | { | ||
681 | IUserAccountService accounts = p.Scene.RequestModuleInterface<IUserAccountService>(); | ||
682 | UserAccount user = accounts.GetUserAccount(p.Scene.RegionInfo.ScopeID, land.LandData.OwnerID); | ||
683 | landOwnerName = user.Name; | ||
684 | } | ||
685 | |||
686 | pick.PickId = pickID; | ||
687 | pick.CreatorId = creatorID; | ||
688 | pick.TopPick = topPick; | ||
689 | pick.Name = name; | ||
690 | pick.Desc = desc; | ||
691 | pick.ParcelId = p.currentParcelUUID; | ||
692 | pick.SnapshotId = snapshotID; | ||
693 | pick.User = landOwnerName; | ||
694 | pick.SimName = remoteClient.Scene.RegionInfo.RegionName; | ||
695 | pick.GlobalPos = posGlobal.ToString(); | ||
696 | pick.SortOrder = sortOrder; | ||
697 | pick.Enabled = enabled; | ||
698 | |||
699 | object Pick = (object)pick; | ||
700 | if(!JsonRpcRequest(ref Pick, "picks_update", serverURI, UUID.Random().ToString())) | ||
701 | { | ||
702 | remoteClient.SendAgentAlertMessage( | ||
703 | "Error updating pick", false); | ||
704 | } | ||
705 | |||
706 | m_log.DebugFormat("[PROFILES]: Finish PickInfoUpdate {0} {1}", pick.Name, pick.PickId.ToString()); | ||
707 | } | ||
708 | |||
709 | /// <summary> | ||
710 | /// Delete a Pick | ||
711 | /// </summary> | ||
712 | /// <param name='remoteClient'> | ||
713 | /// Remote client. | ||
714 | /// </param> | ||
715 | /// <param name='queryPickID'> | ||
716 | /// Query pick I. | ||
717 | /// </param> | ||
718 | public void PickDelete(IClientAPI remoteClient, UUID queryPickID) | ||
719 | { | ||
720 | string serverURI = string.Empty; | ||
721 | GetUserProfileServerURI(remoteClient.AgentId, out serverURI); | ||
722 | |||
723 | OSDMap parameters= new OSDMap(); | ||
724 | parameters.Add("pickId", OSD.FromUUID(queryPickID)); | ||
725 | OSD Params = (OSD)parameters; | ||
726 | if(!JsonRpcRequest(ref Params, "picks_delete", serverURI, UUID.Random().ToString())) | ||
727 | { | ||
728 | remoteClient.SendAgentAlertMessage( | ||
729 | "Error picks delete", false); | ||
730 | } | ||
731 | } | ||
732 | #endregion Picks | ||
733 | |||
734 | #region Notes | ||
735 | /// <summary> | ||
736 | /// Handles the avatar notes request. | ||
737 | /// </summary> | ||
738 | /// <param name='sender'> | ||
739 | /// Sender. | ||
740 | /// </param> | ||
741 | /// <param name='method'> | ||
742 | /// Method. | ||
743 | /// </param> | ||
744 | /// <param name='args'> | ||
745 | /// Arguments. | ||
746 | /// </param> | ||
747 | public void NotesRequest(Object sender, string method, List<String> args) | ||
748 | { | ||
749 | UserProfileNotes note = new UserProfileNotes(); | ||
750 | |||
751 | if (!(sender is IClientAPI)) | ||
752 | return; | ||
753 | |||
754 | IClientAPI remoteClient = (IClientAPI)sender; | ||
755 | string serverURI = string.Empty; | ||
756 | GetUserProfileServerURI(remoteClient.AgentId, out serverURI); | ||
757 | note.UserId = remoteClient.AgentId; | ||
758 | UUID.TryParse(args[0], out note.TargetId); | ||
759 | |||
760 | object Note = (object)note; | ||
761 | if(!JsonRpcRequest(ref Note, "avatarnotesrequest", serverURI, UUID.Random().ToString())) | ||
762 | { | ||
763 | remoteClient.SendAvatarNotesReply(note.TargetId, note.Notes); | ||
764 | return; | ||
765 | } | ||
766 | note = (UserProfileNotes) Note; | ||
767 | |||
768 | remoteClient.SendAvatarNotesReply(note.TargetId, note.Notes); | ||
769 | } | ||
770 | |||
771 | /// <summary> | ||
772 | /// Avatars the notes update. | ||
773 | /// </summary> | ||
774 | /// <param name='remoteClient'> | ||
775 | /// Remote client. | ||
776 | /// </param> | ||
777 | /// <param name='queryTargetID'> | ||
778 | /// Query target I. | ||
779 | /// </param> | ||
780 | /// <param name='queryNotes'> | ||
781 | /// Query notes. | ||
782 | /// </param> | ||
783 | public void NotesUpdate(IClientAPI remoteClient, UUID queryTargetID, string queryNotes) | ||
784 | { | ||
785 | UserProfileNotes note = new UserProfileNotes(); | ||
786 | |||
787 | note.UserId = remoteClient.AgentId; | ||
788 | note.TargetId = queryTargetID; | ||
789 | note.Notes = queryNotes; | ||
790 | |||
791 | string serverURI = string.Empty; | ||
792 | GetUserProfileServerURI(remoteClient.AgentId, out serverURI); | ||
793 | |||
794 | object Note = note; | ||
795 | if(!JsonRpcRequest(ref Note, "avatar_notes_update", serverURI, UUID.Random().ToString())) | ||
796 | { | ||
797 | return; | ||
798 | } | ||
799 | } | ||
800 | #endregion Notes | ||
801 | |||
802 | #region Avatar Properties | ||
803 | /// <summary> | ||
804 | /// Update the avatars interests . | ||
805 | /// </summary> | ||
806 | /// <param name='remoteClient'> | ||
807 | /// Remote client. | ||
808 | /// </param> | ||
809 | /// <param name='wantmask'> | ||
810 | /// Wantmask. | ||
811 | /// </param> | ||
812 | /// <param name='wanttext'> | ||
813 | /// Wanttext. | ||
814 | /// </param> | ||
815 | /// <param name='skillsmask'> | ||
816 | /// Skillsmask. | ||
817 | /// </param> | ||
818 | /// <param name='skillstext'> | ||
819 | /// Skillstext. | ||
820 | /// </param> | ||
821 | /// <param name='languages'> | ||
822 | /// Languages. | ||
823 | /// </param> | ||
824 | public void AvatarInterestsUpdate(IClientAPI remoteClient, uint wantmask, string wanttext, uint skillsmask, string skillstext, string languages) | ||
825 | { | ||
826 | UserProfileProperties prop = new UserProfileProperties(); | ||
827 | |||
828 | prop.UserId = remoteClient.AgentId; | ||
829 | prop.WantToMask = (int)wantmask; | ||
830 | prop.WantToText = wanttext; | ||
831 | prop.SkillsMask = (int)skillsmask; | ||
832 | prop.SkillsText = skillstext; | ||
833 | prop.Language = languages; | ||
834 | |||
835 | string serverURI = string.Empty; | ||
836 | GetUserProfileServerURI(remoteClient.AgentId, out serverURI); | ||
837 | |||
838 | object Param = prop; | ||
839 | if(!JsonRpcRequest(ref Param, "avatar_interests_update", serverURI, UUID.Random().ToString())) | ||
840 | { | ||
841 | remoteClient.SendAgentAlertMessage( | ||
842 | "Error updating interests", false); | ||
843 | } | ||
844 | } | ||
845 | |||
846 | public void RequestAvatarProperties(IClientAPI remoteClient, UUID avatarID) | ||
847 | { | ||
848 | if ( String.IsNullOrEmpty(avatarID.ToString()) || String.IsNullOrEmpty(remoteClient.AgentId.ToString())) | ||
849 | { | ||
850 | // Looking for a reason that some viewers are sending null Id's | ||
851 | m_log.DebugFormat("[PROFILES]: This should not happen remoteClient.AgentId {0} - avatarID {1}", remoteClient.AgentId, avatarID); | ||
852 | return; | ||
853 | } | ||
854 | |||
855 | // Can't handle NPC yet... | ||
856 | ScenePresence p = FindPresence(avatarID); | ||
857 | |||
858 | if (null != p) | ||
859 | { | ||
860 | if (p.PresenceType == PresenceType.Npc) | ||
861 | return; | ||
862 | } | ||
863 | |||
864 | string serverURI = string.Empty; | ||
865 | bool foreign = GetUserProfileServerURI(avatarID, out serverURI); | ||
866 | |||
867 | UserAccount account = null; | ||
868 | Dictionary<string,object> userInfo; | ||
869 | |||
870 | if (!foreign) | ||
871 | { | ||
872 | account = Scene.UserAccountService.GetUserAccount(Scene.RegionInfo.ScopeID, avatarID); | ||
873 | } | ||
874 | else | ||
875 | { | ||
876 | userInfo = new Dictionary<string, object>(); | ||
877 | } | ||
878 | |||
879 | Byte[] charterMember = new Byte[1]; | ||
880 | string born = String.Empty; | ||
881 | uint flags = 0x00; | ||
882 | |||
883 | if (null != account) | ||
884 | { | ||
885 | if (account.UserTitle == "") | ||
886 | { | ||
887 | charterMember[0] = (Byte)((account.UserFlags & 0xf00) >> 8); | ||
888 | } | ||
889 | else | ||
890 | { | ||
891 | charterMember = Utils.StringToBytes(account.UserTitle); | ||
892 | } | ||
893 | |||
894 | born = Util.ToDateTime(account.Created).ToString( | ||
895 | "M/d/yyyy", CultureInfo.InvariantCulture); | ||
896 | flags = (uint)(account.UserFlags & 0xff); | ||
897 | } | ||
898 | else | ||
899 | { | ||
900 | if (GetUserAccountData(avatarID, out userInfo) == true) | ||
901 | { | ||
902 | if ((string)userInfo["user_title"] == "") | ||
903 | { | ||
904 | charterMember[0] = (Byte)(((Byte)userInfo["user_flags"] & 0xf00) >> 8); | ||
905 | } | ||
906 | else | ||
907 | { | ||
908 | charterMember = Utils.StringToBytes((string)userInfo["user_title"]); | ||
909 | } | ||
910 | |||
911 | int val_born = (int)userInfo["user_created"]; | ||
912 | born = Util.ToDateTime(val_born).ToString( | ||
913 | "M/d/yyyy", CultureInfo.InvariantCulture); | ||
914 | |||
915 | // picky, picky | ||
916 | int val_flags = (int)userInfo["user_flags"]; | ||
917 | flags = (uint)(val_flags & 0xff); | ||
918 | } | ||
919 | } | ||
920 | |||
921 | UserProfileProperties props = new UserProfileProperties(); | ||
922 | string result = string.Empty; | ||
923 | |||
924 | props.UserId = avatarID; | ||
925 | GetProfileData(ref props, out result); | ||
926 | |||
927 | remoteClient.SendAvatarProperties(props.UserId, props.AboutText, born, charterMember , props.FirstLifeText, flags, | ||
928 | props.FirstLifeImageId, props.ImageId, props.WebUrl, props.PartnerId); | ||
929 | |||
930 | |||
931 | remoteClient.SendAvatarInterestsReply(props.UserId, (uint)props.WantToMask, props.WantToText, (uint)props.SkillsMask, | ||
932 | props.SkillsText, props.Language); | ||
933 | } | ||
934 | |||
935 | /// <summary> | ||
936 | /// Updates the avatar properties. | ||
937 | /// </summary> | ||
938 | /// <param name='remoteClient'> | ||
939 | /// Remote client. | ||
940 | /// </param> | ||
941 | /// <param name='newProfile'> | ||
942 | /// New profile. | ||
943 | /// </param> | ||
944 | public void AvatarPropertiesUpdate(IClientAPI remoteClient, UserProfileData newProfile) | ||
945 | { | ||
946 | if (remoteClient.AgentId == newProfile.ID) | ||
947 | { | ||
948 | UserProfileProperties prop = new UserProfileProperties(); | ||
949 | |||
950 | prop.UserId = remoteClient.AgentId; | ||
951 | prop.WebUrl = newProfile.ProfileUrl; | ||
952 | prop.ImageId = newProfile.Image; | ||
953 | prop.AboutText = newProfile.AboutText; | ||
954 | prop.FirstLifeImageId = newProfile.FirstLifeImage; | ||
955 | prop.FirstLifeText = newProfile.FirstLifeAboutText; | ||
956 | |||
957 | string serverURI = string.Empty; | ||
958 | GetUserProfileServerURI(remoteClient.AgentId, out serverURI); | ||
959 | |||
960 | object Prop = prop; | ||
961 | |||
962 | if(!JsonRpcRequest(ref Prop, "avatar_properties_update", serverURI, UUID.Random().ToString())) | ||
963 | { | ||
964 | remoteClient.SendAgentAlertMessage( | ||
965 | "Error updating properties", false); | ||
966 | } | ||
967 | |||
968 | RequestAvatarProperties(remoteClient, newProfile.ID); | ||
969 | } | ||
970 | } | ||
971 | |||
972 | /// <summary> | ||
973 | /// Gets the profile data. | ||
974 | /// </summary> | ||
975 | /// <returns> | ||
976 | /// The profile data. | ||
977 | /// </returns> | ||
978 | /// <param name='userID'> | ||
979 | /// User I. | ||
980 | /// </param> | ||
981 | bool GetProfileData(ref UserProfileProperties properties, out string message) | ||
982 | { | ||
983 | // Can't handle NPC yet... | ||
984 | ScenePresence p = FindPresence(properties.UserId); | ||
985 | |||
986 | if (null != p) | ||
987 | { | ||
988 | if (p.PresenceType == PresenceType.Npc) | ||
989 | { | ||
990 | message = "Id points to NPC"; | ||
991 | return false; | ||
992 | } | ||
993 | } | ||
994 | |||
995 | string serverURI = string.Empty; | ||
996 | GetUserProfileServerURI(properties.UserId, out serverURI); | ||
997 | |||
998 | // This is checking a friend on the home grid | ||
999 | // Not HG friend | ||
1000 | if ( String.IsNullOrEmpty(serverURI)) | ||
1001 | { | ||
1002 | message = "No Presence - foreign friend"; | ||
1003 | return false; | ||
1004 | } | ||
1005 | |||
1006 | object Prop = (object)properties; | ||
1007 | JsonRpcRequest(ref Prop, "avatar_properties_request", serverURI, UUID.Random().ToString()); | ||
1008 | properties = (UserProfileProperties)Prop; | ||
1009 | |||
1010 | message = "Success"; | ||
1011 | return true; | ||
1012 | } | ||
1013 | #endregion Avatar Properties | ||
1014 | |||
1015 | #region Utils | ||
1016 | bool GetImageAssets(UUID avatarId) | ||
1017 | { | ||
1018 | string profileServerURI = string.Empty; | ||
1019 | string assetServerURI = string.Empty; | ||
1020 | |||
1021 | bool foreign = GetUserProfileServerURI(avatarId, out profileServerURI); | ||
1022 | |||
1023 | if(!foreign) | ||
1024 | return true; | ||
1025 | |||
1026 | assetServerURI = UserManagementModule.GetUserServerURL(avatarId, "AssetServerURI"); | ||
1027 | |||
1028 | OSDMap parameters= new OSDMap(); | ||
1029 | parameters.Add("avatarId", OSD.FromUUID(avatarId)); | ||
1030 | OSD Params = (OSD)parameters; | ||
1031 | if(!JsonRpcRequest(ref Params, "image_assets_request", profileServerURI, UUID.Random().ToString())) | ||
1032 | { | ||
1033 | return false; | ||
1034 | } | ||
1035 | |||
1036 | parameters = (OSDMap)Params; | ||
1037 | |||
1038 | OSDArray list = (OSDArray)parameters["result"]; | ||
1039 | |||
1040 | foreach(OSD asset in list) | ||
1041 | { | ||
1042 | OSDString assetId = (OSDString)asset; | ||
1043 | |||
1044 | Scene.AssetService.Get(string.Format("{0}/{1}",assetServerURI, assetId.AsString())); | ||
1045 | } | ||
1046 | return true; | ||
1047 | } | ||
1048 | |||
1049 | /// <summary> | ||
1050 | /// Gets the user account data. | ||
1051 | /// </summary> | ||
1052 | /// <returns> | ||
1053 | /// The user profile data. | ||
1054 | /// </returns> | ||
1055 | /// <param name='userID'> | ||
1056 | /// If set to <c>true</c> user I. | ||
1057 | /// </param> | ||
1058 | /// <param name='userInfo'> | ||
1059 | /// If set to <c>true</c> user info. | ||
1060 | /// </param> | ||
1061 | bool GetUserAccountData(UUID userID, out Dictionary<string, object> userInfo) | ||
1062 | { | ||
1063 | Dictionary<string,object> info = new Dictionary<string, object>(); | ||
1064 | |||
1065 | if (UserManagementModule.IsLocalGridUser(userID)) | ||
1066 | { | ||
1067 | // Is local | ||
1068 | IUserAccountService uas = Scene.UserAccountService; | ||
1069 | UserAccount account = uas.GetUserAccount(Scene.RegionInfo.ScopeID, userID); | ||
1070 | |||
1071 | info["user_flags"] = account.UserFlags; | ||
1072 | info["user_created"] = account.Created; | ||
1073 | |||
1074 | if (!String.IsNullOrEmpty(account.UserTitle)) | ||
1075 | info["user_title"] = account.UserTitle; | ||
1076 | else | ||
1077 | info["user_title"] = ""; | ||
1078 | |||
1079 | userInfo = info; | ||
1080 | |||
1081 | return false; | ||
1082 | } | ||
1083 | else | ||
1084 | { | ||
1085 | // Is Foreign | ||
1086 | string home_url = UserManagementModule.GetUserServerURL(userID, "HomeURI"); | ||
1087 | |||
1088 | if (String.IsNullOrEmpty(home_url)) | ||
1089 | { | ||
1090 | info["user_flags"] = 0; | ||
1091 | info["user_created"] = 0; | ||
1092 | info["user_title"] = "Unavailable"; | ||
1093 | |||
1094 | userInfo = info; | ||
1095 | return true; | ||
1096 | } | ||
1097 | |||
1098 | UserAgentServiceConnector uConn = new UserAgentServiceConnector(home_url); | ||
1099 | |||
1100 | Dictionary<string, object> account = uConn.GetUserInfo(userID); | ||
1101 | |||
1102 | if (account.Count > 0) | ||
1103 | { | ||
1104 | if (account.ContainsKey("user_flags")) | ||
1105 | info["user_flags"] = account["user_flags"]; | ||
1106 | else | ||
1107 | info["user_flags"] = ""; | ||
1108 | |||
1109 | if (account.ContainsKey("user_created")) | ||
1110 | info["user_created"] = account["user_created"]; | ||
1111 | else | ||
1112 | info["user_created"] = ""; | ||
1113 | |||
1114 | info["user_title"] = "HG Visitor"; | ||
1115 | } | ||
1116 | else | ||
1117 | { | ||
1118 | info["user_flags"] = 0; | ||
1119 | info["user_created"] = 0; | ||
1120 | info["user_title"] = "HG Visitor"; | ||
1121 | } | ||
1122 | userInfo = info; | ||
1123 | return true; | ||
1124 | } | ||
1125 | } | ||
1126 | |||
1127 | /// <summary> | ||
1128 | /// Gets the user profile server UR. | ||
1129 | /// </summary> | ||
1130 | /// <returns> | ||
1131 | /// The user profile server UR. | ||
1132 | /// </returns> | ||
1133 | /// <param name='userID'> | ||
1134 | /// If set to <c>true</c> user I. | ||
1135 | /// </param> | ||
1136 | /// <param name='serverURI'> | ||
1137 | /// If set to <c>true</c> server UR. | ||
1138 | /// </param> | ||
1139 | bool GetUserProfileServerURI(UUID userID, out string serverURI) | ||
1140 | { | ||
1141 | bool local; | ||
1142 | local = UserManagementModule.IsLocalGridUser(userID); | ||
1143 | |||
1144 | if (!local) | ||
1145 | { | ||
1146 | serverURI = UserManagementModule.GetUserServerURL(userID, "ProfileServerURI"); | ||
1147 | // Is Foreign | ||
1148 | return true; | ||
1149 | } | ||
1150 | else | ||
1151 | { | ||
1152 | serverURI = ProfileServerUri; | ||
1153 | // Is local | ||
1154 | return false; | ||
1155 | } | ||
1156 | } | ||
1157 | |||
1158 | /// <summary> | ||
1159 | /// Finds the presence. | ||
1160 | /// </summary> | ||
1161 | /// <returns> | ||
1162 | /// The presence. | ||
1163 | /// </returns> | ||
1164 | /// <param name='clientID'> | ||
1165 | /// Client I. | ||
1166 | /// </param> | ||
1167 | ScenePresence FindPresence(UUID clientID) | ||
1168 | { | ||
1169 | ScenePresence p; | ||
1170 | |||
1171 | p = Scene.GetScenePresence(clientID); | ||
1172 | if (p != null && !p.IsChildAgent) | ||
1173 | return p; | ||
1174 | |||
1175 | return null; | ||
1176 | } | ||
1177 | #endregion Util | ||
1178 | |||
1179 | #region Web Util | ||
1180 | /// <summary> | ||
1181 | /// Sends json-rpc request with a serializable type. | ||
1182 | /// </summary> | ||
1183 | /// <returns> | ||
1184 | /// OSD Map. | ||
1185 | /// </returns> | ||
1186 | /// <param name='parameters'> | ||
1187 | /// Serializable type . | ||
1188 | /// </param> | ||
1189 | /// <param name='method'> | ||
1190 | /// Json-rpc method to call. | ||
1191 | /// </param> | ||
1192 | /// <param name='uri'> | ||
1193 | /// URI of json-rpc service. | ||
1194 | /// </param> | ||
1195 | /// <param name='jsonId'> | ||
1196 | /// Id for our call. | ||
1197 | /// </param> | ||
1198 | bool JsonRpcRequest(ref object parameters, string method, string uri, string jsonId) | ||
1199 | { | ||
1200 | if (jsonId == null) | ||
1201 | throw new ArgumentNullException ("jsonId"); | ||
1202 | if (uri == null) | ||
1203 | throw new ArgumentNullException ("uri"); | ||
1204 | if (method == null) | ||
1205 | throw new ArgumentNullException ("method"); | ||
1206 | if (parameters == null) | ||
1207 | throw new ArgumentNullException ("parameters"); | ||
1208 | |||
1209 | // Prep our payload | ||
1210 | OSDMap json = new OSDMap(); | ||
1211 | |||
1212 | json.Add("jsonrpc", OSD.FromString("2.0")); | ||
1213 | json.Add("id", OSD.FromString(jsonId)); | ||
1214 | json.Add("method", OSD.FromString(method)); | ||
1215 | |||
1216 | json.Add("params", OSD.SerializeMembers(parameters)); | ||
1217 | |||
1218 | string jsonRequestData = OSDParser.SerializeJsonString(json); | ||
1219 | byte[] content = Encoding.UTF8.GetBytes(jsonRequestData); | ||
1220 | |||
1221 | HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uri); | ||
1222 | |||
1223 | webRequest.ContentType = "application/json-rpc"; | ||
1224 | webRequest.Method = "POST"; | ||
1225 | |||
1226 | Stream dataStream = webRequest.GetRequestStream(); | ||
1227 | dataStream.Write(content, 0, content.Length); | ||
1228 | dataStream.Close(); | ||
1229 | |||
1230 | WebResponse webResponse = null; | ||
1231 | try | ||
1232 | { | ||
1233 | webResponse = webRequest.GetResponse(); | ||
1234 | } | ||
1235 | catch (WebException e) | ||
1236 | { | ||
1237 | Console.WriteLine("Web Error" + e.Message); | ||
1238 | Console.WriteLine ("Please check input"); | ||
1239 | return false; | ||
1240 | } | ||
1241 | |||
1242 | Stream rstream = webResponse.GetResponseStream(); | ||
1243 | |||
1244 | OSDMap mret = new OSDMap(); | ||
1245 | try | ||
1246 | { | ||
1247 | mret = (OSDMap)OSDParser.DeserializeJson(rstream); | ||
1248 | } | ||
1249 | catch (Exception e) | ||
1250 | { | ||
1251 | m_log.DebugFormat("[PROFILES]: JsonRpcRequest Error {0} - remote user with legacy profiles?", e.Message); | ||
1252 | return false; | ||
1253 | } | ||
1254 | |||
1255 | |||
1256 | if (mret.ContainsKey("error")) | ||
1257 | return false; | ||
1258 | |||
1259 | // get params... | ||
1260 | OSD.DeserializeMembers(ref parameters, (OSDMap) mret["result"]); | ||
1261 | return true; | ||
1262 | } | ||
1263 | |||
1264 | /// <summary> | ||
1265 | /// Sends json-rpc request with OSD parameter. | ||
1266 | /// </summary> | ||
1267 | /// <returns> | ||
1268 | /// The rpc request. | ||
1269 | /// </returns> | ||
1270 | /// <param name='data'> | ||
1271 | /// data - incoming as parameters, outgong as result/error | ||
1272 | /// </param> | ||
1273 | /// <param name='method'> | ||
1274 | /// Json-rpc method to call. | ||
1275 | /// </param> | ||
1276 | /// <param name='uri'> | ||
1277 | /// URI of json-rpc service. | ||
1278 | /// </param> | ||
1279 | /// <param name='jsonId'> | ||
1280 | /// If set to <c>true</c> json identifier. | ||
1281 | /// </param> | ||
1282 | bool JsonRpcRequest(ref OSD data, string method, string uri, string jsonId) | ||
1283 | { | ||
1284 | OSDMap map = new OSDMap(); | ||
1285 | |||
1286 | map["jsonrpc"] = "2.0"; | ||
1287 | if(string.IsNullOrEmpty(jsonId)) | ||
1288 | map["id"] = UUID.Random().ToString(); | ||
1289 | else | ||
1290 | map["id"] = jsonId; | ||
1291 | |||
1292 | map["method"] = method; | ||
1293 | map["params"] = data; | ||
1294 | |||
1295 | string jsonRequestData = OSDParser.SerializeJsonString(map); | ||
1296 | byte[] content = Encoding.UTF8.GetBytes(jsonRequestData); | ||
1297 | |||
1298 | HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uri); | ||
1299 | webRequest.ContentType = "application/json-rpc"; | ||
1300 | webRequest.Method = "POST"; | ||
1301 | |||
1302 | Stream dataStream = webRequest.GetRequestStream(); | ||
1303 | dataStream.Write(content, 0, content.Length); | ||
1304 | dataStream.Close(); | ||
1305 | |||
1306 | WebResponse webResponse = null; | ||
1307 | try | ||
1308 | { | ||
1309 | webResponse = webRequest.GetResponse(); | ||
1310 | } | ||
1311 | catch (WebException e) | ||
1312 | { | ||
1313 | Console.WriteLine("Web Error" + e.Message); | ||
1314 | Console.WriteLine ("Please check input"); | ||
1315 | return false; | ||
1316 | } | ||
1317 | |||
1318 | Stream rstream = webResponse.GetResponseStream(); | ||
1319 | |||
1320 | OSDMap response = new OSDMap(); | ||
1321 | try | ||
1322 | { | ||
1323 | response = (OSDMap)OSDParser.DeserializeJson(rstream); | ||
1324 | } | ||
1325 | catch (Exception e) | ||
1326 | { | ||
1327 | m_log.DebugFormat("[PROFILES]: JsonRpcRequest Error {0} - remote user with legacy profiles?", e.Message); | ||
1328 | return false; | ||
1329 | } | ||
1330 | |||
1331 | if(response.ContainsKey("error")) | ||
1332 | { | ||
1333 | data = response["error"]; | ||
1334 | return false; | ||
1335 | } | ||
1336 | |||
1337 | data = response; | ||
1338 | |||
1339 | return true; | ||
1340 | } | ||
1341 | #endregion Web Util | ||
1342 | } | ||
1343 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs index fff86d5..de8925d 100644 --- a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs +++ b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs | |||
@@ -28,6 +28,7 @@ | |||
28 | using System; | 28 | using System; |
29 | using System.Collections; | 29 | using System.Collections; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Linq; | ||
31 | using System.Reflection; | 32 | using System.Reflection; |
32 | using System.Text; | 33 | using System.Text; |
33 | using log4net; | 34 | using log4net; |
@@ -37,6 +38,7 @@ using OpenMetaverse; | |||
37 | using OpenSim.Framework; | 38 | using OpenSim.Framework; |
38 | using OpenSim.Framework.Console; | 39 | using OpenSim.Framework.Console; |
39 | using OpenSim.Framework.Servers; | 40 | using OpenSim.Framework.Servers; |
41 | using OpenSim.Framework.Servers.HttpServer; | ||
40 | using OpenSim.Region.Framework.Interfaces; | 42 | using OpenSim.Region.Framework.Interfaces; |
41 | using OpenSim.Region.Framework.Scenes; | 43 | using OpenSim.Region.Framework.Scenes; |
42 | using Caps=OpenSim.Framework.Capabilities.Caps; | 44 | using Caps=OpenSim.Framework.Capabilities.Caps; |
@@ -57,8 +59,9 @@ namespace OpenSim.Region.CoreModules.Framework | |||
57 | /// </summary> | 59 | /// </summary> |
58 | protected Dictionary<uint, Caps> m_capsObjects = new Dictionary<uint, Caps>(); | 60 | protected Dictionary<uint, Caps> m_capsObjects = new Dictionary<uint, Caps>(); |
59 | 61 | ||
60 | protected Dictionary<UUID, string> capsPaths = new Dictionary<UUID, string>(); | 62 | protected Dictionary<UUID, string> m_capsPaths = new Dictionary<UUID, string>(); |
61 | protected Dictionary<UUID, Dictionary<ulong, string>> childrenSeeds | 63 | |
64 | protected Dictionary<UUID, Dictionary<ulong, string>> m_childrenSeeds | ||
62 | = new Dictionary<UUID, Dictionary<ulong, string>>(); | 65 | = new Dictionary<UUID, Dictionary<ulong, string>>(); |
63 | 66 | ||
64 | public void Initialise(IConfigSource source) | 67 | public void Initialise(IConfigSource source) |
@@ -70,9 +73,24 @@ namespace OpenSim.Region.CoreModules.Framework | |||
70 | m_scene = scene; | 73 | m_scene = scene; |
71 | m_scene.RegisterModuleInterface<ICapabilitiesModule>(this); | 74 | m_scene.RegisterModuleInterface<ICapabilitiesModule>(this); |
72 | 75 | ||
73 | MainConsole.Instance.Commands.AddCommand("Comms", false, "show caps", | 76 | MainConsole.Instance.Commands.AddCommand( |
74 | "show caps", | 77 | "Comms", false, "show caps list", |
75 | "Shows all registered capabilities for users", HandleShowCapsCommand); | 78 | "show caps list", |
79 | "Shows list of registered capabilities for users.", HandleShowCapsListCommand); | ||
80 | |||
81 | MainConsole.Instance.Commands.AddCommand( | ||
82 | "Comms", false, "show caps stats by user", | ||
83 | "show caps stats by user [<first-name> <last-name>]", | ||
84 | "Shows statistics on capabilities use by user.", | ||
85 | "If a user name is given, then prints a detailed breakdown of caps use ordered by number of requests received.", | ||
86 | HandleShowCapsStatsByUserCommand); | ||
87 | |||
88 | MainConsole.Instance.Commands.AddCommand( | ||
89 | "Comms", false, "show caps stats by cap", | ||
90 | "show caps stats by cap [<cap-name>]", | ||
91 | "Shows statistics on capabilities use by capability.", | ||
92 | "If a capability name is given, then prints a detailed breakdown of use by each user.", | ||
93 | HandleShowCapsStatsByCapCommand); | ||
76 | } | 94 | } |
77 | 95 | ||
78 | public void RegionLoaded(Scene scene) | 96 | public void RegionLoaded(Scene scene) |
@@ -106,35 +124,38 @@ namespace OpenSim.Region.CoreModules.Framework | |||
106 | if (m_scene.RegionInfo.EstateSettings.IsBanned(agentId, flags)) | 124 | if (m_scene.RegionInfo.EstateSettings.IsBanned(agentId, flags)) |
107 | return; | 125 | return; |
108 | 126 | ||
127 | Caps caps; | ||
109 | String capsObjectPath = GetCapsPath(agentId); | 128 | String capsObjectPath = GetCapsPath(agentId); |
110 | 129 | ||
111 | if (m_capsObjects.ContainsKey(circuitCode)) | 130 | lock (m_capsObjects) |
112 | { | 131 | { |
113 | Caps oldCaps = m_capsObjects[circuitCode]; | 132 | if (m_capsObjects.ContainsKey(circuitCode)) |
114 | 133 | { | |
115 | m_log.DebugFormat( | 134 | Caps oldCaps = m_capsObjects[circuitCode]; |
116 | "[CAPS]: Recreating caps for agent {0}. Old caps path {1}, new caps path {2}. ", | 135 | |
117 | agentId, oldCaps.CapsObjectPath, capsObjectPath); | 136 | //m_log.WarnFormat( |
118 | // This should not happen. The caller code is confused. We need to fix that. | 137 | // "[CAPS]: Recreating caps for agent {0} in region {1}. Old caps path {2}, new caps path {3}. ", |
119 | // CAPs can never be reregistered, or the client will be confused. | 138 | // agentId, m_scene.RegionInfo.RegionName, oldCaps.CapsObjectPath, capsObjectPath); |
120 | // Hence this return here. | 139 | } |
121 | //return; | ||
122 | } | ||
123 | |||
124 | Caps caps = new Caps(MainServer.Instance, m_scene.RegionInfo.ExternalHostName, | ||
125 | (MainServer.Instance == null) ? 0: MainServer.Instance.Port, | ||
126 | capsObjectPath, agentId, m_scene.RegionInfo.RegionName); | ||
127 | 140 | ||
128 | m_capsObjects[circuitCode] = caps; | 141 | caps = new Caps(MainServer.Instance, m_scene.RegionInfo.ExternalHostName, |
142 | (MainServer.Instance == null) ? 0: MainServer.Instance.Port, | ||
143 | capsObjectPath, agentId, m_scene.RegionInfo.RegionName); | ||
129 | 144 | ||
145 | m_capsObjects[circuitCode] = caps; | ||
146 | } | ||
130 | m_scene.EventManager.TriggerOnRegisterCaps(agentId, caps); | 147 | m_scene.EventManager.TriggerOnRegisterCaps(agentId, caps); |
131 | } | 148 | } |
132 | 149 | ||
133 | public void RemoveCaps(UUID agentId, uint circuitCode) | 150 | public void RemoveCaps(UUID agentId, uint circuitCode) |
134 | { | 151 | { |
135 | if (childrenSeeds.ContainsKey(agentId)) | 152 | m_log.DebugFormat("[CAPS]: Remove caps for agent {0} in region {1}", agentId, m_scene.RegionInfo.RegionName); |
153 | lock (m_childrenSeeds) | ||
136 | { | 154 | { |
137 | childrenSeeds.Remove(agentId); | 155 | if (m_childrenSeeds.ContainsKey(agentId)) |
156 | { | ||
157 | m_childrenSeeds.Remove(agentId); | ||
158 | } | ||
138 | } | 159 | } |
139 | 160 | ||
140 | lock (m_capsObjects) | 161 | lock (m_capsObjects) |
@@ -180,16 +201,22 @@ namespace OpenSim.Region.CoreModules.Framework | |||
180 | 201 | ||
181 | public void SetAgentCapsSeeds(AgentCircuitData agent) | 202 | public void SetAgentCapsSeeds(AgentCircuitData agent) |
182 | { | 203 | { |
183 | capsPaths[agent.AgentID] = agent.CapsPath; | 204 | lock (m_capsPaths) |
184 | childrenSeeds[agent.AgentID] | 205 | m_capsPaths[agent.AgentID] = agent.CapsPath; |
185 | = ((agent.ChildrenCapSeeds == null) ? new Dictionary<ulong, string>() : agent.ChildrenCapSeeds); | 206 | |
207 | lock (m_childrenSeeds) | ||
208 | m_childrenSeeds[agent.AgentID] | ||
209 | = ((agent.ChildrenCapSeeds == null) ? new Dictionary<ulong, string>() : agent.ChildrenCapSeeds); | ||
186 | } | 210 | } |
187 | 211 | ||
188 | public string GetCapsPath(UUID agentId) | 212 | public string GetCapsPath(UUID agentId) |
189 | { | 213 | { |
190 | if (capsPaths.ContainsKey(agentId)) | 214 | lock (m_capsPaths) |
191 | { | 215 | { |
192 | return capsPaths[agentId]; | 216 | if (m_capsPaths.ContainsKey(agentId)) |
217 | { | ||
218 | return m_capsPaths[agentId]; | ||
219 | } | ||
193 | } | 220 | } |
194 | 221 | ||
195 | return null; | 222 | return null; |
@@ -198,17 +225,24 @@ namespace OpenSim.Region.CoreModules.Framework | |||
198 | public Dictionary<ulong, string> GetChildrenSeeds(UUID agentID) | 225 | public Dictionary<ulong, string> GetChildrenSeeds(UUID agentID) |
199 | { | 226 | { |
200 | Dictionary<ulong, string> seeds = null; | 227 | Dictionary<ulong, string> seeds = null; |
201 | if (childrenSeeds.TryGetValue(agentID, out seeds)) | 228 | |
202 | return seeds; | 229 | lock (m_childrenSeeds) |
230 | if (m_childrenSeeds.TryGetValue(agentID, out seeds)) | ||
231 | return seeds; | ||
232 | |||
203 | return new Dictionary<ulong, string>(); | 233 | return new Dictionary<ulong, string>(); |
204 | } | 234 | } |
205 | 235 | ||
206 | public void DropChildSeed(UUID agentID, ulong handle) | 236 | public void DropChildSeed(UUID agentID, ulong handle) |
207 | { | 237 | { |
208 | Dictionary<ulong, string> seeds; | 238 | Dictionary<ulong, string> seeds; |
209 | if (childrenSeeds.TryGetValue(agentID, out seeds)) | 239 | |
240 | lock (m_childrenSeeds) | ||
210 | { | 241 | { |
211 | seeds.Remove(handle); | 242 | if (m_childrenSeeds.TryGetValue(agentID, out seeds)) |
243 | { | ||
244 | seeds.Remove(handle); | ||
245 | } | ||
212 | } | 246 | } |
213 | } | 247 | } |
214 | 248 | ||
@@ -216,53 +250,339 @@ namespace OpenSim.Region.CoreModules.Framework | |||
216 | { | 250 | { |
217 | Dictionary<ulong, string> seeds; | 251 | Dictionary<ulong, string> seeds; |
218 | string returnval; | 252 | string returnval; |
219 | if (childrenSeeds.TryGetValue(agentID, out seeds)) | 253 | |
254 | lock (m_childrenSeeds) | ||
220 | { | 255 | { |
221 | if (seeds.TryGetValue(handle, out returnval)) | 256 | if (m_childrenSeeds.TryGetValue(agentID, out seeds)) |
222 | return returnval; | 257 | { |
258 | if (seeds.TryGetValue(handle, out returnval)) | ||
259 | return returnval; | ||
260 | } | ||
223 | } | 261 | } |
262 | |||
224 | return null; | 263 | return null; |
225 | } | 264 | } |
226 | 265 | ||
227 | public void SetChildrenSeed(UUID agentID, Dictionary<ulong, string> seeds) | 266 | public void SetChildrenSeed(UUID agentID, Dictionary<ulong, string> seeds) |
228 | { | 267 | { |
229 | //m_log.DebugFormat(" !!! Setting child seeds in {0} to {1}", m_scene.RegionInfo.RegionName, seeds.Count); | 268 | //m_log.DebugFormat(" !!! Setting child seeds in {0} to {1}", m_scene.RegionInfo.RegionName, seeds.Count); |
230 | childrenSeeds[agentID] = seeds; | 269 | |
270 | lock (m_childrenSeeds) | ||
271 | m_childrenSeeds[agentID] = seeds; | ||
231 | } | 272 | } |
232 | 273 | ||
233 | public void DumpChildrenSeeds(UUID agentID) | 274 | public void DumpChildrenSeeds(UUID agentID) |
234 | { | 275 | { |
235 | m_log.Info("================ ChildrenSeed "+m_scene.RegionInfo.RegionName+" ================"); | 276 | m_log.Info("================ ChildrenSeed "+m_scene.RegionInfo.RegionName+" ================"); |
236 | foreach (KeyValuePair<ulong, string> kvp in childrenSeeds[agentID]) | 277 | |
278 | lock (m_childrenSeeds) | ||
279 | { | ||
280 | foreach (KeyValuePair<ulong, string> kvp in m_childrenSeeds[agentID]) | ||
281 | { | ||
282 | uint x, y; | ||
283 | Utils.LongToUInts(kvp.Key, out x, out y); | ||
284 | x = x / Constants.RegionSize; | ||
285 | y = y / Constants.RegionSize; | ||
286 | m_log.Info(" >> "+x+", "+y+": "+kvp.Value); | ||
287 | } | ||
288 | } | ||
289 | } | ||
290 | |||
291 | private void HandleShowCapsListCommand(string module, string[] cmdParams) | ||
292 | { | ||
293 | if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene) | ||
294 | return; | ||
295 | |||
296 | StringBuilder capsReport = new StringBuilder(); | ||
297 | capsReport.AppendFormat("Region {0}:\n", m_scene.RegionInfo.RegionName); | ||
298 | |||
299 | lock (m_capsObjects) | ||
237 | { | 300 | { |
238 | uint x, y; | 301 | foreach (KeyValuePair<uint, Caps> kvp in m_capsObjects) |
239 | Utils.LongToUInts(kvp.Key, out x, out y); | 302 | { |
240 | x = x / Constants.RegionSize; | 303 | capsReport.AppendFormat("** Circuit {0}:\n", kvp.Key); |
241 | y = y / Constants.RegionSize; | 304 | Caps caps = kvp.Value; |
242 | m_log.Info(" >> "+x+", "+y+": "+kvp.Value); | 305 | |
306 | for (IDictionaryEnumerator kvp2 = caps.CapsHandlers.GetCapsDetails(false, null).GetEnumerator(); kvp2.MoveNext(); ) | ||
307 | { | ||
308 | Uri uri = new Uri(kvp2.Value.ToString()); | ||
309 | capsReport.AppendFormat(m_showCapsCommandFormat, kvp2.Key, uri.PathAndQuery); | ||
310 | } | ||
311 | |||
312 | foreach (KeyValuePair<string, PollServiceEventArgs> kvp2 in caps.GetPollHandlers()) | ||
313 | capsReport.AppendFormat(m_showCapsCommandFormat, kvp2.Key, kvp2.Value.Url); | ||
314 | |||
315 | foreach (KeyValuePair<string, string> kvp3 in caps.ExternalCapsHandlers) | ||
316 | capsReport.AppendFormat(m_showCapsCommandFormat, kvp3.Key, kvp3.Value); | ||
317 | } | ||
243 | } | 318 | } |
319 | |||
320 | MainConsole.Instance.Output(capsReport.ToString()); | ||
244 | } | 321 | } |
245 | 322 | ||
246 | private void HandleShowCapsCommand(string module, string[] cmdparams) | 323 | private void HandleShowCapsStatsByCapCommand(string module, string[] cmdParams) |
247 | { | 324 | { |
248 | StringBuilder caps = new StringBuilder(); | 325 | if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene) |
249 | caps.AppendFormat("Region {0}:\n", m_scene.RegionInfo.RegionName); | 326 | return; |
327 | |||
328 | if (cmdParams.Length != 5 && cmdParams.Length != 6) | ||
329 | { | ||
330 | MainConsole.Instance.Output("Usage: show caps stats by cap [<cap-name>]"); | ||
331 | return; | ||
332 | } | ||
333 | |||
334 | StringBuilder sb = new StringBuilder(); | ||
335 | sb.AppendFormat("Region {0}:\n", m_scene.Name); | ||
336 | |||
337 | if (cmdParams.Length == 5) | ||
338 | { | ||
339 | BuildSummaryStatsByCapReport(sb); | ||
340 | } | ||
341 | else if (cmdParams.Length == 6) | ||
342 | { | ||
343 | BuildDetailedStatsByCapReport(sb, cmdParams[5]); | ||
344 | } | ||
345 | |||
346 | MainConsole.Instance.Output(sb.ToString()); | ||
347 | } | ||
348 | |||
349 | private void BuildDetailedStatsByCapReport(StringBuilder sb, string capName) | ||
350 | { | ||
351 | /* | ||
352 | sb.AppendFormat("Capability name {0}\n", capName); | ||
353 | |||
354 | ConsoleDisplayTable cdt = new ConsoleDisplayTable(); | ||
355 | cdt.AddColumn("User Name", 34); | ||
356 | cdt.AddColumn("Req Received", 12); | ||
357 | cdt.AddColumn("Req Handled", 12); | ||
358 | cdt.Indent = 2; | ||
359 | |||
360 | Dictionary<string, int> receivedStats = new Dictionary<string, int>(); | ||
361 | Dictionary<string, int> handledStats = new Dictionary<string, int>(); | ||
362 | |||
363 | m_scene.ForEachScenePresence( | ||
364 | sp => | ||
365 | { | ||
366 | Caps caps = m_scene.CapsModule.GetCapsForUser(sp.UUID); | ||
250 | 367 | ||
251 | foreach (KeyValuePair<uint, Caps> kvp in m_capsObjects) | 368 | if (caps == null) |
369 | return; | ||
370 | |||
371 | Dictionary<string, IRequestHandler> capsHandlers = caps.CapsHandlers.GetCapsHandlers(); | ||
372 | |||
373 | IRequestHandler reqHandler; | ||
374 | if (capsHandlers.TryGetValue(capName, out reqHandler)) | ||
375 | { | ||
376 | receivedStats[sp.Name] = reqHandler.RequestsReceived; | ||
377 | handledStats[sp.Name] = reqHandler.RequestsHandled; | ||
378 | } | ||
379 | else | ||
380 | { | ||
381 | PollServiceEventArgs pollHandler = null; | ||
382 | if (caps.TryGetPollHandler(capName, out pollHandler)) | ||
383 | { | ||
384 | receivedStats[sp.Name] = pollHandler.RequestsReceived; | ||
385 | handledStats[sp.Name] = pollHandler.RequestsHandled; | ||
386 | } | ||
387 | } | ||
388 | } | ||
389 | ); | ||
390 | |||
391 | foreach (KeyValuePair<string, int> kvp in receivedStats.OrderByDescending(kp => kp.Value)) | ||
252 | { | 392 | { |
253 | caps.AppendFormat("** Circuit {0}:\n", kvp.Key); | 393 | cdt.AddRow(kvp.Key, kvp.Value, handledStats[kvp.Key]); |
394 | } | ||
395 | |||
396 | sb.Append(cdt.ToString()); | ||
397 | */ | ||
398 | } | ||
399 | |||
400 | private void BuildSummaryStatsByCapReport(StringBuilder sb) | ||
401 | { | ||
402 | /* | ||
403 | ConsoleDisplayTable cdt = new ConsoleDisplayTable(); | ||
404 | cdt.AddColumn("Name", 34); | ||
405 | cdt.AddColumn("Req Received", 12); | ||
406 | cdt.AddColumn("Req Handled", 12); | ||
407 | cdt.Indent = 2; | ||
408 | |||
409 | Dictionary<string, int> receivedStats = new Dictionary<string, int>(); | ||
410 | Dictionary<string, int> handledStats = new Dictionary<string, int>(); | ||
254 | 411 | ||
255 | for (IDictionaryEnumerator kvp2 = kvp.Value.CapsHandlers.GetCapsDetails(false, null).GetEnumerator(); kvp2.MoveNext(); ) | 412 | m_scene.ForEachScenePresence( |
413 | sp => | ||
256 | { | 414 | { |
257 | Uri uri = new Uri(kvp2.Value.ToString()); | 415 | Caps caps = m_scene.CapsModule.GetCapsForUser(sp.UUID); |
258 | caps.AppendFormat(m_showCapsCommandFormat, kvp2.Key, uri.PathAndQuery); | 416 | |
417 | if (caps == null) | ||
418 | return; | ||
419 | |||
420 | foreach (IRequestHandler reqHandler in caps.CapsHandlers.GetCapsHandlers().Values) | ||
421 | { | ||
422 | string reqName = reqHandler.Name ?? ""; | ||
423 | |||
424 | if (!receivedStats.ContainsKey(reqName)) | ||
425 | { | ||
426 | receivedStats[reqName] = reqHandler.RequestsReceived; | ||
427 | handledStats[reqName] = reqHandler.RequestsHandled; | ||
428 | } | ||
429 | else | ||
430 | { | ||
431 | receivedStats[reqName] += reqHandler.RequestsReceived; | ||
432 | handledStats[reqName] += reqHandler.RequestsHandled; | ||
433 | } | ||
434 | } | ||
435 | |||
436 | foreach (KeyValuePair<string, PollServiceEventArgs> kvp in caps.GetPollHandlers()) | ||
437 | { | ||
438 | string name = kvp.Key; | ||
439 | PollServiceEventArgs pollHandler = kvp.Value; | ||
440 | |||
441 | if (!receivedStats.ContainsKey(name)) | ||
442 | { | ||
443 | receivedStats[name] = pollHandler.RequestsReceived; | ||
444 | handledStats[name] = pollHandler.RequestsHandled; | ||
445 | } | ||
446 | else | ||
447 | { | ||
448 | receivedStats[name] += pollHandler.RequestsReceived; | ||
449 | handledStats[name] += pollHandler.RequestsHandled; | ||
450 | } | ||
451 | } | ||
259 | } | 452 | } |
453 | ); | ||
454 | |||
455 | foreach (KeyValuePair<string, int> kvp in receivedStats.OrderByDescending(kp => kp.Value)) | ||
456 | cdt.AddRow(kvp.Key, kvp.Value, handledStats[kvp.Key]); | ||
457 | |||
458 | sb.Append(cdt.ToString()); | ||
459 | */ | ||
460 | } | ||
461 | |||
462 | private void HandleShowCapsStatsByUserCommand(string module, string[] cmdParams) | ||
463 | { | ||
464 | /* | ||
465 | if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene) | ||
466 | return; | ||
467 | |||
468 | if (cmdParams.Length != 5 && cmdParams.Length != 7) | ||
469 | { | ||
470 | MainConsole.Instance.Output("Usage: show caps stats by user [<first-name> <last-name>]"); | ||
471 | return; | ||
472 | } | ||
473 | |||
474 | StringBuilder sb = new StringBuilder(); | ||
475 | sb.AppendFormat("Region {0}:\n", m_scene.Name); | ||
476 | |||
477 | if (cmdParams.Length == 5) | ||
478 | { | ||
479 | BuildSummaryStatsByUserReport(sb); | ||
480 | } | ||
481 | else if (cmdParams.Length == 7) | ||
482 | { | ||
483 | string firstName = cmdParams[5]; | ||
484 | string lastName = cmdParams[6]; | ||
485 | |||
486 | ScenePresence sp = m_scene.GetScenePresence(firstName, lastName); | ||
487 | |||
488 | if (sp == null) | ||
489 | return; | ||
260 | 490 | ||
261 | foreach (KeyValuePair<string, string> kvp3 in kvp.Value.ExternalCapsHandlers) | 491 | BuildDetailedStatsByUserReport(sb, sp); |
262 | caps.AppendFormat(m_showCapsCommandFormat, kvp3.Key, kvp3.Value); | ||
263 | } | 492 | } |
264 | 493 | ||
265 | MainConsole.Instance.Output(caps.ToString()); | 494 | MainConsole.Instance.Output(sb.ToString()); |
495 | */ | ||
496 | } | ||
497 | |||
498 | private void BuildDetailedStatsByUserReport(StringBuilder sb, ScenePresence sp) | ||
499 | { | ||
500 | /* | ||
501 | sb.AppendFormat("Avatar name {0}, type {1}\n", sp.Name, sp.IsChildAgent ? "child" : "root"); | ||
502 | |||
503 | ConsoleDisplayTable cdt = new ConsoleDisplayTable(); | ||
504 | cdt.AddColumn("Cap Name", 34); | ||
505 | cdt.AddColumn("Req Received", 12); | ||
506 | cdt.AddColumn("Req Handled", 12); | ||
507 | cdt.Indent = 2; | ||
508 | |||
509 | Caps caps = m_scene.CapsModule.GetCapsForUser(sp.UUID); | ||
510 | |||
511 | if (caps == null) | ||
512 | return; | ||
513 | |||
514 | List<CapTableRow> capRows = new List<CapTableRow>(); | ||
515 | |||
516 | foreach (IRequestHandler reqHandler in caps.CapsHandlers.GetCapsHandlers().Values) | ||
517 | capRows.Add(new CapTableRow(reqHandler.Name, reqHandler.RequestsReceived, reqHandler.RequestsHandled)); | ||
518 | |||
519 | foreach (KeyValuePair<string, PollServiceEventArgs> kvp in caps.GetPollHandlers()) | ||
520 | capRows.Add(new CapTableRow(kvp.Key, kvp.Value.RequestsReceived, kvp.Value.RequestsHandled)); | ||
521 | |||
522 | foreach (CapTableRow ctr in capRows.OrderByDescending(ctr => ctr.RequestsReceived)) | ||
523 | cdt.AddRow(ctr.Name, ctr.RequestsReceived, ctr.RequestsHandled); | ||
524 | |||
525 | sb.Append(cdt.ToString()); | ||
526 | */ | ||
527 | } | ||
528 | |||
529 | private void BuildSummaryStatsByUserReport(StringBuilder sb) | ||
530 | { | ||
531 | /* | ||
532 | ConsoleDisplayTable cdt = new ConsoleDisplayTable(); | ||
533 | cdt.AddColumn("Name", 32); | ||
534 | cdt.AddColumn("Type", 5); | ||
535 | cdt.AddColumn("Req Received", 12); | ||
536 | cdt.AddColumn("Req Handled", 12); | ||
537 | cdt.Indent = 2; | ||
538 | |||
539 | m_scene.ForEachScenePresence( | ||
540 | sp => | ||
541 | { | ||
542 | Caps caps = m_scene.CapsModule.GetCapsForUser(sp.UUID); | ||
543 | |||
544 | if (caps == null) | ||
545 | return; | ||
546 | |||
547 | Dictionary<string, IRequestHandler> capsHandlers = caps.CapsHandlers.GetCapsHandlers(); | ||
548 | |||
549 | int totalRequestsReceived = 0; | ||
550 | int totalRequestsHandled = 0; | ||
551 | |||
552 | foreach (IRequestHandler reqHandler in capsHandlers.Values) | ||
553 | { | ||
554 | totalRequestsReceived += reqHandler.RequestsReceived; | ||
555 | totalRequestsHandled += reqHandler.RequestsHandled; | ||
556 | } | ||
557 | |||
558 | Dictionary<string, PollServiceEventArgs> capsPollHandlers = caps.GetPollHandlers(); | ||
559 | |||
560 | foreach (PollServiceEventArgs handler in capsPollHandlers.Values) | ||
561 | { | ||
562 | totalRequestsReceived += handler.RequestsReceived; | ||
563 | totalRequestsHandled += handler.RequestsHandled; | ||
564 | } | ||
565 | |||
566 | cdt.AddRow(sp.Name, sp.IsChildAgent ? "child" : "root", totalRequestsReceived, totalRequestsHandled); | ||
567 | } | ||
568 | ); | ||
569 | |||
570 | sb.Append(cdt.ToString()); | ||
571 | */ | ||
572 | } | ||
573 | |||
574 | private class CapTableRow | ||
575 | { | ||
576 | public string Name { get; set; } | ||
577 | public int RequestsReceived { get; set; } | ||
578 | public int RequestsHandled { get; set; } | ||
579 | |||
580 | public CapTableRow(string name, int requestsReceived, int requestsHandled) | ||
581 | { | ||
582 | Name = name; | ||
583 | RequestsReceived = requestsReceived; | ||
584 | RequestsHandled = requestsHandled; | ||
585 | } | ||
266 | } | 586 | } |
267 | } | 587 | } |
268 | } | 588 | } |
diff --git a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs index 1f1568f..0c632b1 100644 --- a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs +++ b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DAExampleModule.cs | |||
@@ -44,11 +44,12 @@ namespace OpenSim.Region.CoreModules.Framework.DynamicAttributes.DAExampleModule | |||
44 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DAExampleModule")] | 44 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DAExampleModule")] |
45 | public class DAExampleModule : INonSharedRegionModule | 45 | public class DAExampleModule : INonSharedRegionModule |
46 | { | 46 | { |
47 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 47 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
48 | 48 | ||
49 | private static readonly bool ENABLED = false; // enable for testing | 49 | private readonly bool ENABLED = false; // enable for testing |
50 | 50 | ||
51 | public const string DANamespace = "DAExample Module"; | 51 | public const string Namespace = "Example"; |
52 | public const string StoreName = "DA"; | ||
52 | 53 | ||
53 | protected Scene m_scene; | 54 | protected Scene m_scene; |
54 | protected IDialogModule m_dialogMod; | 55 | protected IDialogModule m_dialogMod; |
@@ -65,6 +66,8 @@ namespace OpenSim.Region.CoreModules.Framework.DynamicAttributes.DAExampleModule | |||
65 | m_scene = scene; | 66 | m_scene = scene; |
66 | m_scene.EventManager.OnSceneGroupMove += OnSceneGroupMove; | 67 | m_scene.EventManager.OnSceneGroupMove += OnSceneGroupMove; |
67 | m_dialogMod = m_scene.RequestModuleInterface<IDialogModule>(); | 68 | m_dialogMod = m_scene.RequestModuleInterface<IDialogModule>(); |
69 | |||
70 | m_log.DebugFormat("[DA EXAMPLE MODULE]: Added region {0}", m_scene.Name); | ||
68 | } | 71 | } |
69 | } | 72 | } |
70 | 73 | ||
@@ -91,7 +94,7 @@ namespace OpenSim.Region.CoreModules.Framework.DynamicAttributes.DAExampleModule | |||
91 | if (sop == null) | 94 | if (sop == null) |
92 | return true; | 95 | return true; |
93 | 96 | ||
94 | if (!sop.DynAttrs.TryGetValue(DANamespace, out attrs)) | 97 | if (!sop.DynAttrs.TryGetStore(Namespace, StoreName, out attrs)) |
95 | attrs = new OSDMap(); | 98 | attrs = new OSDMap(); |
96 | 99 | ||
97 | OSDInteger newValue; | 100 | OSDInteger newValue; |
@@ -106,12 +109,14 @@ namespace OpenSim.Region.CoreModules.Framework.DynamicAttributes.DAExampleModule | |||
106 | 109 | ||
107 | attrs["moves"] = newValue; | 110 | attrs["moves"] = newValue; |
108 | 111 | ||
109 | sop.DynAttrs[DANamespace] = attrs; | 112 | sop.DynAttrs.SetStore(Namespace, StoreName, attrs); |
110 | } | 113 | } |
111 | 114 | ||
112 | sop.ParentGroup.HasGroupChanged = true; | 115 | sop.ParentGroup.HasGroupChanged = true; |
113 | 116 | ||
114 | m_dialogMod.SendGeneralAlert(string.Format("{0} {1} moved {2} times", sop.Name, sop.UUID, newValue)); | 117 | string msg = string.Format("{0} {1} moved {2} times", sop.Name, sop.UUID, newValue); |
118 | m_log.DebugFormat("[DA EXAMPLE MODULE]: {0}", msg); | ||
119 | m_dialogMod.SendGeneralAlert(msg); | ||
115 | 120 | ||
116 | return true; | 121 | return true; |
117 | } | 122 | } |
diff --git a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs index 650aa35..166a994 100644 --- a/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs +++ b/OpenSim/Region/CoreModules/Framework/DynamicAttributes/DOExampleModule.cs | |||
@@ -64,8 +64,8 @@ namespace OpenSim.Region.Framework.DynamicAttributes.DOExampleModule | |||
64 | 64 | ||
65 | private Scene m_scene; | 65 | private Scene m_scene; |
66 | private IDialogModule m_dialogMod; | 66 | private IDialogModule m_dialogMod; |
67 | 67 | ||
68 | public string Name { get { return "DOExample Module"; } } | 68 | public string Name { get { return "DO"; } } |
69 | public Type ReplaceableInterface { get { return null; } } | 69 | public Type ReplaceableInterface { get { return null; } } |
70 | 70 | ||
71 | public void Initialise(IConfigSource source) {} | 71 | public void Initialise(IConfigSource source) {} |
@@ -106,7 +106,7 @@ namespace OpenSim.Region.Framework.DynamicAttributes.DOExampleModule | |||
106 | 106 | ||
107 | // Console.WriteLine("Here for {0}", so.Name); | 107 | // Console.WriteLine("Here for {0}", so.Name); |
108 | 108 | ||
109 | if (rootPart.DynAttrs.TryGetValue(DAExampleModule.DANamespace, out attrs)) | 109 | if (rootPart.DynAttrs.TryGetStore(DAExampleModule.Namespace, DAExampleModule.StoreName, out attrs)) |
110 | { | 110 | { |
111 | movesSoFar = attrs["moves"].AsInteger(); | 111 | movesSoFar = attrs["moves"].AsInteger(); |
112 | 112 | ||
@@ -114,7 +114,7 @@ namespace OpenSim.Region.Framework.DynamicAttributes.DOExampleModule | |||
114 | "[DO EXAMPLE MODULE]: Found saved moves {0} for {1} in {2}", movesSoFar, so.Name, m_scene.Name); | 114 | "[DO EXAMPLE MODULE]: Found saved moves {0} for {1} in {2}", movesSoFar, so.Name, m_scene.Name); |
115 | } | 115 | } |
116 | 116 | ||
117 | rootPart.DynObjs.Add(Name, new MyObject(movesSoFar)); | 117 | rootPart.DynObjs.Add(DAExampleModule.Namespace, Name, new MyObject(movesSoFar)); |
118 | } | 118 | } |
119 | 119 | ||
120 | private bool OnSceneGroupMove(UUID groupId, Vector3 delta) | 120 | private bool OnSceneGroupMove(UUID groupId, Vector3 delta) |
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index ed867b8..5fea0cf 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | |||
@@ -51,11 +51,19 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
51 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "EntityTransferModule")] | 51 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "EntityTransferModule")] |
52 | public class EntityTransferModule : INonSharedRegionModule, IEntityTransferModule | 52 | public class EntityTransferModule : INonSharedRegionModule, IEntityTransferModule |
53 | { | 53 | { |
54 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 54 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
55 | private static readonly string LogHeader = "[ENTITY TRANSFER MODULE]"; | ||
55 | 56 | ||
56 | public const int DefaultMaxTransferDistance = 4095; | 57 | public const int DefaultMaxTransferDistance = 4095; |
57 | public const bool WaitForAgentArrivedAtDestinationDefault = true; | 58 | public const bool WaitForAgentArrivedAtDestinationDefault = true; |
58 | 59 | ||
60 | public string OutgoingTransferVersionName { get; set; } | ||
61 | |||
62 | /// <summary> | ||
63 | /// Determine the maximum entity transfer version we will use for teleports. | ||
64 | /// </summary> | ||
65 | public float MaxOutgoingTransferVersion { get; set; } | ||
66 | |||
59 | /// <summary> | 67 | /// <summary> |
60 | /// The maximum distance, in standard region units (256m) that an agent is allowed to transfer. | 68 | /// The maximum distance, in standard region units (256m) that an agent is allowed to transfer. |
61 | /// </summary> | 69 | /// </summary> |
@@ -151,9 +159,39 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
151 | /// <param name="source"></param> | 159 | /// <param name="source"></param> |
152 | protected virtual void InitialiseCommon(IConfigSource source) | 160 | protected virtual void InitialiseCommon(IConfigSource source) |
153 | { | 161 | { |
162 | string transferVersionName = "SIMULATION"; | ||
163 | float maxTransferVersion = 0.2f; | ||
164 | |||
154 | IConfig transferConfig = source.Configs["EntityTransfer"]; | 165 | IConfig transferConfig = source.Configs["EntityTransfer"]; |
155 | if (transferConfig != null) | 166 | if (transferConfig != null) |
156 | { | 167 | { |
168 | string rawVersion | ||
169 | = transferConfig.GetString( | ||
170 | "MaxOutgoingTransferVersion", | ||
171 | string.Format("{0}/{1}", transferVersionName, maxTransferVersion)); | ||
172 | |||
173 | string[] rawVersionComponents = rawVersion.Split(new char[] { '/' }); | ||
174 | |||
175 | bool versionValid = false; | ||
176 | |||
177 | if (rawVersionComponents.Length >= 2) | ||
178 | versionValid = float.TryParse(rawVersionComponents[1], out maxTransferVersion); | ||
179 | |||
180 | if (!versionValid) | ||
181 | { | ||
182 | m_log.ErrorFormat( | ||
183 | "[ENTITY TRANSFER MODULE]: MaxOutgoingTransferVersion {0} is invalid, using {1}", | ||
184 | rawVersion, string.Format("{0}/{1}", transferVersionName, maxTransferVersion)); | ||
185 | } | ||
186 | else | ||
187 | { | ||
188 | transferVersionName = rawVersionComponents[0]; | ||
189 | |||
190 | m_log.InfoFormat( | ||
191 | "[ENTITY TRANSFER MODULE]: MaxOutgoingTransferVersion set to {0}", | ||
192 | string.Format("{0}/{1}", transferVersionName, maxTransferVersion)); | ||
193 | } | ||
194 | |||
157 | DisableInterRegionTeleportCancellation | 195 | DisableInterRegionTeleportCancellation |
158 | = transferConfig.GetBoolean("DisableInterRegionTeleportCancellation", false); | 196 | = transferConfig.GetBoolean("DisableInterRegionTeleportCancellation", false); |
159 | 197 | ||
@@ -167,6 +205,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
167 | MaxTransferDistance = DefaultMaxTransferDistance; | 205 | MaxTransferDistance = DefaultMaxTransferDistance; |
168 | } | 206 | } |
169 | 207 | ||
208 | OutgoingTransferVersionName = transferVersionName; | ||
209 | MaxOutgoingTransferVersion = maxTransferVersion; | ||
210 | |||
170 | m_entityTransferStateMachine = new EntityTransferStateMachine(this); | 211 | m_entityTransferStateMachine = new EntityTransferStateMachine(this); |
171 | 212 | ||
172 | m_Enabled = true; | 213 | m_Enabled = true; |
@@ -280,10 +321,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
280 | 321 | ||
281 | private void OnConnectionClosed(IClientAPI client) | 322 | private void OnConnectionClosed(IClientAPI client) |
282 | { | 323 | { |
283 | if (client.IsLoggingOut) | 324 | if (client.IsLoggingOut && m_entityTransferStateMachine.UpdateInTransit(client.AgentId, AgentTransferState.Aborting)) |
284 | { | 325 | { |
285 | m_entityTransferStateMachine.UpdateInTransit(client.AgentId, AgentTransferState.Aborting); | ||
286 | |||
287 | m_log.DebugFormat( | 326 | m_log.DebugFormat( |
288 | "[ENTITY TRANSFER MODULE]: Aborted teleport request from {0} in {1} due to simultaneous logout", | 327 | "[ENTITY TRANSFER MODULE]: Aborted teleport request from {0} in {1} due to simultaneous logout", |
289 | client.Name, Scene.Name); | 328 | client.Name, Scene.Name); |
@@ -318,7 +357,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
318 | m_log.DebugFormat( | 357 | m_log.DebugFormat( |
319 | "[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2}@{3} - agent is already in transit.", | 358 | "[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2}@{3} - agent is already in transit.", |
320 | sp.Name, sp.UUID, position, regionHandle); | 359 | sp.Name, sp.UUID, position, regionHandle); |
321 | 360 | ||
361 | sp.ControllingClient.SendTeleportFailed("Previous teleport process incomplete. Please retry shortly."); | ||
362 | |||
322 | return; | 363 | return; |
323 | } | 364 | } |
324 | 365 | ||
@@ -522,6 +563,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
522 | /// </returns> | 563 | /// </returns> |
523 | private bool IsWithinMaxTeleportDistance(RegionInfo sourceRegion, GridRegion destRegion) | 564 | private bool IsWithinMaxTeleportDistance(RegionInfo sourceRegion, GridRegion destRegion) |
524 | { | 565 | { |
566 | if(MaxTransferDistance == 0) | ||
567 | return true; | ||
568 | |||
525 | // m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Source co-ords are x={0} y={1}", curRegionX, curRegionY); | 569 | // m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Source co-ords are x={0} y={1}", curRegionX, curRegionY); |
526 | // | 570 | // |
527 | // m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Final dest is x={0} y={1} {2}@{3}", | 571 | // m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Final dest is x={0} y={1} {2}@{3}", |
@@ -623,7 +667,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
623 | if (!sp.ValidateAttachments()) | 667 | if (!sp.ValidateAttachments()) |
624 | m_log.DebugFormat( | 668 | m_log.DebugFormat( |
625 | "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.", | 669 | "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.", |
626 | sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName); | 670 | sp.Name, sp.Scene.Name, finalDestination.RegionName); |
627 | 671 | ||
628 | string reason; | 672 | string reason; |
629 | string version; | 673 | string version; |
@@ -634,7 +678,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
634 | 678 | ||
635 | m_log.DebugFormat( | 679 | m_log.DebugFormat( |
636 | "[ENTITY TRANSFER MODULE]: {0} was stopped from teleporting from {1} to {2} because {3}", | 680 | "[ENTITY TRANSFER MODULE]: {0} was stopped from teleporting from {1} to {2} because {3}", |
637 | sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason); | 681 | sp.Name, sp.Scene.Name, finalDestination.RegionName, reason); |
638 | 682 | ||
639 | return; | 683 | return; |
640 | } | 684 | } |
@@ -644,7 +688,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
644 | // as server attempts. | 688 | // as server attempts. |
645 | m_interRegionTeleportAttempts.Value++; | 689 | m_interRegionTeleportAttempts.Value++; |
646 | 690 | ||
647 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version); | 691 | m_log.DebugFormat( |
692 | "[ENTITY TRANSFER MODULE]: {0} max transfer version is {1}/{2}, {3} max version is {4}", | ||
693 | sp.Scene.Name, OutgoingTransferVersionName, MaxOutgoingTransferVersion, finalDestination.RegionName, version); | ||
648 | 694 | ||
649 | // Fixing a bug where teleporting while sitting results in the avatar ending up removed from | 695 | // Fixing a bug where teleporting while sitting results in the avatar ending up removed from |
650 | // both regions | 696 | // both regions |
@@ -691,6 +737,29 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
691 | agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); | 737 | agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); |
692 | } | 738 | } |
693 | 739 | ||
740 | // We're going to fallback to V1 if the destination gives us anything smaller than 0.2 or we're forcing | ||
741 | // use of the earlier protocol | ||
742 | float versionNumber = 0.1f; | ||
743 | string[] versionComponents = version.Split(new char[] { '/' }); | ||
744 | if (versionComponents.Length >= 2) | ||
745 | float.TryParse(versionComponents[1], out versionNumber); | ||
746 | |||
747 | if (versionNumber == 0.2f && MaxOutgoingTransferVersion >= versionNumber) | ||
748 | TransferAgent_V2(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, oldRegionX, newRegionX, oldRegionY, newRegionY, version, out reason); | ||
749 | else | ||
750 | TransferAgent_V1(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, oldRegionX, newRegionX, oldRegionY, newRegionY, version, out reason); | ||
751 | } | ||
752 | |||
753 | private void TransferAgent_V1(ScenePresence sp, AgentCircuitData agentCircuit, GridRegion reg, GridRegion finalDestination, | ||
754 | IPEndPoint endPoint, uint teleportFlags, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, string version, out string reason) | ||
755 | { | ||
756 | ulong destinationHandle = finalDestination.RegionHandle; | ||
757 | AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); | ||
758 | |||
759 | m_log.DebugFormat( | ||
760 | "[ENTITY TRANSFER MODULE]: Using TP V1 for {0} going from {1} to {2}", | ||
761 | sp.Name, Scene.Name, finalDestination.RegionName); | ||
762 | |||
694 | // Let's create an agent there if one doesn't exist yet. | 763 | // Let's create an agent there if one doesn't exist yet. |
695 | // NOTE: logout will always be false for a non-HG teleport. | 764 | // NOTE: logout will always be false for a non-HG teleport. |
696 | bool logout = false; | 765 | bool logout = false; |
@@ -712,7 +781,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
712 | m_interRegionTeleportCancels.Value++; | 781 | m_interRegionTeleportCancels.Value++; |
713 | 782 | ||
714 | m_log.DebugFormat( | 783 | m_log.DebugFormat( |
715 | "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after CreateAgent on client request", | 784 | "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after CreateAgent on client request", |
716 | sp.Name, finalDestination.RegionName, sp.Scene.Name); | 785 | sp.Name, finalDestination.RegionName, sp.Scene.Name); |
717 | 786 | ||
718 | return; | 787 | return; |
@@ -734,11 +803,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
734 | // OK, it got this agent. Let's close some child agents | 803 | // OK, it got this agent. Let's close some child agents |
735 | sp.CloseChildAgents(newRegionX, newRegionY); | 804 | sp.CloseChildAgents(newRegionX, newRegionY); |
736 | 805 | ||
737 | IClientIPEndpoint ipepClient; | 806 | IClientIPEndpoint ipepClient; |
807 | string capsPath = String.Empty; | ||
738 | if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) | 808 | if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) |
739 | { | 809 | { |
740 | m_log.DebugFormat( | 810 | m_log.DebugFormat( |
741 | "[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} needs new child agent for incoming agent {3} from {4}", | 811 | "[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} needs new child agent for incoming agent {3} from {4}", |
742 | finalDestination.RegionName, newRegionX, newRegionY, sp.Name, Scene.Name); | 812 | finalDestination.RegionName, newRegionX, newRegionY, sp.Name, Scene.Name); |
743 | 813 | ||
744 | //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent..."); | 814 | //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent..."); |
@@ -756,7 +826,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
756 | // The EnableSimulator message makes the client establish a connection with the destination | 826 | // The EnableSimulator message makes the client establish a connection with the destination |
757 | // simulator by sending the initial UseCircuitCode UDP packet to the destination containing the | 827 | // simulator by sending the initial UseCircuitCode UDP packet to the destination containing the |
758 | // correct circuit code. | 828 | // correct circuit code. |
759 | m_eqModule.EnableSimulator(destinationHandle, endPoint, sp.UUID); | 829 | m_eqModule.EnableSimulator(destinationHandle, endPoint, sp.UUID, |
830 | finalDestination.RegionSizeX, finalDestination.RegionSizeY); | ||
831 | m_log.DebugFormat("{0} Sent EnableSimulator. regName={1}, size=<{2},{3}>", LogHeader, | ||
832 | finalDestination.RegionName, finalDestination.RegionSizeX, finalDestination.RegionSizeY); | ||
760 | 833 | ||
761 | // XXX: Is this wait necessary? We will always end up waiting on UpdateAgent for the destination | 834 | // XXX: Is this wait necessary? We will always end up waiting on UpdateAgent for the destination |
762 | // simulator to confirm that it has established communication with the viewer. | 835 | // simulator to confirm that it has established communication with the viewer. |
@@ -766,7 +839,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
766 | // unnecessary - teleport will succeed and SEED caps will be requested without it (though possibly | 839 | // unnecessary - teleport will succeed and SEED caps will be requested without it (though possibly |
767 | // only on TeleportFinish). This is untested for region teleport between different simulators | 840 | // only on TeleportFinish). This is untested for region teleport between different simulators |
768 | // though this probably also works. | 841 | // though this probably also works. |
769 | m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); | 842 | m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath, finalDestination.RegionHandle, |
843 | finalDestination.RegionSizeX, finalDestination.RegionSizeY); | ||
770 | } | 844 | } |
771 | else | 845 | else |
772 | { | 846 | { |
@@ -785,10 +859,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
785 | // Let's send a full update of the agent. This is a synchronous call. | 859 | // Let's send a full update of the agent. This is a synchronous call. |
786 | AgentData agent = new AgentData(); | 860 | AgentData agent = new AgentData(); |
787 | sp.CopyTo(agent); | 861 | sp.CopyTo(agent); |
788 | agent.Position = position; | 862 | agent.Position = agentCircuit.startpos; |
789 | SetCallbackURL(agent, sp.Scene.RegionInfo); | 863 | SetCallbackURL(agent, sp.Scene.RegionInfo); |
790 | 864 | ||
791 | //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent..."); | ||
792 | 865 | ||
793 | // We will check for an abort before UpdateAgent since UpdateAgent will require an active viewer to | 866 | // We will check for an abort before UpdateAgent since UpdateAgent will require an active viewer to |
794 | // establish th econnection to the destination which makes it return true. | 867 | // establish th econnection to the destination which makes it return true. |
@@ -821,10 +894,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
821 | } | 894 | } |
822 | 895 | ||
823 | m_log.WarnFormat( | 896 | m_log.WarnFormat( |
824 | "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Keeping avatar in source region.", | 897 | "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1}. Keeping avatar in {2}", |
825 | sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); | 898 | sp.Name, finalDestination.RegionName, sp.Scene.Name); |
826 | 899 | ||
827 | Fail(sp, finalDestination, logout, "Connection between viewer and destination region could not be established."); | 900 | Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Connection between viewer and destination region could not be established."); |
828 | return; | 901 | return; |
829 | } | 902 | } |
830 | 903 | ||
@@ -833,10 +906,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
833 | m_interRegionTeleportCancels.Value++; | 906 | m_interRegionTeleportCancels.Value++; |
834 | 907 | ||
835 | m_log.DebugFormat( | 908 | m_log.DebugFormat( |
836 | "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after UpdateAgent on client request", | 909 | "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after UpdateAgent on client request", |
837 | sp.Name, finalDestination.RegionName, sp.Scene.Name); | 910 | sp.Name, finalDestination.RegionName, sp.Scene.Name); |
838 | 911 | ||
839 | CleanupFailedInterRegionTeleport(sp, finalDestination); | 912 | CleanupFailedInterRegionTeleport(sp, currentAgentCircuit.SessionID.ToString(), finalDestination); |
840 | 913 | ||
841 | return; | 914 | return; |
842 | } | 915 | } |
@@ -850,9 +923,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
850 | // closes our existing agent which is still signalled as root. | 923 | // closes our existing agent which is still signalled as root. |
851 | sp.IsChildAgent = true; | 924 | sp.IsChildAgent = true; |
852 | 925 | ||
926 | // OK, send TPFinish to the client, so that it starts the process of contacting the destination region | ||
853 | if (m_eqModule != null) | 927 | if (m_eqModule != null) |
854 | { | 928 | { |
855 | m_eqModule.TeleportFinishEvent(destinationHandle, 13, endPoint, 0, teleportFlags, capsPath, sp.UUID); | 929 | m_eqModule.TeleportFinishEvent(destinationHandle, 13, endPoint, 0, teleportFlags, capsPath, sp.UUID, |
930 | finalDestination.RegionSizeX, finalDestination.RegionSizeY); | ||
856 | } | 931 | } |
857 | else | 932 | else |
858 | { | 933 | { |
@@ -879,8 +954,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
879 | m_log.WarnFormat( | 954 | m_log.WarnFormat( |
880 | "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.", | 955 | "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.", |
881 | sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); | 956 | sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); |
882 | 957 | ||
883 | Fail(sp, finalDestination, logout, "Destination region did not signal teleport completion."); | 958 | Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Destination region did not signal teleport completion."); |
884 | 959 | ||
885 | return; | 960 | return; |
886 | } | 961 | } |
@@ -908,15 +983,190 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
908 | 983 | ||
909 | if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) | 984 | if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) |
910 | { | 985 | { |
986 | if (!sp.Scene.IncomingPreCloseClient(sp)) | ||
987 | return; | ||
988 | |||
911 | // We need to delay here because Imprudence viewers, unlike v1 or v3, have a short (<200ms, <500ms) delay before | 989 | // We need to delay here because Imprudence viewers, unlike v1 or v3, have a short (<200ms, <500ms) delay before |
912 | // they regard the new region as the current region after receiving the AgentMovementComplete | 990 | // they regard the new region as the current region after receiving the AgentMovementComplete |
913 | // response. If close is sent before then, it will cause the viewer to quit instead. | 991 | // response. If close is sent before then, it will cause the viewer to quit instead. |
914 | // | 992 | // |
915 | // This sleep can be increased if necessary. However, whilst it's active, | 993 | // This sleep can be increased if necessary. However, whilst it's active, |
916 | // an agent cannot teleport back to this region if it has teleported away. | 994 | // an agent cannot teleport back to this region if it has teleported away. |
917 | Thread.Sleep(3000); | 995 | Thread.Sleep(2000); |
918 | 996 | ||
919 | sp.Scene.IncomingCloseAgent(sp.UUID, false); | 997 | sp.Scene.CloseAgent(sp.UUID, false); |
998 | } | ||
999 | else | ||
1000 | { | ||
1001 | // now we have a child agent in this region. | ||
1002 | sp.Reset(); | ||
1003 | } | ||
1004 | } | ||
1005 | |||
1006 | private void TransferAgent_V2(ScenePresence sp, AgentCircuitData agentCircuit, GridRegion reg, GridRegion finalDestination, | ||
1007 | IPEndPoint endPoint, uint teleportFlags, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, string version, out string reason) | ||
1008 | { | ||
1009 | ulong destinationHandle = finalDestination.RegionHandle; | ||
1010 | AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); | ||
1011 | |||
1012 | // Let's create an agent there if one doesn't exist yet. | ||
1013 | // NOTE: logout will always be false for a non-HG teleport. | ||
1014 | bool logout = false; | ||
1015 | if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout)) | ||
1016 | { | ||
1017 | m_interRegionTeleportFailures.Value++; | ||
1018 | |||
1019 | sp.ControllingClient.SendTeleportFailed(String.Format("Teleport refused: {0}", reason)); | ||
1020 | |||
1021 | m_log.DebugFormat( | ||
1022 | "[ENTITY TRANSFER MODULE]: Teleport of {0} from {1} to {2} was refused because {3}", | ||
1023 | sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason); | ||
1024 | |||
1025 | return; | ||
1026 | } | ||
1027 | |||
1028 | if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Cancelling) | ||
1029 | { | ||
1030 | m_interRegionTeleportCancels.Value++; | ||
1031 | |||
1032 | m_log.DebugFormat( | ||
1033 | "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after CreateAgent on client request", | ||
1034 | sp.Name, finalDestination.RegionName, sp.Scene.Name); | ||
1035 | |||
1036 | return; | ||
1037 | } | ||
1038 | else if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting) | ||
1039 | { | ||
1040 | m_interRegionTeleportAborts.Value++; | ||
1041 | |||
1042 | m_log.DebugFormat( | ||
1043 | "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after CreateAgent due to previous client close.", | ||
1044 | sp.Name, finalDestination.RegionName, sp.Scene.Name); | ||
1045 | |||
1046 | return; | ||
1047 | } | ||
1048 | |||
1049 | // Past this point we have to attempt clean up if the teleport fails, so update transfer state. | ||
1050 | m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); | ||
1051 | |||
1052 | IClientIPEndpoint ipepClient; | ||
1053 | string capsPath = String.Empty; | ||
1054 | if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) | ||
1055 | { | ||
1056 | m_log.DebugFormat( | ||
1057 | "[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} needs new child agent for agent {3} from {4}", | ||
1058 | finalDestination.RegionName, newRegionX, newRegionY, sp.Name, Scene.Name); | ||
1059 | |||
1060 | //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent..."); | ||
1061 | #region IP Translation for NAT | ||
1062 | // Uses ipepClient above | ||
1063 | if (sp.ClientView.TryGet(out ipepClient)) | ||
1064 | { | ||
1065 | endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); | ||
1066 | } | ||
1067 | #endregion | ||
1068 | capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); | ||
1069 | } | ||
1070 | else | ||
1071 | { | ||
1072 | agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle); | ||
1073 | capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); | ||
1074 | } | ||
1075 | |||
1076 | // We need to set this here to avoid an unlikely race condition when teleporting to a neighbour simulator, | ||
1077 | // where that neighbour simulator could otherwise request a child agent create on the source which then | ||
1078 | // closes our existing agent which is still signalled as root. | ||
1079 | //sp.IsChildAgent = true; | ||
1080 | |||
1081 | // New protocol: send TP Finish directly, without prior ES or EAC. That's what happens in the Linden grid | ||
1082 | if (m_eqModule != null) | ||
1083 | m_eqModule.TeleportFinishEvent(destinationHandle, 13, endPoint, 0, teleportFlags, capsPath, sp.UUID, | ||
1084 | finalDestination.RegionSizeX, finalDestination.RegionSizeY); | ||
1085 | else | ||
1086 | sp.ControllingClient.SendRegionTeleport(destinationHandle, 13, endPoint, 4, | ||
1087 | teleportFlags, capsPath); | ||
1088 | |||
1089 | m_log.DebugFormat( | ||
1090 | "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} from {1} to {2}", | ||
1091 | capsPath, sp.Scene.RegionInfo.RegionName, sp.Name); | ||
1092 | |||
1093 | // Let's send a full update of the agent. | ||
1094 | AgentData agent = new AgentData(); | ||
1095 | sp.CopyTo(agent); | ||
1096 | agent.Position = agentCircuit.startpos; | ||
1097 | agent.SenderWantsToWaitForRoot = true; | ||
1098 | //SetCallbackURL(agent, sp.Scene.RegionInfo); | ||
1099 | |||
1100 | // Reset the do not close flag. This must be done before the destination opens child connections (here | ||
1101 | // triggered by UpdateAgent) to avoid race conditions. However, we also want to reset it as late as possible | ||
1102 | // to avoid a situation where an unexpectedly early call to Scene.NewUserConnection() wrongly results | ||
1103 | // in no close. | ||
1104 | sp.DoNotCloseAfterTeleport = false; | ||
1105 | |||
1106 | // Send the Update. If this returns true, we know the client has contacted the destination | ||
1107 | // via CompleteMovementIntoRegion, so we can let go. | ||
1108 | // If it returns false, something went wrong, and we need to abort. | ||
1109 | if (!UpdateAgent(reg, finalDestination, agent, sp)) | ||
1110 | { | ||
1111 | if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting) | ||
1112 | { | ||
1113 | m_interRegionTeleportAborts.Value++; | ||
1114 | |||
1115 | m_log.DebugFormat( | ||
1116 | "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after UpdateAgent due to previous client close.", | ||
1117 | sp.Name, finalDestination.RegionName, sp.Scene.Name); | ||
1118 | |||
1119 | return; | ||
1120 | } | ||
1121 | |||
1122 | m_log.WarnFormat( | ||
1123 | "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1}. Keeping avatar in {2}", | ||
1124 | sp.Name, finalDestination.RegionName, sp.Scene.Name); | ||
1125 | |||
1126 | Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Connection between viewer and destination region could not be established."); | ||
1127 | return; | ||
1128 | } | ||
1129 | |||
1130 | m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); | ||
1131 | |||
1132 | // Need to signal neighbours whether child agents may need closing irrespective of whether this | ||
1133 | // one needed closing. We also need to close child agents as quickly as possible to avoid complicated | ||
1134 | // race conditions with rapid agent releporting (e.g. from A1 to a non-neighbour B, back | ||
1135 | // to a neighbour A2 then off to a non-neighbour C). Closing child agents any later requires complex | ||
1136 | // distributed checks to avoid problems in rapid reteleporting scenarios and where child agents are | ||
1137 | // abandoned without proper close by viewer but then re-used by an incoming connection. | ||
1138 | sp.CloseChildAgents(newRegionX, newRegionY); | ||
1139 | |||
1140 | // May need to logout or other cleanup | ||
1141 | AgentHasMovedAway(sp, logout); | ||
1142 | |||
1143 | // Well, this is it. The agent is over there. | ||
1144 | KillEntity(sp.Scene, sp.LocalId); | ||
1145 | |||
1146 | // Now let's make it officially a child agent | ||
1147 | sp.MakeChildAgent(); | ||
1148 | |||
1149 | // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone | ||
1150 | if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) | ||
1151 | { | ||
1152 | if (!sp.Scene.IncomingPreCloseClient(sp)) | ||
1153 | return; | ||
1154 | |||
1155 | // RED ALERT!!!! | ||
1156 | // PLEASE DO NOT DECREASE THIS WAIT TIME UNDER ANY CIRCUMSTANCES. | ||
1157 | // THE VIEWERS SEEM TO NEED SOME TIME AFTER RECEIVING MoveAgentIntoRegion | ||
1158 | // BEFORE THEY SETTLE IN THE NEW REGION. | ||
1159 | // DECREASING THE WAIT TIME HERE WILL EITHER RESULT IN A VIEWER CRASH OR | ||
1160 | // IN THE AVIE BEING PLACED IN INFINITY FOR A COUPLE OF SECONDS. | ||
1161 | Thread.Sleep(15000); | ||
1162 | |||
1163 | // OK, it got this agent. Let's close everything | ||
1164 | // If we shouldn't close the agent due to some other region renewing the connection | ||
1165 | // then this will be handled in IncomingCloseAgent under lock conditions | ||
1166 | m_log.DebugFormat( | ||
1167 | "[ENTITY TRANSFER MODULE]: Closing agent {0} in {1} after teleport", sp.Name, Scene.Name); | ||
1168 | |||
1169 | sp.Scene.CloseAgent(sp.UUID, false); | ||
920 | } | 1170 | } |
921 | else | 1171 | else |
922 | { | 1172 | { |
@@ -934,17 +1184,20 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
934 | /// <remarks> | 1184 | /// <remarks> |
935 | /// <param name='sp'> </param> | 1185 | /// <param name='sp'> </param> |
936 | /// <param name='finalDestination'></param> | 1186 | /// <param name='finalDestination'></param> |
937 | protected virtual void CleanupFailedInterRegionTeleport(ScenePresence sp, GridRegion finalDestination) | 1187 | protected virtual void CleanupFailedInterRegionTeleport(ScenePresence sp, string auth_token, GridRegion finalDestination) |
938 | { | 1188 | { |
939 | m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); | 1189 | m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); |
940 | 1190 | ||
941 | sp.IsChildAgent = false; | 1191 | if (sp.IsChildAgent) // We had set it to child before attempted TP (V1) |
942 | ReInstantiateScripts(sp); | 1192 | { |
943 | 1193 | sp.IsChildAgent = false; | |
944 | EnableChildAgents(sp); | 1194 | ReInstantiateScripts(sp); |
945 | 1195 | ||
1196 | EnableChildAgents(sp); | ||
1197 | } | ||
946 | // Finally, kill the agent we just created at the destination. | 1198 | // Finally, kill the agent we just created at the destination. |
947 | Scene.SimulationService.CloseAgent(finalDestination, sp.UUID); | 1199 | // XXX: Possibly this should be done asynchronously. |
1200 | Scene.SimulationService.CloseAgent(finalDestination, sp.UUID, auth_token); | ||
948 | } | 1201 | } |
949 | 1202 | ||
950 | /// <summary> | 1203 | /// <summary> |
@@ -954,9 +1207,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
954 | /// <param name='finalDestination'></param> | 1207 | /// <param name='finalDestination'></param> |
955 | /// <param name='logout'></param> | 1208 | /// <param name='logout'></param> |
956 | /// <param name='reason'>Human readable reason for teleport failure. Will be sent to client.</param> | 1209 | /// <param name='reason'>Human readable reason for teleport failure. Will be sent to client.</param> |
957 | protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout, string reason) | 1210 | protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout, string auth_code, string reason) |
958 | { | 1211 | { |
959 | CleanupFailedInterRegionTeleport(sp, finalDestination); | 1212 | CleanupFailedInterRegionTeleport(sp, auth_code, finalDestination); |
960 | 1213 | ||
961 | m_interRegionTeleportFailures.Value++; | 1214 | m_interRegionTeleportFailures.Value++; |
962 | 1215 | ||
@@ -1132,7 +1385,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1132 | public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos) | 1385 | public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos) |
1133 | { | 1386 | { |
1134 | version = String.Empty; | 1387 | version = String.Empty; |
1135 | newpos = new Vector3(pos.X, pos.Y, pos.Z); | 1388 | newpos = pos; |
1136 | 1389 | ||
1137 | // m_log.DebugFormat( | 1390 | // m_log.DebugFormat( |
1138 | // "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name); | 1391 | // "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name); |
@@ -1471,11 +1724,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1471 | if (m_eqModule != null) | 1724 | if (m_eqModule != null) |
1472 | { | 1725 | { |
1473 | m_eqModule.CrossRegion( | 1726 | m_eqModule.CrossRegion( |
1474 | neighbourRegion.RegionHandle, pos + agent.Velocity, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint, | 1727 | neighbourRegion.RegionHandle, pos + agent.Velocity, vel2 /* agent.Velocity */, |
1475 | capsPath, agent.UUID, agent.ControllingClient.SessionId); | 1728 | neighbourRegion.ExternalEndPoint, |
1729 | capsPath, agent.UUID, agent.ControllingClient.SessionId, | ||
1730 | neighbourRegion.RegionSizeX, neighbourRegion.RegionSizeY); | ||
1476 | } | 1731 | } |
1477 | else | 1732 | else |
1478 | { | 1733 | { |
1734 | m_log.ErrorFormat("{0} Using old CrossRegion packet. Varregion will not work!!", LogHeader); | ||
1479 | agent.ControllingClient.CrossRegion(neighbourRegion.RegionHandle, pos + agent.Velocity, agent.Velocity, neighbourRegion.ExternalEndPoint, | 1735 | agent.ControllingClient.CrossRegion(neighbourRegion.RegionHandle, pos + agent.Velocity, agent.Velocity, neighbourRegion.ExternalEndPoint, |
1480 | capsPath); | 1736 | capsPath); |
1481 | } | 1737 | } |
@@ -1654,10 +1910,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1654 | List<ulong> newRegions = NewNeighbours(neighbourHandles, previousRegionNeighbourHandles); | 1910 | List<ulong> newRegions = NewNeighbours(neighbourHandles, previousRegionNeighbourHandles); |
1655 | List<ulong> oldRegions = OldNeighbours(neighbourHandles, previousRegionNeighbourHandles); | 1911 | List<ulong> oldRegions = OldNeighbours(neighbourHandles, previousRegionNeighbourHandles); |
1656 | 1912 | ||
1657 | //Dump("Current Neighbors", neighbourHandles); | 1913 | // Dump("Current Neighbors", neighbourHandles); |
1658 | //Dump("Previous Neighbours", previousRegionNeighbourHandles); | 1914 | // Dump("Previous Neighbours", previousRegionNeighbourHandles); |
1659 | //Dump("New Neighbours", newRegions); | 1915 | // Dump("New Neighbours", newRegions); |
1660 | //Dump("Old Neighbours", oldRegions); | 1916 | // Dump("Old Neighbours", oldRegions); |
1661 | 1917 | ||
1662 | /// Update the scene presence's known regions here on this region | 1918 | /// Update the scene presence's known regions here on this region |
1663 | sp.DropOldNeighbours(oldRegions); | 1919 | sp.DropOldNeighbours(oldRegions); |
@@ -1665,8 +1921,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1665 | /// Collect as many seeds as possible | 1921 | /// Collect as many seeds as possible |
1666 | Dictionary<ulong, string> seeds; | 1922 | Dictionary<ulong, string> seeds; |
1667 | if (sp.Scene.CapsModule != null) | 1923 | if (sp.Scene.CapsModule != null) |
1668 | seeds | 1924 | seeds = new Dictionary<ulong, string>(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID)); |
1669 | = new Dictionary<ulong, string>(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID)); | ||
1670 | else | 1925 | else |
1671 | seeds = new Dictionary<ulong, string>(); | 1926 | seeds = new Dictionary<ulong, string>(); |
1672 | 1927 | ||
@@ -1736,6 +1991,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1736 | newAgent = true; | 1991 | newAgent = true; |
1737 | else | 1992 | else |
1738 | newAgent = false; | 1993 | newAgent = false; |
1994 | // continue; | ||
1739 | 1995 | ||
1740 | if (neighbour.RegionHandle != sp.Scene.RegionInfo.RegionHandle) | 1996 | if (neighbour.RegionHandle != sp.Scene.RegionInfo.RegionHandle) |
1741 | { | 1997 | { |
@@ -1841,12 +2097,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
1841 | } | 2097 | } |
1842 | #endregion | 2098 | #endregion |
1843 | 2099 | ||
1844 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: {0} is sending {1} EnableSimulator for neighbour region {2} @ {3} " + | 2100 | m_log.DebugFormat("{0} {1} is sending {2} EnableSimulator for neighbour region {3}(loc=<{4},{5}>,siz=<{6},{7}>) " + |
1845 | "and EstablishAgentCommunication with seed cap {4}", | 2101 | "and EstablishAgentCommunication with seed cap {8}", LogHeader, |
1846 | scene.RegionInfo.RegionName, sp.Name, reg.RegionName, reg.RegionHandle, capsPath); | 2102 | scene.RegionInfo.RegionName, sp.Name, |
2103 | reg.RegionName, reg.RegionLocX, reg.RegionLocY, reg.RegionSizeX, reg.RegionSizeY , capsPath); | ||
1847 | 2104 | ||
1848 | m_eqModule.EnableSimulator(reg.RegionHandle, endPoint, sp.UUID); | 2105 | m_eqModule.EnableSimulator(reg.RegionHandle, endPoint, sp.UUID, reg.RegionSizeX, reg.RegionSizeY); |
1849 | m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); | 2106 | m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath, reg.RegionHandle, reg.RegionSizeX, reg.RegionSizeY); |
1850 | } | 2107 | } |
1851 | else | 2108 | else |
1852 | { | 2109 | { |
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index d372c0e..7abdc21 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs | |||
@@ -53,8 +53,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
53 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 53 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
54 | 54 | ||
55 | private int m_levelHGTeleport = 0; | 55 | private int m_levelHGTeleport = 0; |
56 | private string m_ThisHomeURI; | ||
56 | 57 | ||
57 | private GatekeeperServiceConnector m_GatekeeperConnector; | 58 | private GatekeeperServiceConnector m_GatekeeperConnector; |
59 | private IUserAgentService m_UAS; | ||
58 | 60 | ||
59 | protected bool m_RestrictAppearanceAbroad; | 61 | protected bool m_RestrictAppearanceAbroad; |
60 | protected string m_AccountName; | 62 | protected string m_AccountName; |
@@ -143,6 +145,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
143 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: {0} enabled.", Name); | 145 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: {0} enabled.", Name); |
144 | } | 146 | } |
145 | } | 147 | } |
148 | |||
149 | moduleConfig = source.Configs["Hypergrid"]; | ||
150 | if (moduleConfig != null) | ||
151 | { | ||
152 | m_ThisHomeURI = moduleConfig.GetString("HomeURI", string.Empty); | ||
153 | if (m_ThisHomeURI != string.Empty && !m_ThisHomeURI.EndsWith("/")) | ||
154 | m_ThisHomeURI += '/'; | ||
155 | } | ||
146 | } | 156 | } |
147 | 157 | ||
148 | public override void AddRegion(Scene scene) | 158 | public override void AddRegion(Scene scene) |
@@ -161,22 +171,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
161 | if (!so.IsAttachment) | 171 | if (!so.IsAttachment) |
162 | return; | 172 | return; |
163 | 173 | ||
164 | if (so.Scene.UserManagementModule.IsLocalGridUser(so.AttachedAvatar)) | 174 | if (so.AttachedAvatar == UUID.Zero || Scene.UserManagementModule.IsLocalGridUser(so.AttachedAvatar)) |
165 | return; | 175 | return; |
166 | 176 | ||
167 | // foreign user | 177 | // foreign user |
168 | AgentCircuitData aCircuit = so.Scene.AuthenticateHandler.GetAgentCircuitData(so.AttachedAvatar); | 178 | AgentCircuitData aCircuit = Scene.AuthenticateHandler.GetAgentCircuitData(so.AttachedAvatar); |
169 | if (aCircuit != null && (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0) | 179 | if (aCircuit != null && (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0) |
170 | { | 180 | { |
171 | if (aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("AssetServerURI")) | 181 | if (aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("AssetServerURI")) |
172 | { | 182 | { |
173 | string url = aCircuit.ServiceURLs["AssetServerURI"].ToString(); | 183 | string url = aCircuit.ServiceURLs["AssetServerURI"].ToString(); |
174 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Incoming attachement {0} for HG user {1} with asset server {2}", so.Name, so.AttachedAvatar, url); | 184 | m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Incoming attachment {0} for HG user {1} with asset server {2}", so.Name, so.AttachedAvatar, url); |
175 | Dictionary<UUID, AssetType> ids = new Dictionary<UUID, AssetType>(); | 185 | Dictionary<UUID, sbyte> ids = new Dictionary<UUID, sbyte>(); |
176 | HGUuidGatherer uuidGatherer = new HGUuidGatherer(so.Scene.AssetService, url); | 186 | HGUuidGatherer uuidGatherer = new HGUuidGatherer(Scene.AssetService, url); |
177 | uuidGatherer.GatherAssetUuids(so, ids); | 187 | uuidGatherer.GatherAssetUuids(so, ids); |
178 | 188 | ||
179 | foreach (KeyValuePair<UUID, AssetType> kvp in ids) | 189 | foreach (KeyValuePair<UUID, sbyte> kvp in ids) |
180 | uuidGatherer.FetchAsset(kvp.Key); | 190 | uuidGatherer.FetchAsset(kvp.Key); |
181 | } | 191 | } |
182 | } | 192 | } |
@@ -194,7 +204,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
194 | base.RegionLoaded(scene); | 204 | base.RegionLoaded(scene); |
195 | 205 | ||
196 | if (m_Enabled) | 206 | if (m_Enabled) |
207 | { | ||
197 | m_GatekeeperConnector = new GatekeeperServiceConnector(scene.AssetService); | 208 | m_GatekeeperConnector = new GatekeeperServiceConnector(scene.AssetService); |
209 | m_UAS = scene.RequestModuleInterface<IUserAgentService>(); | ||
210 | if (m_UAS == null) | ||
211 | m_UAS = new UserAgentServiceConnector(m_ThisHomeURI); | ||
212 | |||
213 | } | ||
198 | } | 214 | } |
199 | 215 | ||
200 | public override void RemoveRegion(Scene scene) | 216 | public override void RemoveRegion(Scene scene) |
@@ -272,8 +288,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
272 | if (agentCircuit.ServiceURLs.ContainsKey("HomeURI")) | 288 | if (agentCircuit.ServiceURLs.ContainsKey("HomeURI")) |
273 | { | 289 | { |
274 | string userAgentDriver = agentCircuit.ServiceURLs["HomeURI"].ToString(); | 290 | string userAgentDriver = agentCircuit.ServiceURLs["HomeURI"].ToString(); |
275 | IUserAgentService connector = new UserAgentServiceConnector(userAgentDriver); | 291 | IUserAgentService connector; |
276 | bool success = connector.LoginAgentToGrid(agentCircuit, reg, finalDestination, out reason); | 292 | |
293 | if (userAgentDriver.Equals(m_ThisHomeURI) && m_UAS != null) | ||
294 | connector = m_UAS; | ||
295 | else | ||
296 | connector = new UserAgentServiceConnector(userAgentDriver); | ||
297 | |||
298 | bool success = connector.LoginAgentToGrid(agentCircuit, reg, finalDestination, false, out reason); | ||
277 | logout = success; // flag for later logout from this grid; this is an HG TP | 299 | logout = success; // flag for later logout from this grid; this is an HG TP |
278 | 300 | ||
279 | if (success) | 301 | if (success) |
@@ -552,12 +574,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
552 | if (uMan != null && uMan.IsLocalGridUser(obj.AgentId)) | 574 | if (uMan != null && uMan.IsLocalGridUser(obj.AgentId)) |
553 | { | 575 | { |
554 | // local grid user | 576 | // local grid user |
577 | m_UAS.LogoutAgent(obj.AgentId, obj.SessionId); | ||
555 | return; | 578 | return; |
556 | } | 579 | } |
557 | 580 | ||
558 | AgentCircuitData aCircuit = ((Scene)(obj.Scene)).AuthenticateHandler.GetAgentCircuitData(obj.CircuitCode); | 581 | AgentCircuitData aCircuit = ((Scene)(obj.Scene)).AuthenticateHandler.GetAgentCircuitData(obj.CircuitCode); |
559 | 582 | if (aCircuit != null && aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("HomeURI")) | |
560 | if (aCircuit.ServiceURLs.ContainsKey("HomeURI")) | ||
561 | { | 583 | { |
562 | string url = aCircuit.ServiceURLs["HomeURI"].ToString(); | 584 | string url = aCircuit.ServiceURLs["HomeURI"].ToString(); |
563 | IUserAgentService security = new UserAgentServiceConnector(url); | 585 | IUserAgentService security = new UserAgentServiceConnector(url); |
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs index 7871eda..d4fb1ba 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs | |||
@@ -73,6 +73,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
73 | 73 | ||
74 | private AssetMetadata FetchMetadata(string url, UUID assetID) | 74 | private AssetMetadata FetchMetadata(string url, UUID assetID) |
75 | { | 75 | { |
76 | if (string.IsNullOrEmpty(url)) | ||
77 | return null; | ||
78 | |||
76 | if (!url.EndsWith("/") && !url.EndsWith("=")) | 79 | if (!url.EndsWith("/") && !url.EndsWith("=")) |
77 | url = url + "/"; | 80 | url = url + "/"; |
78 | 81 | ||
@@ -92,6 +95,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
92 | AssetBase asset = m_scene.AssetService.Get(assetID.ToString()); | 95 | AssetBase asset = m_scene.AssetService.Get(assetID.ToString()); |
93 | if (asset == null) | 96 | if (asset == null) |
94 | { | 97 | { |
98 | if (string.IsNullOrEmpty(url)) | ||
99 | return null; | ||
100 | |||
95 | if (!url.EndsWith("/") && !url.EndsWith("=")) | 101 | if (!url.EndsWith("/") && !url.EndsWith("=")) |
96 | url = url + "/"; | 102 | url = url + "/"; |
97 | 103 | ||
@@ -109,6 +115,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
109 | 115 | ||
110 | public bool PostAsset(string url, AssetBase asset) | 116 | public bool PostAsset(string url, AssetBase asset) |
111 | { | 117 | { |
118 | if (string.IsNullOrEmpty(url)) | ||
119 | return false; | ||
120 | |||
112 | if (asset != null) | 121 | if (asset != null) |
113 | { | 122 | { |
114 | if (!url.EndsWith("/") && !url.EndsWith("=")) | 123 | if (!url.EndsWith("/") && !url.EndsWith("=")) |
@@ -165,7 +174,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
165 | 174 | ||
166 | private void AdjustIdentifiers(AssetMetadata meta) | 175 | private void AdjustIdentifiers(AssetMetadata meta) |
167 | { | 176 | { |
168 | if (meta.CreatorID != null && meta.CreatorID != string.Empty) | 177 | if (!string.IsNullOrEmpty(meta.CreatorID)) |
169 | { | 178 | { |
170 | UUID uuid = UUID.Zero; | 179 | UUID uuid = UUID.Zero; |
171 | UUID.TryParse(meta.CreatorID, out uuid); | 180 | UUID.TryParse(meta.CreatorID, out uuid); |
@@ -251,9 +260,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
251 | 260 | ||
252 | // The act of gathering UUIDs downloads some assets from the remote server | 261 | // The act of gathering UUIDs downloads some assets from the remote server |
253 | // but not all... | 262 | // but not all... |
254 | Dictionary<UUID, AssetType> ids = new Dictionary<UUID, AssetType>(); | 263 | Dictionary<UUID, sbyte> ids = new Dictionary<UUID, sbyte>(); |
255 | HGUuidGatherer uuidGatherer = new HGUuidGatherer(m_scene.AssetService, userAssetURL); | 264 | HGUuidGatherer uuidGatherer = new HGUuidGatherer(m_scene.AssetService, userAssetURL); |
256 | uuidGatherer.GatherAssetUuids(assetID, (AssetType)meta.Type, ids); | 265 | uuidGatherer.GatherAssetUuids(assetID, meta.Type, ids); |
257 | m_log.DebugFormat("[HG ASSET MAPPER]: Preparing to get {0} assets", ids.Count); | 266 | m_log.DebugFormat("[HG ASSET MAPPER]: Preparing to get {0} assets", ids.Count); |
258 | bool success = true; | 267 | bool success = true; |
259 | foreach (UUID uuid in ids.Keys) | 268 | foreach (UUID uuid in ids.Keys) |
@@ -277,9 +286,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
277 | AssetBase asset = m_scene.AssetService.Get(assetID.ToString()); | 286 | AssetBase asset = m_scene.AssetService.Get(assetID.ToString()); |
278 | if (asset != null) | 287 | if (asset != null) |
279 | { | 288 | { |
280 | Dictionary<UUID, AssetType> ids = new Dictionary<UUID, AssetType>(); | 289 | Dictionary<UUID, sbyte> ids = new Dictionary<UUID, sbyte>(); |
281 | HGUuidGatherer uuidGatherer = new HGUuidGatherer(m_scene.AssetService, string.Empty); | 290 | HGUuidGatherer uuidGatherer = new HGUuidGatherer(m_scene.AssetService, string.Empty); |
282 | uuidGatherer.GatherAssetUuids(asset.FullID, (AssetType)asset.Type, ids); | 291 | uuidGatherer.GatherAssetUuids(asset.FullID, asset.Type, ids); |
283 | bool success = false; | 292 | bool success = false; |
284 | foreach (UUID uuid in ids.Keys) | 293 | foreach (UUID uuid in ids.Keys) |
285 | { | 294 | { |
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs index b2b628d..ce7ed26 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs | |||
@@ -62,6 +62,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
62 | private string m_ThisGatekeeper; | 62 | private string m_ThisGatekeeper; |
63 | private bool m_RestrictInventoryAccessAbroad; | 63 | private bool m_RestrictInventoryAccessAbroad; |
64 | 64 | ||
65 | private bool m_bypassPermissions = true; | ||
66 | |||
65 | // private bool m_Initialized = false; | 67 | // private bool m_Initialized = false; |
66 | 68 | ||
67 | #region INonSharedRegionModule | 69 | #region INonSharedRegionModule |
@@ -100,6 +102,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
100 | } | 102 | } |
101 | else | 103 | else |
102 | m_log.Warn("[HG INVENTORY ACCESS MODULE]: HGInventoryAccessModule configs not found. ProfileServerURI not set!"); | 104 | m_log.Warn("[HG INVENTORY ACCESS MODULE]: HGInventoryAccessModule configs not found. ProfileServerURI not set!"); |
105 | |||
106 | m_bypassPermissions = !Util.GetConfigVarFromSections<bool>(source, "serverside_object_permissions", | ||
107 | new string[] { "Startup", "Permissions" }, true); | ||
108 | |||
103 | } | 109 | } |
104 | } | 110 | } |
105 | } | 111 | } |
@@ -114,6 +120,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
114 | scene.EventManager.OnNewInventoryItemUploadComplete += UploadInventoryItem; | 120 | scene.EventManager.OnNewInventoryItemUploadComplete += UploadInventoryItem; |
115 | scene.EventManager.OnTeleportStart += TeleportStart; | 121 | scene.EventManager.OnTeleportStart += TeleportStart; |
116 | scene.EventManager.OnTeleportFail += TeleportFail; | 122 | scene.EventManager.OnTeleportFail += TeleportFail; |
123 | |||
124 | // We're fgoing to enforce some stricter permissions if Outbound is false | ||
125 | scene.Permissions.OnTakeObject += CanTakeObject; | ||
126 | scene.Permissions.OnTakeCopyObject += CanTakeObject; | ||
127 | scene.Permissions.OnTransferUserInventory += OnTransferUserInventory; | ||
117 | } | 128 | } |
118 | 129 | ||
119 | #endregion | 130 | #endregion |
@@ -135,7 +146,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
135 | if (sp is ScenePresence) | 146 | if (sp is ScenePresence) |
136 | { | 147 | { |
137 | AgentCircuitData aCircuit = ((ScenePresence)sp).Scene.AuthenticateHandler.GetAgentCircuitData(client.AgentId); | 148 | AgentCircuitData aCircuit = ((ScenePresence)sp).Scene.AuthenticateHandler.GetAgentCircuitData(client.AgentId); |
138 | if ((aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0) | 149 | if (aCircuit != null && (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0) |
139 | { | 150 | { |
140 | if (m_RestrictInventoryAccessAbroad) | 151 | if (m_RestrictInventoryAccessAbroad) |
141 | { | 152 | { |
@@ -185,8 +196,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
185 | } | 196 | } |
186 | } | 197 | } |
187 | 198 | ||
188 | public void UploadInventoryItem(UUID avatarID, UUID assetID, string name, int userlevel) | 199 | public void UploadInventoryItem(UUID avatarID, AssetType type, UUID assetID, string name, int userlevel) |
189 | { | 200 | { |
201 | if (type == AssetType.Link) | ||
202 | return; | ||
203 | |||
190 | string userAssetServer = string.Empty; | 204 | string userAssetServer = string.Empty; |
191 | if (IsForeignUser(avatarID, out userAssetServer) && userAssetServer != string.Empty && m_OutboundPermission) | 205 | if (IsForeignUser(avatarID, out userAssetServer) && userAssetServer != string.Empty && m_OutboundPermission) |
192 | { | 206 | { |
@@ -221,7 +235,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
221 | { | 235 | { |
222 | UUID newAssetID = base.CapsUpdateInventoryItemAsset(remoteClient, itemID, data); | 236 | UUID newAssetID = base.CapsUpdateInventoryItemAsset(remoteClient, itemID, data); |
223 | 237 | ||
224 | UploadInventoryItem(remoteClient.AgentId, newAssetID, "", 0); | 238 | UploadInventoryItem(remoteClient.AgentId, AssetType.Unknown, newAssetID, "", 0); |
225 | 239 | ||
226 | return newAssetID; | 240 | return newAssetID; |
227 | } | 241 | } |
@@ -232,7 +246,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
232 | protected override void ExportAsset(UUID agentID, UUID assetID) | 246 | protected override void ExportAsset(UUID agentID, UUID assetID) |
233 | { | 247 | { |
234 | if (!assetID.Equals(UUID.Zero)) | 248 | if (!assetID.Equals(UUID.Zero)) |
235 | UploadInventoryItem(agentID, assetID, "", 0); | 249 | UploadInventoryItem(agentID, AssetType.Unknown, assetID, "", 0); |
236 | else | 250 | else |
237 | m_log.Debug("[HGScene]: Scene.Inventory did not create asset"); | 251 | m_log.Debug("[HGScene]: Scene.Inventory did not create asset"); |
238 | } | 252 | } |
@@ -244,7 +258,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
244 | UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, | 258 | UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, |
245 | bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) | 259 | bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) |
246 | { | 260 | { |
247 | m_log.DebugFormat("[HGScene] RezObject itemID={0} fromTaskID={1}", itemID, fromTaskID); | 261 | m_log.DebugFormat("[HGScene]: RezObject itemID={0} fromTaskID={1}", itemID, fromTaskID); |
248 | 262 | ||
249 | //if (fromTaskID.Equals(UUID.Zero)) | 263 | //if (fromTaskID.Equals(UUID.Zero)) |
250 | //{ | 264 | //{ |
@@ -297,7 +311,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
297 | if (m_Scene.TryGetScenePresence(userID, out sp)) | 311 | if (m_Scene.TryGetScenePresence(userID, out sp)) |
298 | { | 312 | { |
299 | AgentCircuitData aCircuit = m_Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); | 313 | AgentCircuitData aCircuit = m_Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); |
300 | if (aCircuit.ServiceURLs.ContainsKey("AssetServerURI")) | 314 | if (aCircuit != null && aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("AssetServerURI")) |
301 | { | 315 | { |
302 | assetServerURL = aCircuit.ServiceURLs["AssetServerURI"].ToString(); | 316 | assetServerURL = aCircuit.ServiceURLs["AssetServerURI"].ToString(); |
303 | assetServerURL = assetServerURL.Trim(new char[] { '/' }); | 317 | assetServerURL = assetServerURL.Trim(new char[] { '/' }); |
@@ -348,7 +362,15 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
348 | InventoryFolderBase root = m_Scene.InventoryService.GetRootFolder(client.AgentId); | 362 | InventoryFolderBase root = m_Scene.InventoryService.GetRootFolder(client.AgentId); |
349 | InventoryCollection content = m_Scene.InventoryService.GetFolderContent(client.AgentId, root.ID); | 363 | InventoryCollection content = m_Scene.InventoryService.GetFolderContent(client.AgentId, root.ID); |
350 | 364 | ||
351 | inv.SendBulkUpdateInventory(content.Folders.ToArray(), content.Items.ToArray()); | 365 | List<InventoryFolderBase> keep = new List<InventoryFolderBase>(); |
366 | |||
367 | foreach (InventoryFolderBase f in content.Folders) | ||
368 | { | ||
369 | if (f.Name != "My Suitcase" && f.Name != "Current Outfit") | ||
370 | keep.Add(f); | ||
371 | } | ||
372 | |||
373 | inv.SendBulkUpdateInventory(keep.ToArray(), content.Items.ToArray()); | ||
352 | } | 374 | } |
353 | } | 375 | } |
354 | } | 376 | } |
@@ -381,7 +403,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
381 | 403 | ||
382 | foreach (InventoryFolderBase f in content.Folders) | 404 | foreach (InventoryFolderBase f in content.Folders) |
383 | { | 405 | { |
384 | if (f.Name != "My Suitcase") | 406 | if (f.Name != "My Suitcase" && f.Name != "Current Outfit") |
385 | { | 407 | { |
386 | f.Name = f.Name + " (Unavailable)"; | 408 | f.Name = f.Name + " (Unavailable)"; |
387 | keep.Add(f); | 409 | keep.Add(f); |
@@ -406,5 +428,36 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
406 | } | 428 | } |
407 | 429 | ||
408 | #endregion | 430 | #endregion |
431 | |||
432 | #region Permissions | ||
433 | |||
434 | private bool CanTakeObject(UUID objectID, UUID stealer, Scene scene) | ||
435 | { | ||
436 | if (m_bypassPermissions) return true; | ||
437 | |||
438 | if (!m_OutboundPermission && !UserManagementModule.IsLocalGridUser(stealer)) | ||
439 | { | ||
440 | SceneObjectGroup sog = null; | ||
441 | if (m_Scene.TryGetSceneObjectGroup(objectID, out sog) && sog.OwnerID == stealer) | ||
442 | return true; | ||
443 | |||
444 | return false; | ||
445 | } | ||
446 | |||
447 | return true; | ||
448 | } | ||
449 | |||
450 | private bool OnTransferUserInventory(UUID itemID, UUID userID, UUID recipientID) | ||
451 | { | ||
452 | if (m_bypassPermissions) return true; | ||
453 | |||
454 | if (!m_OutboundPermission && !UserManagementModule.IsLocalGridUser(recipientID)) | ||
455 | return false; | ||
456 | |||
457 | return true; | ||
458 | } | ||
459 | |||
460 | |||
461 | #endregion | ||
409 | } | 462 | } |
410 | } \ No newline at end of file | 463 | } \ No newline at end of file |
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index d09ea3e..fadcd5e 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs | |||
@@ -358,7 +358,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
358 | bool asAttachment) | 358 | bool asAttachment) |
359 | { | 359 | { |
360 | CoalescedSceneObjects coa = new CoalescedSceneObjects(UUID.Zero); | 360 | CoalescedSceneObjects coa = new CoalescedSceneObjects(UUID.Zero); |
361 | Dictionary<UUID, Vector3> originalPositions = new Dictionary<UUID, Vector3>(); | 361 | // Dictionary<UUID, Vector3> originalPositions = new Dictionary<UUID, Vector3>(); |
362 | 362 | ||
363 | foreach (SceneObjectGroup objectGroup in objlist) | 363 | foreach (SceneObjectGroup objectGroup in objlist) |
364 | { | 364 | { |
@@ -379,7 +379,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
379 | objectGroup.AbsolutePosition.Z); | 379 | objectGroup.AbsolutePosition.Z); |
380 | 380 | ||
381 | Quaternion inventoryStoredRotation = objectGroup.GroupRotation; | 381 | Quaternion inventoryStoredRotation = objectGroup.GroupRotation; |
382 | originalPositions[objectGroup.UUID] = objectGroup.AbsolutePosition; | 382 | //originalPositions[objectGroup.UUID] = objectGroup.AbsolutePosition; |
383 | 383 | ||
384 | // Restore attachment data after trip through the sim | 384 | // Restore attachment data after trip through the sim |
385 | if (objectGroup.RootPart.AttachPoint > 0) | 385 | if (objectGroup.RootPart.AttachPoint > 0) |
@@ -390,9 +390,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
390 | 390 | ||
391 | // Trees could be attached and it's been done, but it makes | 391 | // Trees could be attached and it's been done, but it makes |
392 | // no sense. State must be preserved because it's the tree type | 392 | // no sense. State must be preserved because it's the tree type |
393 | if (objectGroup.RootPart.Shape.PCode != (byte)PCode.Tree && | 393 | if (objectGroup.RootPart.Shape.PCode != (byte) PCode.Tree && |
394 | objectGroup.RootPart.Shape.PCode != (byte)PCode.NewTree) | 394 | objectGroup.RootPart.Shape.PCode != (byte) PCode.NewTree) |
395 | { | ||
395 | objectGroup.RootPart.Shape.State = objectGroup.RootPart.AttachPoint; | 396 | objectGroup.RootPart.Shape.State = objectGroup.RootPart.AttachPoint; |
397 | if (objectGroup.RootPart.AttachPoint > 0) | ||
398 | objectGroup.RootPart.Shape.LastAttachPoint = objectGroup.RootPart.AttachPoint; | ||
399 | } | ||
396 | 400 | ||
397 | objectGroup.AbsolutePosition = inventoryStoredPosition; | 401 | objectGroup.AbsolutePosition = inventoryStoredPosition; |
398 | objectGroup.RootPart.RotationOffset = inventoryStoredRotation; | 402 | objectGroup.RootPart.RotationOffset = inventoryStoredRotation; |
@@ -423,9 +427,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
423 | else | 427 | else |
424 | itemXml = SceneObjectSerializer.ToOriginalXmlFormat(objlist[0], !asAttachment); | 428 | itemXml = SceneObjectSerializer.ToOriginalXmlFormat(objlist[0], !asAttachment); |
425 | 429 | ||
426 | // Restore the position of each group now that it has been stored to inventory. | 430 | // // Restore the position of each group now that it has been stored to inventory. |
427 | foreach (SceneObjectGroup objectGroup in objlist) | 431 | // foreach (SceneObjectGroup objectGroup in objlist) |
428 | objectGroup.AbsolutePosition = originalPositions[objectGroup.UUID]; | 432 | // objectGroup.AbsolutePosition = originalPositions[objectGroup.UUID]; |
429 | 433 | ||
430 | InventoryItemBase item = CreateItemForObject(action, remoteClient, objlist[0], folderID); | 434 | InventoryItemBase item = CreateItemForObject(action, remoteClient, objlist[0], folderID); |
431 | 435 | ||
@@ -435,17 +439,28 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
435 | 439 | ||
436 | if (item == null) | 440 | if (item == null) |
437 | return null; | 441 | return null; |
442 | |||
443 | item.CreatorId = objlist[0].RootPart.CreatorID.ToString(); | ||
444 | item.CreatorData = objlist[0].RootPart.CreatorData; | ||
438 | 445 | ||
439 | // Can't know creator is the same, so null it in inventory | ||
440 | if (objlist.Count > 1) | 446 | if (objlist.Count > 1) |
441 | { | 447 | { |
442 | item.CreatorId = UUID.Zero.ToString(); | ||
443 | item.Flags = (uint)InventoryItemFlags.ObjectHasMultipleItems; | 448 | item.Flags = (uint)InventoryItemFlags.ObjectHasMultipleItems; |
449 | |||
450 | // If the objects have different creators then don't specify a creator at all | ||
451 | foreach (SceneObjectGroup objectGroup in objlist) | ||
452 | { | ||
453 | if ((objectGroup.RootPart.CreatorID.ToString() != item.CreatorId) | ||
454 | || (objectGroup.RootPart.CreatorData.ToString() != item.CreatorData)) | ||
455 | { | ||
456 | item.CreatorId = UUID.Zero.ToString(); | ||
457 | item.CreatorData = string.Empty; | ||
458 | break; | ||
459 | } | ||
460 | } | ||
444 | } | 461 | } |
445 | else | 462 | else |
446 | { | 463 | { |
447 | item.CreatorId = objlist[0].RootPart.CreatorID.ToString(); | ||
448 | item.CreatorData = objlist[0].RootPart.CreatorData; | ||
449 | item.SaleType = objlist[0].RootPart.ObjectSaleType; | 464 | item.SaleType = objlist[0].RootPart.ObjectSaleType; |
450 | item.SalePrice = objlist[0].RootPart.SalePrice; | 465 | item.SalePrice = objlist[0].RootPart.SalePrice; |
451 | } | 466 | } |
@@ -466,13 +481,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
466 | } | 481 | } |
467 | else | 482 | else |
468 | { | 483 | { |
469 | AddPermissions(item, objlist[0], objlist, remoteClient); | ||
470 | |||
471 | item.CreationDate = Util.UnixTimeSinceEpoch(); | 484 | item.CreationDate = Util.UnixTimeSinceEpoch(); |
472 | item.Description = asset.Description; | 485 | item.Description = asset.Description; |
473 | item.Name = asset.Name; | 486 | item.Name = asset.Name; |
474 | item.AssetType = asset.Type; | 487 | item.AssetType = asset.Type; |
475 | 488 | ||
489 | AddPermissions(item, objlist[0], objlist, remoteClient); | ||
490 | |||
476 | m_Scene.AddInventoryItem(item); | 491 | m_Scene.AddInventoryItem(item); |
477 | 492 | ||
478 | if (remoteClient != null && item.Owner == remoteClient.AgentId) | 493 | if (remoteClient != null && item.Owner == remoteClient.AgentId) |
@@ -527,16 +542,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
527 | } | 542 | } |
528 | effectivePerms |= (uint)PermissionMask.Move; | 543 | effectivePerms |= (uint)PermissionMask.Move; |
529 | 544 | ||
545 | //PermissionsUtil.LogPermissions(item.Name, "Before AddPermissions", item.BasePermissions, item.CurrentPermissions, item.NextPermissions); | ||
546 | |||
530 | if (remoteClient != null && (remoteClient.AgentId != so.RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions()) | 547 | if (remoteClient != null && (remoteClient.AgentId != so.RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions()) |
531 | { | 548 | { |
532 | uint perms = effectivePerms; | 549 | uint perms = effectivePerms; |
533 | uint nextPerms = (perms & 7) << 13; | 550 | PermissionsUtil.ApplyFoldedPermissions(effectivePerms, ref perms); |
534 | if ((nextPerms & (uint)PermissionMask.Copy) == 0) | ||
535 | perms &= ~(uint)PermissionMask.Copy; | ||
536 | if ((nextPerms & (uint)PermissionMask.Transfer) == 0) | ||
537 | perms &= ~(uint)PermissionMask.Transfer; | ||
538 | if ((nextPerms & (uint)PermissionMask.Modify) == 0) | ||
539 | perms &= ~(uint)PermissionMask.Modify; | ||
540 | 551 | ||
541 | item.BasePermissions = perms & so.RootPart.NextOwnerMask; | 552 | item.BasePermissions = perms & so.RootPart.NextOwnerMask; |
542 | item.CurrentPermissions = item.BasePermissions; | 553 | item.CurrentPermissions = item.BasePermissions; |
@@ -544,10 +555,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
544 | item.EveryOnePermissions = so.RootPart.EveryoneMask & so.RootPart.NextOwnerMask; | 555 | item.EveryOnePermissions = so.RootPart.EveryoneMask & so.RootPart.NextOwnerMask; |
545 | item.GroupPermissions = so.RootPart.GroupMask & so.RootPart.NextOwnerMask; | 556 | item.GroupPermissions = so.RootPart.GroupMask & so.RootPart.NextOwnerMask; |
546 | 557 | ||
547 | // Magic number badness. Maybe this deserves an enum. | 558 | // apply next owner perms on rez |
548 | // bit 4 (16) is the "Slam" bit, it means treat as passed | 559 | item.CurrentPermissions |= SceneObjectGroup.SLAM; |
549 | // and apply next owner perms on rez | ||
550 | item.CurrentPermissions |= 16; // Slam! | ||
551 | } | 560 | } |
552 | else | 561 | else |
553 | { | 562 | { |
@@ -564,8 +573,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
564 | (uint)PermissionMask.Move | | 573 | (uint)PermissionMask.Move | |
565 | (uint)PermissionMask.Export | | 574 | (uint)PermissionMask.Export | |
566 | 7); // Preserve folded permissions | 575 | 7); // Preserve folded permissions |
567 | } | 576 | } |
568 | 577 | ||
578 | //PermissionsUtil.LogPermissions(item.Name, "After AddPermissions", item.BasePermissions, item.CurrentPermissions, item.NextPermissions); | ||
579 | |||
569 | return item; | 580 | return item; |
570 | } | 581 | } |
571 | 582 | ||
@@ -707,6 +718,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
707 | InventoryFolderBase f = new InventoryFolderBase(so.FromFolderID, userID); | 718 | InventoryFolderBase f = new InventoryFolderBase(so.FromFolderID, userID); |
708 | if (f != null) | 719 | if (f != null) |
709 | folder = m_Scene.InventoryService.GetFolder(f); | 720 | folder = m_Scene.InventoryService.GetFolder(f); |
721 | |||
722 | if(folder.Type == 14 || folder.Type == 16) | ||
723 | { | ||
724 | // folder.Type = 6; | ||
725 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.Object); | ||
726 | } | ||
710 | } | 727 | } |
711 | } | 728 | } |
712 | 729 | ||
@@ -779,83 +796,29 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
779 | 796 | ||
780 | SceneObjectGroup group = null; | 797 | SceneObjectGroup group = null; |
781 | 798 | ||
782 | string xmlData = Utils.BytesToString(rezAsset.Data); | 799 | List<SceneObjectGroup> objlist; |
783 | List<SceneObjectGroup> objlist = new List<SceneObjectGroup>(); | 800 | List<Vector3> veclist; |
784 | List<Vector3> veclist = new List<Vector3>(); | 801 | Vector3 bbox; |
802 | float offsetHeight; | ||
785 | byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0); | 803 | byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0); |
786 | Vector3 pos; | 804 | Vector3 pos; |
787 | 805 | ||
788 | XmlDocument doc = new XmlDocument(); | 806 | bool single = m_Scene.GetObjectsToRez(rezAsset.Data, attachment, out objlist, out veclist, out bbox, out offsetHeight); |
789 | doc.LoadXml(xmlData); | ||
790 | XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject"); | ||
791 | Vector3 rez_pos; | ||
792 | if (e == null || attachment) // Single | ||
793 | { | ||
794 | SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); | ||
795 | if (!attachment) | ||
796 | { | ||
797 | g.RootPart.AttachPoint = g.RootPart.Shape.State; | ||
798 | g.RootPart.AttachOffset = g.AbsolutePosition; | ||
799 | g.RootPart.AttachRotation = g.GroupRotation; | ||
800 | if (g.RootPart.Shape.PCode != (byte)PCode.NewTree && | ||
801 | g.RootPart.Shape.PCode != (byte)PCode.Tree) | ||
802 | g.RootPart.Shape.State = 0; | ||
803 | } | ||
804 | 807 | ||
805 | objlist.Add(g); | 808 | if (single) |
806 | veclist.Add(new Vector3(0, 0, 0)); | 809 | { |
807 | |||
808 | float offsetHeight = 0; | ||
809 | pos = m_Scene.GetNewRezLocation( | 810 | pos = m_Scene.GetNewRezLocation( |
810 | RayStart, RayEnd, RayTargetID, Quaternion.Identity, | 811 | RayStart, RayEnd, RayTargetID, Quaternion.Identity, |
811 | BypassRayCast, bRayEndIsIntersection, true, g.GetAxisAlignedBoundingBox(out offsetHeight), false); | 812 | BypassRayCast, bRayEndIsIntersection, true, bbox, false); |
812 | pos.Z += offsetHeight; | 813 | pos.Z += offsetHeight; |
813 | rez_pos = pos; | ||
814 | } | 814 | } |
815 | else | 815 | else |
816 | { | 816 | { |
817 | XmlElement coll = (XmlElement)e; | ||
818 | float bx = Convert.ToSingle(coll.GetAttribute("x")); | ||
819 | float by = Convert.ToSingle(coll.GetAttribute("y")); | ||
820 | float bz = Convert.ToSingle(coll.GetAttribute("z")); | ||
821 | Vector3 bbox = new Vector3(bx, by, bz); | ||
822 | |||
823 | pos = m_Scene.GetNewRezLocation(RayStart, RayEnd, | 817 | pos = m_Scene.GetNewRezLocation(RayStart, RayEnd, |
824 | RayTargetID, Quaternion.Identity, | 818 | RayTargetID, Quaternion.Identity, |
825 | BypassRayCast, bRayEndIsIntersection, true, | 819 | BypassRayCast, bRayEndIsIntersection, true, |
826 | bbox, false); | 820 | bbox, false); |
827 | |||
828 | rez_pos = pos; | ||
829 | |||
830 | pos -= bbox / 2; | 821 | pos -= bbox / 2; |
831 | |||
832 | XmlNodeList groups = e.SelectNodes("SceneObjectGroup"); | ||
833 | foreach (XmlNode n in groups) | ||
834 | { | ||
835 | SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(n.OuterXml); | ||
836 | g.RootPart.AttachPoint = g.RootPart.Shape.State; | ||
837 | g.RootPart.AttachOffset = g.AbsolutePosition; | ||
838 | g.RootPart.AttachRotation = g.GroupRotation; | ||
839 | if (g.RootPart.Shape.PCode != (byte)PCode.NewTree && | ||
840 | g.RootPart.Shape.PCode != (byte)PCode.Tree) | ||
841 | g.RootPart.Shape.State = 0; | ||
842 | |||
843 | objlist.Add(g); | ||
844 | XmlElement el = (XmlElement)n; | ||
845 | |||
846 | string rawX = el.GetAttribute("offsetx"); | ||
847 | string rawY = el.GetAttribute("offsety"); | ||
848 | string rawZ = el.GetAttribute("offsetz"); | ||
849 | // | ||
850 | // m_log.DebugFormat( | ||
851 | // "[INVENTORY ACCESS MODULE]: Converting coalesced object {0} offset <{1}, {2}, {3}>", | ||
852 | // g.Name, rawX, rawY, rawZ); | ||
853 | |||
854 | float x = Convert.ToSingle(rawX); | ||
855 | float y = Convert.ToSingle(rawY); | ||
856 | float z = Convert.ToSingle(rawZ); | ||
857 | veclist.Add(new Vector3(x, y, z)); | ||
858 | } | ||
859 | } | 822 | } |
860 | 823 | ||
861 | int primcount = 0; | 824 | int primcount = 0; |
@@ -863,7 +826,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
863 | primcount += g.PrimCount; | 826 | primcount += g.PrimCount; |
864 | 827 | ||
865 | if (!m_Scene.Permissions.CanRezObject( | 828 | if (!m_Scene.Permissions.CanRezObject( |
866 | primcount, remoteClient.AgentId, rez_pos) | 829 | primcount, remoteClient.AgentId, pos) |
867 | && !attachment) | 830 | && !attachment) |
868 | { | 831 | { |
869 | // The client operates in no fail mode. It will | 832 | // The client operates in no fail mode. It will |
@@ -880,7 +843,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
880 | return null; | 843 | return null; |
881 | } | 844 | } |
882 | 845 | ||
883 | if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, rez_pos, attachment)) | 846 | if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, pos, veclist, attachment)) |
884 | return null; | 847 | return null; |
885 | 848 | ||
886 | for (int i = 0; i < objlist.Count; i++) | 849 | for (int i = 0; i < objlist.Count; i++) |
@@ -900,11 +863,23 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
900 | m_log.Debug("[INVENTORY ACCESS MODULE]: Object has UUID.Zero! Position 3"); | 863 | m_log.Debug("[INVENTORY ACCESS MODULE]: Object has UUID.Zero! Position 3"); |
901 | } | 864 | } |
902 | 865 | ||
903 | foreach (SceneObjectPart part in group.Parts) | 866 | // if this was previously an attachment and is now being rezzed, |
867 | // save the old attachment info. | ||
868 | if (group.IsAttachment == false && group.RootPart.Shape.State != 0) | ||
904 | { | 869 | { |
905 | // Make the rezzer the owner, as this is not necessarily set correctly in the serialized asset. | 870 | group.RootPart.AttachedPos = group.AbsolutePosition; |
906 | part.LastOwnerID = part.OwnerID; | 871 | group.RootPart.Shape.LastAttachPoint = (byte)group.AttachmentPoint; |
907 | part.OwnerID = remoteClient.AgentId; | 872 | } |
873 | |||
874 | if (item == null) | ||
875 | { | ||
876 | // Change ownership. Normally this is done in DoPreRezWhenFromItem(), but in this case we must do it here. | ||
877 | foreach (SceneObjectPart part in group.Parts) | ||
878 | { | ||
879 | // Make the rezzer the owner, as this is not necessarily set correctly in the serialized asset. | ||
880 | part.LastOwnerID = part.OwnerID; | ||
881 | part.OwnerID = remoteClient.AgentId; | ||
882 | } | ||
908 | } | 883 | } |
909 | 884 | ||
910 | if (!attachment) | 885 | if (!attachment) |
@@ -979,10 +954,15 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
979 | /// <param name="item"></param> | 954 | /// <param name="item"></param> |
980 | /// <param name="objlist"></param> | 955 | /// <param name="objlist"></param> |
981 | /// <param name="pos"></param> | 956 | /// <param name="pos"></param> |
957 | /// <param name="veclist"> | ||
958 | /// List of vector position adjustments for a coalesced objects. For ordinary objects | ||
959 | /// this list will contain just Vector3.Zero. The order of adjustments must match the order of objlist | ||
960 | /// </param> | ||
982 | /// <param name="isAttachment"></param> | 961 | /// <param name="isAttachment"></param> |
983 | /// <returns>true if we can processed with rezzing, false if we need to abort</returns> | 962 | /// <returns>true if we can processed with rezzing, false if we need to abort</returns> |
984 | private bool DoPreRezWhenFromItem( | 963 | private bool DoPreRezWhenFromItem( |
985 | IClientAPI remoteClient, InventoryItemBase item, List<SceneObjectGroup> objlist, Vector3 pos, bool isAttachment) | 964 | IClientAPI remoteClient, InventoryItemBase item, List<SceneObjectGroup> objlist, |
965 | Vector3 pos, List<Vector3> veclist, bool isAttachment) | ||
986 | { | 966 | { |
987 | UUID fromUserInventoryItemId = UUID.Zero; | 967 | UUID fromUserInventoryItemId = UUID.Zero; |
988 | 968 | ||
@@ -1005,28 +985,29 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
1005 | } | 985 | } |
1006 | } | 986 | } |
1007 | 987 | ||
1008 | int primcount = 0; | 988 | for (int i = 0; i < objlist.Count; i++) |
1009 | foreach (SceneObjectGroup g in objlist) | ||
1010 | primcount += g.PrimCount; | ||
1011 | |||
1012 | if (!m_Scene.Permissions.CanRezObject( | ||
1013 | primcount, remoteClient.AgentId, pos) | ||
1014 | && !isAttachment) | ||
1015 | { | 989 | { |
1016 | // The client operates in no fail mode. It will | 990 | SceneObjectGroup g = objlist[i]; |
1017 | // have already removed the item from the folder | ||
1018 | // if it's no copy. | ||
1019 | // Put it back if it's not an attachment | ||
1020 | // | ||
1021 | if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!isAttachment)) | ||
1022 | remoteClient.SendBulkUpdateInventory(item); | ||
1023 | 991 | ||
1024 | ILandObject land = m_Scene.LandChannel.GetLandObject(pos.X, pos.Y); | 992 | if (!m_Scene.Permissions.CanRezObject( |
1025 | remoteClient.SendAlertMessage(string.Format( | 993 | g.PrimCount, remoteClient.AgentId, pos + veclist[i]) |
1026 | "Can't rez object '{0}' at <{1:F3}, {2:F3}, {3:F3}> on parcel '{4}' in region {5}.", | 994 | && !isAttachment) |
1027 | item.Name, pos.X, pos.Y, pos.Z, land != null ? land.LandData.Name : "Unknown", m_Scene.RegionInfo.RegionName)); | 995 | { |
996 | // The client operates in no fail mode. It will | ||
997 | // have already removed the item from the folder | ||
998 | // if it's no copy. | ||
999 | // Put it back if it's not an attachment | ||
1000 | // | ||
1001 | if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!isAttachment)) | ||
1002 | remoteClient.SendBulkUpdateInventory(item); | ||
1028 | 1003 | ||
1029 | return false; | 1004 | ILandObject land = m_Scene.LandChannel.GetLandObject(pos.X, pos.Y); |
1005 | remoteClient.SendAlertMessage(string.Format( | ||
1006 | "Can't rez object '{0}' at <{1:F3}, {2:F3}, {3:F3}> on parcel '{4}' in region {5}.", | ||
1007 | item.Name, pos.X, pos.Y, pos.Z, land != null ? land.LandData.Name : "Unknown", m_Scene.Name)); | ||
1008 | |||
1009 | return false; | ||
1010 | } | ||
1030 | } | 1011 | } |
1031 | 1012 | ||
1032 | for (int i = 0; i < objlist.Count; i++) | 1013 | for (int i = 0; i < objlist.Count; i++) |
@@ -1107,7 +1088,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
1107 | part.GroupMask = item.GroupPermissions; | 1088 | part.GroupMask = item.GroupPermissions; |
1108 | } | 1089 | } |
1109 | } | 1090 | } |
1110 | 1091 | ||
1111 | rootPart.TrimPermissions(); | 1092 | rootPart.TrimPermissions(); |
1112 | 1093 | ||
1113 | if (isAttachment) | 1094 | if (isAttachment) |
diff --git a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs index d07cff4..69d7e16 100644 --- a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs +++ b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs | |||
@@ -176,7 +176,7 @@ namespace OpenSim.Region.CoreModules.Framework.Library | |||
176 | m_log.InfoFormat("[LIBRARY MODULE]: Loading library archive {0} ({1})...", iarFileName, simpleName); | 176 | m_log.InfoFormat("[LIBRARY MODULE]: Loading library archive {0} ({1})...", iarFileName, simpleName); |
177 | simpleName = GetInventoryPathFromName(simpleName); | 177 | simpleName = GetInventoryPathFromName(simpleName); |
178 | 178 | ||
179 | InventoryArchiveReadRequest archread = new InventoryArchiveReadRequest(m_MockScene, uinfo, simpleName, iarFileName, false); | 179 | InventoryArchiveReadRequest archread = new InventoryArchiveReadRequest(m_MockScene.InventoryService, m_MockScene.AssetService, m_MockScene.UserAccountService, uinfo, simpleName, iarFileName, false); |
180 | try | 180 | try |
181 | { | 181 | { |
182 | HashSet<InventoryNodeBase> nodes = archread.Execute(); | 182 | HashSet<InventoryNodeBase> nodes = archread.Execute(); |
@@ -185,7 +185,7 @@ namespace OpenSim.Region.CoreModules.Framework.Library | |||
185 | // didn't find the subfolder with the given name; place it on the top | 185 | // didn't find the subfolder with the given name; place it on the top |
186 | m_log.InfoFormat("[LIBRARY MODULE]: Didn't find {0} in library. Placing archive on the top level", simpleName); | 186 | m_log.InfoFormat("[LIBRARY MODULE]: Didn't find {0} in library. Placing archive on the top level", simpleName); |
187 | archread.Close(); | 187 | archread.Close(); |
188 | archread = new InventoryArchiveReadRequest(m_MockScene, uinfo, "/", iarFileName, false); | 188 | archread = new InventoryArchiveReadRequest(m_MockScene.InventoryService, m_MockScene.AssetService, m_MockScene.UserAccountService, uinfo, "/", iarFileName, false); |
189 | archread.Execute(); | 189 | archread.Execute(); |
190 | } | 190 | } |
191 | 191 | ||
diff --git a/OpenSim/Region/CoreModules/Framework/Search/BasicSearchModule.cs b/OpenSim/Region/CoreModules/Framework/Search/BasicSearchModule.cs new file mode 100644 index 0000000..8838612 --- /dev/null +++ b/OpenSim/Region/CoreModules/Framework/Search/BasicSearchModule.cs | |||
@@ -0,0 +1,197 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | using System; | ||
28 | using System.Collections.Generic; | ||
29 | using System.IO; | ||
30 | using System.Reflection; | ||
31 | using System.Threading; | ||
32 | |||
33 | using OpenSim.Framework; | ||
34 | using OpenSim.Framework.Console; | ||
35 | using OpenSim.Framework.Monitoring; | ||
36 | using OpenSim.Region.ClientStack.LindenUDP; | ||
37 | using OpenSim.Region.Framework; | ||
38 | using OpenSim.Region.Framework.Interfaces; | ||
39 | using OpenSim.Region.Framework.Scenes; | ||
40 | using OpenSim.Services.Interfaces; | ||
41 | using OpenSim.Services.Connectors.Hypergrid; | ||
42 | |||
43 | using OpenMetaverse; | ||
44 | using OpenMetaverse.Packets; | ||
45 | using log4net; | ||
46 | using Nini.Config; | ||
47 | using Mono.Addins; | ||
48 | |||
49 | using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags; | ||
50 | |||
51 | namespace OpenSim.Region.CoreModules.Framework.Search | ||
52 | { | ||
53 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "BasicSearchModule")] | ||
54 | public class BasicSearchModule : ISharedRegionModule | ||
55 | { | ||
56 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
57 | |||
58 | protected bool m_Enabled; | ||
59 | protected List<Scene> m_Scenes = new List<Scene>(); | ||
60 | |||
61 | private IGroupsModule m_GroupsService = null; | ||
62 | |||
63 | #region ISharedRegionModule | ||
64 | |||
65 | public void Initialise(IConfigSource config) | ||
66 | { | ||
67 | string umanmod = config.Configs["Modules"].GetString("SearchModule", Name); | ||
68 | if (umanmod == Name) | ||
69 | { | ||
70 | m_Enabled = true; | ||
71 | m_log.DebugFormat("[BASIC SEARCH MODULE]: {0} is enabled", Name); | ||
72 | } | ||
73 | } | ||
74 | |||
75 | public bool IsSharedModule | ||
76 | { | ||
77 | get { return true; } | ||
78 | } | ||
79 | |||
80 | public virtual string Name | ||
81 | { | ||
82 | get { return "BasicSearchModule"; } | ||
83 | } | ||
84 | |||
85 | public Type ReplaceableInterface | ||
86 | { | ||
87 | get { return null; } | ||
88 | } | ||
89 | |||
90 | public void AddRegion(Scene scene) | ||
91 | { | ||
92 | if (m_Enabled) | ||
93 | { | ||
94 | m_Scenes.Add(scene); | ||
95 | |||
96 | scene.EventManager.OnMakeRootAgent += new Action<ScenePresence>(EventManager_OnMakeRootAgent); | ||
97 | scene.EventManager.OnMakeChildAgent += new EventManager.OnMakeChildAgentDelegate(EventManager_OnMakeChildAgent); | ||
98 | } | ||
99 | } | ||
100 | |||
101 | public void RemoveRegion(Scene scene) | ||
102 | { | ||
103 | if (m_Enabled) | ||
104 | { | ||
105 | m_Scenes.Remove(scene); | ||
106 | |||
107 | scene.EventManager.OnMakeRootAgent -= new Action<ScenePresence>(EventManager_OnMakeRootAgent); | ||
108 | scene.EventManager.OnMakeChildAgent -= new EventManager.OnMakeChildAgentDelegate(EventManager_OnMakeChildAgent); | ||
109 | } | ||
110 | } | ||
111 | |||
112 | public void RegionLoaded(Scene s) | ||
113 | { | ||
114 | if (!m_Enabled) | ||
115 | return; | ||
116 | |||
117 | if (m_GroupsService == null) | ||
118 | { | ||
119 | m_GroupsService = s.RequestModuleInterface<IGroupsModule>(); | ||
120 | |||
121 | // No Groups Service Connector, then group search won't work... | ||
122 | if (m_GroupsService == null) | ||
123 | m_log.Warn("[BASIC SEARCH MODULE]: Could not get IGroupsModule"); | ||
124 | } | ||
125 | } | ||
126 | |||
127 | public void PostInitialise() | ||
128 | { | ||
129 | } | ||
130 | |||
131 | public void Close() | ||
132 | { | ||
133 | m_Scenes.Clear(); | ||
134 | } | ||
135 | |||
136 | #endregion ISharedRegionModule | ||
137 | |||
138 | |||
139 | #region Event Handlers | ||
140 | |||
141 | void EventManager_OnMakeRootAgent(ScenePresence sp) | ||
142 | { | ||
143 | sp.ControllingClient.OnDirFindQuery += OnDirFindQuery; | ||
144 | } | ||
145 | |||
146 | void EventManager_OnMakeChildAgent(ScenePresence sp) | ||
147 | { | ||
148 | sp.ControllingClient.OnDirFindQuery -= OnDirFindQuery; | ||
149 | } | ||
150 | |||
151 | void OnDirFindQuery(IClientAPI remoteClient, UUID queryID, string queryText, uint queryFlags, int queryStart) | ||
152 | { | ||
153 | if (((DirFindFlags)queryFlags & DirFindFlags.People) == DirFindFlags.People) | ||
154 | { | ||
155 | if (string.IsNullOrEmpty(queryText)) | ||
156 | remoteClient.SendDirPeopleReply(queryID, new DirPeopleReplyData[0]); | ||
157 | |||
158 | List<UserAccount> accounts = m_Scenes[0].UserAccountService.GetUserAccounts(m_Scenes[0].RegionInfo.ScopeID, queryText); | ||
159 | DirPeopleReplyData[] hits = new DirPeopleReplyData[accounts.Count]; | ||
160 | int i = 0; | ||
161 | foreach (UserAccount acc in accounts) | ||
162 | { | ||
163 | DirPeopleReplyData d = new DirPeopleReplyData(); | ||
164 | d.agentID = acc.PrincipalID; | ||
165 | d.firstName = acc.FirstName; | ||
166 | d.lastName = acc.LastName; | ||
167 | d.online = false; | ||
168 | |||
169 | hits[i++] = d; | ||
170 | } | ||
171 | |||
172 | // TODO: This currently ignores pretty much all the query flags including Mature and sort order | ||
173 | remoteClient.SendDirPeopleReply(queryID, hits); | ||
174 | } | ||
175 | else if (((DirFindFlags)queryFlags & DirFindFlags.Groups) == DirFindFlags.Groups) | ||
176 | { | ||
177 | if (m_GroupsService == null) | ||
178 | { | ||
179 | m_log.Warn("[BASIC SEARCH MODULE]: Groups service is not available. Unable to search groups."); | ||
180 | remoteClient.SendAlertMessage("Groups search is not enabled"); | ||
181 | return; | ||
182 | } | ||
183 | |||
184 | if (string.IsNullOrEmpty(queryText)) | ||
185 | remoteClient.SendDirGroupsReply(queryID, new DirGroupsReplyData[0]); | ||
186 | |||
187 | // TODO: This currently ignores pretty much all the query flags including Mature and sort order | ||
188 | remoteClient.SendDirGroupsReply(queryID, m_GroupsService.FindGroups(remoteClient, queryText).ToArray()); | ||
189 | } | ||
190 | |||
191 | } | ||
192 | |||
193 | #endregion Event Handlers | ||
194 | |||
195 | } | ||
196 | |||
197 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs b/OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs new file mode 100644 index 0000000..a70261e --- /dev/null +++ b/OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs | |||
@@ -0,0 +1,256 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Reflection; | ||
31 | using System.Threading; | ||
32 | using log4net; | ||
33 | using Mono.Addins; | ||
34 | using Nini.Config; | ||
35 | using OpenMetaverse; | ||
36 | using OpenSim.Framework; | ||
37 | using OpenSim.Region.Framework.Interfaces; | ||
38 | using OpenSim.Framework.Monitoring; | ||
39 | using OpenSim.Region.Framework.Scenes; | ||
40 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; | ||
41 | |||
42 | namespace OpenSim.Region.CoreModules.Framework | ||
43 | { | ||
44 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GridServiceThrottleModule")] | ||
45 | public class ServiceThrottleModule : ISharedRegionModule, IServiceThrottleModule | ||
46 | { | ||
47 | private static readonly ILog m_log = LogManager.GetLogger( | ||
48 | MethodBase.GetCurrentMethod().DeclaringType); | ||
49 | |||
50 | private readonly List<Scene> m_scenes = new List<Scene>(); | ||
51 | private System.Timers.Timer m_timer = new System.Timers.Timer(); | ||
52 | |||
53 | private Queue<Action> m_RequestQueue = new Queue<Action>(); | ||
54 | private Dictionary<string, List<string>> m_Pending = new Dictionary<string, List<string>>(); | ||
55 | private int m_Interval; | ||
56 | |||
57 | #region ISharedRegionModule | ||
58 | |||
59 | public void Initialise(IConfigSource config) | ||
60 | { | ||
61 | m_Interval = Util.GetConfigVarFromSections<int>(config, "Interval", new string[] { "ServiceThrottle" }, 5000); | ||
62 | |||
63 | m_timer = new System.Timers.Timer(); | ||
64 | m_timer.AutoReset = false; | ||
65 | m_timer.Enabled = true; | ||
66 | m_timer.Interval = 15000; // 15 secs at first | ||
67 | m_timer.Elapsed += ProcessQueue; | ||
68 | m_timer.Start(); | ||
69 | |||
70 | //Watchdog.StartThread( | ||
71 | // ProcessQueue, | ||
72 | // "GridServiceRequestThread", | ||
73 | // ThreadPriority.BelowNormal, | ||
74 | // true, | ||
75 | // false); | ||
76 | } | ||
77 | |||
78 | public void AddRegion(Scene scene) | ||
79 | { | ||
80 | lock (m_scenes) | ||
81 | { | ||
82 | m_scenes.Add(scene); | ||
83 | scene.RegisterModuleInterface<IServiceThrottleModule>(this); | ||
84 | scene.EventManager.OnNewClient += OnNewClient; | ||
85 | scene.EventManager.OnMakeRootAgent += OnMakeRootAgent; | ||
86 | } | ||
87 | } | ||
88 | |||
89 | public void RegionLoaded(Scene scene) | ||
90 | { | ||
91 | } | ||
92 | |||
93 | public void RemoveRegion(Scene scene) | ||
94 | { | ||
95 | lock (m_scenes) | ||
96 | { | ||
97 | m_scenes.Remove(scene); | ||
98 | scene.EventManager.OnNewClient -= OnNewClient; | ||
99 | } | ||
100 | } | ||
101 | |||
102 | public void PostInitialise() | ||
103 | { | ||
104 | } | ||
105 | |||
106 | public void Close() | ||
107 | { | ||
108 | } | ||
109 | |||
110 | public string Name | ||
111 | { | ||
112 | get { return "ServiceThrottleModule"; } | ||
113 | } | ||
114 | |||
115 | public Type ReplaceableInterface | ||
116 | { | ||
117 | get { return null; } | ||
118 | } | ||
119 | |||
120 | #endregion ISharedRegionMOdule | ||
121 | |||
122 | #region Events | ||
123 | |||
124 | void OnNewClient(IClientAPI client) | ||
125 | { | ||
126 | client.OnRegionHandleRequest += OnRegionHandleRequest; | ||
127 | } | ||
128 | |||
129 | void OnMakeRootAgent(ScenePresence obj) | ||
130 | { | ||
131 | lock (m_timer) | ||
132 | { | ||
133 | if (!m_timer.Enabled) | ||
134 | { | ||
135 | m_timer.Interval = m_Interval; | ||
136 | m_timer.Enabled = true; | ||
137 | m_timer.Start(); | ||
138 | } | ||
139 | } | ||
140 | } | ||
141 | |||
142 | public void OnRegionHandleRequest(IClientAPI client, UUID regionID) | ||
143 | { | ||
144 | //m_log.DebugFormat("[SERVICE THROTTLE]: RegionHandleRequest {0}", regionID); | ||
145 | ulong handle = 0; | ||
146 | if (IsLocalRegionHandle(regionID, out handle)) | ||
147 | { | ||
148 | client.SendRegionHandle(regionID, handle); | ||
149 | return; | ||
150 | } | ||
151 | |||
152 | Action action = delegate | ||
153 | { | ||
154 | GridRegion r = m_scenes[0].GridService.GetRegionByUUID(UUID.Zero, regionID); | ||
155 | |||
156 | if (r != null && r.RegionHandle != 0) | ||
157 | client.SendRegionHandle(regionID, r.RegionHandle); | ||
158 | }; | ||
159 | |||
160 | Enqueue("region", regionID.ToString(), action); | ||
161 | } | ||
162 | |||
163 | #endregion Events | ||
164 | |||
165 | #region IServiceThrottleModule | ||
166 | |||
167 | public void Enqueue(string category, string itemid, Action continuation) | ||
168 | { | ||
169 | lock (m_RequestQueue) | ||
170 | { | ||
171 | if (m_Pending.ContainsKey(category)) | ||
172 | { | ||
173 | if (m_Pending[category].Contains(itemid)) | ||
174 | // Don't enqueue, it's already pending | ||
175 | return; | ||
176 | } | ||
177 | else | ||
178 | m_Pending.Add(category, new List<string>()); | ||
179 | |||
180 | m_Pending[category].Add(itemid); | ||
181 | |||
182 | m_RequestQueue.Enqueue(delegate | ||
183 | { | ||
184 | lock (m_RequestQueue) | ||
185 | m_Pending[category].Remove(itemid); | ||
186 | |||
187 | continuation(); | ||
188 | }); | ||
189 | } | ||
190 | } | ||
191 | |||
192 | #endregion IServiceThrottleModule | ||
193 | |||
194 | #region Process Continuation Queue | ||
195 | |||
196 | private void ProcessQueue(object sender, System.Timers.ElapsedEventArgs e) | ||
197 | { | ||
198 | //m_log.DebugFormat("[YYY]: Process queue with {0} continuations", m_RequestQueue.Count); | ||
199 | |||
200 | while (m_RequestQueue.Count > 0) | ||
201 | { | ||
202 | Action continuation = null; | ||
203 | lock (m_RequestQueue) | ||
204 | continuation = m_RequestQueue.Dequeue(); | ||
205 | |||
206 | if (continuation != null) | ||
207 | continuation(); | ||
208 | } | ||
209 | |||
210 | if (AreThereRootAgents()) | ||
211 | { | ||
212 | lock (m_timer) | ||
213 | { | ||
214 | m_timer.Interval = 1000; // 1 sec | ||
215 | m_timer.Enabled = true; | ||
216 | m_timer.Start(); | ||
217 | } | ||
218 | } | ||
219 | else | ||
220 | lock (m_timer) | ||
221 | m_timer.Enabled = false; | ||
222 | |||
223 | } | ||
224 | |||
225 | #endregion Process Continuation Queue | ||
226 | |||
227 | #region Misc | ||
228 | |||
229 | private bool IsLocalRegionHandle(UUID regionID, out ulong regionHandle) | ||
230 | { | ||
231 | regionHandle = 0; | ||
232 | foreach (Scene s in m_scenes) | ||
233 | if (s.RegionInfo.RegionID == regionID) | ||
234 | { | ||
235 | regionHandle = s.RegionInfo.RegionHandle; | ||
236 | return true; | ||
237 | } | ||
238 | return false; | ||
239 | } | ||
240 | |||
241 | private bool AreThereRootAgents() | ||
242 | { | ||
243 | foreach (Scene s in m_scenes) | ||
244 | { | ||
245 | foreach (ScenePresence sp in s.GetScenePresences()) | ||
246 | if (!sp.IsChildAgent) | ||
247 | return true; | ||
248 | } | ||
249 | |||
250 | return false; | ||
251 | } | ||
252 | |||
253 | #endregion Misc | ||
254 | } | ||
255 | |||
256 | } | ||
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs index 8ce20e9..245c808 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs | |||
@@ -54,11 +54,11 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
54 | 54 | ||
55 | public new void Initialise(IConfigSource config) | 55 | public new void Initialise(IConfigSource config) |
56 | { | 56 | { |
57 | string umanmod = config.Configs["Modules"].GetString("UserManagementModule", Name); | 57 | string umanmod = config.Configs["Modules"].GetString("UserManagementModule", null); |
58 | if (umanmod == Name) | 58 | if (umanmod == Name) |
59 | { | 59 | { |
60 | m_Enabled = true; | 60 | m_Enabled = true; |
61 | RegisterConsoleCmds(); | 61 | Init(); |
62 | m_log.DebugFormat("[USER MANAGEMENT MODULE]: {0} is enabled", Name); | 62 | m_log.DebugFormat("[USER MANAGEMENT MODULE]: {0} is enabled", Name); |
63 | } | 63 | } |
64 | } | 64 | } |
@@ -70,7 +70,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
70 | 70 | ||
71 | #endregion ISharedRegionModule | 71 | #endregion ISharedRegionModule |
72 | 72 | ||
73 | protected override void AddAdditionalUsers(UUID avatarID, string query, List<UserData> users) | 73 | protected override void AddAdditionalUsers(string query, List<UserData> users) |
74 | { | 74 | { |
75 | if (query.Contains("@")) // First.Last@foo.com, maybe? | 75 | if (query.Contains("@")) // First.Last@foo.com, maybe? |
76 | { | 76 | { |
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/Tests/HGUserManagementModuleTests.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/Tests/HGUserManagementModuleTests.cs new file mode 100644 index 0000000..9d36aa5 --- /dev/null +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/Tests/HGUserManagementModuleTests.cs | |||
@@ -0,0 +1,76 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using Nini.Config; | ||
30 | using NUnit.Framework; | ||
31 | using OpenMetaverse; | ||
32 | using OpenSim.Framework; | ||
33 | using OpenSim.Region.CoreModules.Framework.UserManagement; | ||
34 | using OpenSim.Tests.Common; | ||
35 | using OpenSim.Tests.Common.Mock; | ||
36 | |||
37 | namespace OpenSim.Region.CoreModules.Framework.UserManagement.Tests | ||
38 | { | ||
39 | [TestFixture] | ||
40 | public class HGUserManagementModuleTests : OpenSimTestCase | ||
41 | { | ||
42 | /// <summary> | ||
43 | /// Test that a new HG agent (i.e. one without a user account) has their name cached in the UMM upon creation. | ||
44 | /// </summary> | ||
45 | [Test] | ||
46 | public void TestCachedUserNameForNewAgent() | ||
47 | { | ||
48 | TestHelpers.InMethod(); | ||
49 | // TestHelpers.EnableLogging(); | ||
50 | |||
51 | HGUserManagementModule hgumm = new HGUserManagementModule(); | ||
52 | UUID userId = TestHelpers.ParseStem("11"); | ||
53 | string firstName = "Fred"; | ||
54 | string lastName = "Astaire"; | ||
55 | string homeUri = "example.com"; | ||
56 | |||
57 | IConfigSource config = new IniConfigSource(); | ||
58 | config.AddConfig("Modules"); | ||
59 | config.Configs["Modules"].Set("UserManagementModule", hgumm.Name); | ||
60 | |||
61 | SceneHelpers sceneHelpers = new SceneHelpers(); | ||
62 | TestScene scene = sceneHelpers.SetupScene(); | ||
63 | SceneHelpers.SetupSceneModules(scene, config, hgumm); | ||
64 | |||
65 | AgentCircuitData acd = SceneHelpers.GenerateAgentData(userId); | ||
66 | acd.firstname = firstName; | ||
67 | acd.lastname = lastName; | ||
68 | acd.ServiceURLs["HomeURI"] = "http://" + homeUri; | ||
69 | |||
70 | SceneHelpers.AddScenePresence(scene, acd); | ||
71 | |||
72 | string name = hgumm.GetUserName(userId); | ||
73 | Assert.That(name, Is.EqualTo(string.Format("{0}.{1} @{2}", firstName, lastName, homeUri))); | ||
74 | } | ||
75 | } | ||
76 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs index 77e8b00..3fb5195 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs | |||
@@ -28,9 +28,11 @@ using System; | |||
28 | using System.Collections.Generic; | 28 | using System.Collections.Generic; |
29 | using System.IO; | 29 | using System.IO; |
30 | using System.Reflection; | 30 | using System.Reflection; |
31 | using System.Threading; | ||
31 | 32 | ||
32 | using OpenSim.Framework; | 33 | using OpenSim.Framework; |
33 | using OpenSim.Framework.Console; | 34 | using OpenSim.Framework.Console; |
35 | using OpenSim.Framework.Monitoring; | ||
34 | using OpenSim.Region.ClientStack.LindenUDP; | 36 | using OpenSim.Region.ClientStack.LindenUDP; |
35 | using OpenSim.Region.Framework; | 37 | using OpenSim.Region.Framework; |
36 | using OpenSim.Region.Framework.Interfaces; | 38 | using OpenSim.Region.Framework.Interfaces; |
@@ -44,25 +46,19 @@ using log4net; | |||
44 | using Nini.Config; | 46 | using Nini.Config; |
45 | using Mono.Addins; | 47 | using Mono.Addins; |
46 | 48 | ||
49 | using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags; | ||
50 | |||
47 | namespace OpenSim.Region.CoreModules.Framework.UserManagement | 51 | namespace OpenSim.Region.CoreModules.Framework.UserManagement |
48 | { | 52 | { |
49 | public class UserData | ||
50 | { | ||
51 | public UUID Id { get; set; } | ||
52 | public string FirstName { get; set; } | ||
53 | public string LastName { get; set; } | ||
54 | public string HomeURL { get; set; } | ||
55 | public Dictionary<string, object> ServerURLs { get; set; } | ||
56 | } | ||
57 | |||
58 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "UserManagementModule")] | 53 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "UserManagementModule")] |
59 | public class UserManagementModule : ISharedRegionModule, IUserManagement | 54 | public class UserManagementModule : ISharedRegionModule, IUserManagement, IPeople |
60 | { | 55 | { |
61 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 56 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
62 | 57 | ||
63 | protected bool m_Enabled; | 58 | protected bool m_Enabled; |
64 | protected List<Scene> m_Scenes = new List<Scene>(); | 59 | protected List<Scene> m_Scenes = new List<Scene>(); |
65 | 60 | ||
61 | protected IServiceThrottleModule m_ServiceThrottle; | ||
66 | // The cache | 62 | // The cache |
67 | protected Dictionary<UUID, UserData> m_UserCache = new Dictionary<UUID, UserData>(); | 63 | protected Dictionary<UUID, UserData> m_UserCache = new Dictionary<UUID, UserData>(); |
68 | 64 | ||
@@ -74,7 +70,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
74 | if (umanmod == Name) | 70 | if (umanmod == Name) |
75 | { | 71 | { |
76 | m_Enabled = true; | 72 | m_Enabled = true; |
77 | RegisterConsoleCmds(); | 73 | Init(); |
78 | m_log.DebugFormat("[USER MANAGEMENT MODULE]: {0} is enabled", Name); | 74 | m_log.DebugFormat("[USER MANAGEMENT MODULE]: {0} is enabled", Name); |
79 | } | 75 | } |
80 | } | 76 | } |
@@ -101,6 +97,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
101 | m_Scenes.Add(scene); | 97 | m_Scenes.Add(scene); |
102 | 98 | ||
103 | scene.RegisterModuleInterface<IUserManagement>(this); | 99 | scene.RegisterModuleInterface<IUserManagement>(this); |
100 | scene.RegisterModuleInterface<IPeople>(this); | ||
104 | scene.EventManager.OnNewClient += new EventManager.OnNewClientDelegate(EventManager_OnNewClient); | 101 | scene.EventManager.OnNewClient += new EventManager.OnNewClientDelegate(EventManager_OnNewClient); |
105 | scene.EventManager.OnPrimsLoaded += new EventManager.PrimsLoaded(EventManager_OnPrimsLoaded); | 102 | scene.EventManager.OnPrimsLoaded += new EventManager.PrimsLoaded(EventManager_OnPrimsLoaded); |
106 | } | 103 | } |
@@ -117,6 +114,8 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
117 | 114 | ||
118 | public void RegionLoaded(Scene s) | 115 | public void RegionLoaded(Scene s) |
119 | { | 116 | { |
117 | if (m_Enabled && m_ServiceThrottle == null) | ||
118 | m_ServiceThrottle = s.RequestModuleInterface<IServiceThrottleModule>(); | ||
120 | } | 119 | } |
121 | 120 | ||
122 | public void PostInitialise() | 121 | public void PostInitialise() |
@@ -143,7 +142,6 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
143 | s.ForEachSOG(delegate(SceneObjectGroup sog) { CacheCreators(sog); }); | 142 | s.ForEachSOG(delegate(SceneObjectGroup sog) { CacheCreators(sog); }); |
144 | } | 143 | } |
145 | 144 | ||
146 | |||
147 | void EventManager_OnNewClient(IClientAPI client) | 145 | void EventManager_OnNewClient(IClientAPI client) |
148 | { | 146 | { |
149 | client.OnConnectionClosed += new Action<IClientAPI>(HandleConnectionClosed); | 147 | client.OnConnectionClosed += new Action<IClientAPI>(HandleConnectionClosed); |
@@ -157,21 +155,43 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
157 | client.OnAvatarPickerRequest -= new AvatarPickerRequest(HandleAvatarPickerRequest); | 155 | client.OnAvatarPickerRequest -= new AvatarPickerRequest(HandleAvatarPickerRequest); |
158 | } | 156 | } |
159 | 157 | ||
160 | void HandleUUIDNameRequest(UUID uuid, IClientAPI remote_client) | 158 | void HandleUUIDNameRequest(UUID uuid, IClientAPI client) |
161 | { | 159 | { |
160 | // m_log.DebugFormat( | ||
161 | // "[USER MANAGEMENT MODULE]: Handling request for name binding of UUID {0} from {1}", | ||
162 | // uuid, remote_client.Name); | ||
163 | |||
162 | if (m_Scenes[0].LibraryService != null && (m_Scenes[0].LibraryService.LibraryRootFolder.Owner == uuid)) | 164 | if (m_Scenes[0].LibraryService != null && (m_Scenes[0].LibraryService.LibraryRootFolder.Owner == uuid)) |
163 | { | 165 | { |
164 | remote_client.SendNameReply(uuid, "Mr", "OpenSim"); | 166 | client.SendNameReply(uuid, "Mr", "OpenSim"); |
165 | } | 167 | } |
166 | else | 168 | else |
167 | { | 169 | { |
168 | string[] names = GetUserNames(uuid); | 170 | string[] names = new string[2]; |
169 | if (names.Length == 2) | 171 | if (TryGetUserNamesFromCache(uuid, names)) |
170 | { | 172 | { |
171 | //m_log.DebugFormat("[XXX] HandleUUIDNameRequest {0} is {1} {2}", uuid, names[0], names[1]); | 173 | client.SendNameReply(uuid, names[0], names[1]); |
172 | remote_client.SendNameReply(uuid, names[0], names[1]); | 174 | return; |
173 | } | 175 | } |
174 | 176 | ||
177 | // Not found in cache, queue continuation | ||
178 | m_ServiceThrottle.Enqueue("name", uuid.ToString(), delegate | ||
179 | { | ||
180 | //m_log.DebugFormat("[YYY]: Name request {0}", uuid); | ||
181 | |||
182 | // As least upto September 2013, clients permanently cache UUID -> Name bindings. Some clients | ||
183 | // appear to clear this when the user asks it to clear the cache, but others may not. | ||
184 | // | ||
185 | // So to avoid clients | ||
186 | // (particularly Hypergrid clients) permanently binding "Unknown User" to a given UUID, we will | ||
187 | // instead drop the request entirely. | ||
188 | if (TryGetUserNames(uuid, names)) | ||
189 | client.SendNameReply(uuid, names[0], names[1]); | ||
190 | // else | ||
191 | // m_log.DebugFormat( | ||
192 | // "[USER MANAGEMENT MODULE]: No bound name for {0} found, ignoring request from {1}", | ||
193 | // uuid, client.Name); | ||
194 | }); | ||
175 | } | 195 | } |
176 | } | 196 | } |
177 | 197 | ||
@@ -181,29 +201,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
181 | 201 | ||
182 | m_log.DebugFormat("[USER MANAGEMENT MODULE]: HandleAvatarPickerRequest for {0}", query); | 202 | m_log.DebugFormat("[USER MANAGEMENT MODULE]: HandleAvatarPickerRequest for {0}", query); |
183 | 203 | ||
184 | // searhc the user accounts service | 204 | List<UserData> users = GetUserData(query, 500, 1); |
185 | List<UserAccount> accs = m_Scenes[0].UserAccountService.GetUserAccounts(m_Scenes[0].RegionInfo.ScopeID, query); | ||
186 | |||
187 | List<UserData> users = new List<UserData>(); | ||
188 | if (accs != null) | ||
189 | { | ||
190 | foreach (UserAccount acc in accs) | ||
191 | { | ||
192 | UserData ud = new UserData(); | ||
193 | ud.FirstName = acc.FirstName; | ||
194 | ud.LastName = acc.LastName; | ||
195 | ud.Id = acc.PrincipalID; | ||
196 | users.Add(ud); | ||
197 | } | ||
198 | } | ||
199 | |||
200 | // search the local cache | ||
201 | foreach (UserData data in m_UserCache.Values) | ||
202 | if (users.Find(delegate(UserData d) { return d.Id == data.Id; }) == null && | ||
203 | (data.FirstName.StartsWith(query) || data.LastName.StartsWith(query))) | ||
204 | users.Add(data); | ||
205 | |||
206 | AddAdditionalUsers(avatarID, query, users); | ||
207 | 205 | ||
208 | AvatarPickerReplyPacket replyPacket = (AvatarPickerReplyPacket)PacketPool.Instance.GetPacket(PacketType.AvatarPickerReply); | 206 | AvatarPickerReplyPacket replyPacket = (AvatarPickerReplyPacket)PacketPool.Instance.GetPacket(PacketType.AvatarPickerReply); |
209 | // TODO: don't create new blocks if recycling an old packet | 207 | // TODO: don't create new blocks if recycling an old packet |
@@ -249,12 +247,51 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
249 | client.SendAvatarPickerReply(agent_data, data_args); | 247 | client.SendAvatarPickerReply(agent_data, data_args); |
250 | } | 248 | } |
251 | 249 | ||
252 | protected virtual void AddAdditionalUsers(UUID avatarID, string query, List<UserData> users) | 250 | protected virtual void AddAdditionalUsers(string query, List<UserData> users) |
253 | { | 251 | { |
254 | } | 252 | } |
255 | 253 | ||
256 | #endregion Event Handlers | 254 | #endregion Event Handlers |
257 | 255 | ||
256 | #region IPeople | ||
257 | |||
258 | public List<UserData> GetUserData(string query, int page_size, int page_number) | ||
259 | { | ||
260 | // search the user accounts service | ||
261 | List<UserAccount> accs = m_Scenes[0].UserAccountService.GetUserAccounts(m_Scenes[0].RegionInfo.ScopeID, query); | ||
262 | |||
263 | List<UserData> users = new List<UserData>(); | ||
264 | if (accs != null) | ||
265 | { | ||
266 | foreach (UserAccount acc in accs) | ||
267 | { | ||
268 | UserData ud = new UserData(); | ||
269 | ud.FirstName = acc.FirstName; | ||
270 | ud.LastName = acc.LastName; | ||
271 | ud.Id = acc.PrincipalID; | ||
272 | users.Add(ud); | ||
273 | } | ||
274 | } | ||
275 | |||
276 | // search the local cache | ||
277 | lock (m_UserCache) | ||
278 | { | ||
279 | foreach (UserData data in m_UserCache.Values) | ||
280 | { | ||
281 | if (users.Find(delegate(UserData d) { return d.Id == data.Id; }) == null && | ||
282 | (data.FirstName.ToLower().StartsWith(query.ToLower()) || data.LastName.ToLower().StartsWith(query.ToLower()))) | ||
283 | users.Add(data); | ||
284 | } | ||
285 | } | ||
286 | |||
287 | AddAdditionalUsers(query, users); | ||
288 | |||
289 | return users; | ||
290 | |||
291 | } | ||
292 | |||
293 | #endregion IPeople | ||
294 | |||
258 | private void CacheCreators(SceneObjectGroup sog) | 295 | private void CacheCreators(SceneObjectGroup sog) |
259 | { | 296 | { |
260 | //m_log.DebugFormat("[USER MANAGEMENT MODULE]: processing {0} {1}; {2}", sog.RootPart.Name, sog.RootPart.CreatorData, sog.RootPart.CreatorIdentification); | 297 | //m_log.DebugFormat("[USER MANAGEMENT MODULE]: processing {0} {1}; {2}", sog.RootPart.Name, sog.RootPart.CreatorData, sog.RootPart.CreatorIdentification); |
@@ -268,26 +305,56 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
268 | } | 305 | } |
269 | } | 306 | } |
270 | 307 | ||
271 | private string[] GetUserNames(UUID uuid) | 308 | /// <summary> |
309 | /// | ||
310 | /// </summary> | ||
311 | /// <param name="uuid"></param> | ||
312 | /// <param name="names">Caller please provide a properly instantiated array for names, string[2]</param> | ||
313 | /// <returns></returns> | ||
314 | private bool TryGetUserNames(UUID uuid, string[] names) | ||
272 | { | 315 | { |
273 | string[] returnstring = new string[2]; | 316 | if (names == null) |
317 | names = new string[2]; | ||
318 | |||
319 | if (TryGetUserNamesFromCache(uuid, names)) | ||
320 | return true; | ||
321 | |||
322 | if (TryGetUserNamesFromServices(uuid, names)) | ||
323 | return true; | ||
324 | |||
325 | return false; | ||
326 | } | ||
274 | 327 | ||
328 | private bool TryGetUserNamesFromCache(UUID uuid, string[] names) | ||
329 | { | ||
275 | lock (m_UserCache) | 330 | lock (m_UserCache) |
276 | { | 331 | { |
277 | if (m_UserCache.ContainsKey(uuid)) | 332 | if (m_UserCache.ContainsKey(uuid)) |
278 | { | 333 | { |
279 | returnstring[0] = m_UserCache[uuid].FirstName; | 334 | names[0] = m_UserCache[uuid].FirstName; |
280 | returnstring[1] = m_UserCache[uuid].LastName; | 335 | names[1] = m_UserCache[uuid].LastName; |
281 | return returnstring; | 336 | |
337 | return true; | ||
282 | } | 338 | } |
283 | } | 339 | } |
284 | 340 | ||
341 | return false; | ||
342 | } | ||
343 | |||
344 | /// <summary> | ||
345 | /// Try to get the names bound to the given uuid, from the services. | ||
346 | /// </summary> | ||
347 | /// <returns>True if the name was found, false if not.</returns> | ||
348 | /// <param name='uuid'></param> | ||
349 | /// <param name='names'>The array of names if found. If not found, then names[0] = "Unknown" and names[1] = "User"</param> | ||
350 | private bool TryGetUserNamesFromServices(UUID uuid, string[] names) | ||
351 | { | ||
285 | UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(UUID.Zero, uuid); | 352 | UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(UUID.Zero, uuid); |
286 | 353 | ||
287 | if (account != null) | 354 | if (account != null) |
288 | { | 355 | { |
289 | returnstring[0] = account.FirstName; | 356 | names[0] = account.FirstName; |
290 | returnstring[1] = account.LastName; | 357 | names[1] = account.LastName; |
291 | 358 | ||
292 | UserData user = new UserData(); | 359 | UserData user = new UserData(); |
293 | user.FirstName = account.FirstName; | 360 | user.FirstName = account.FirstName; |
@@ -295,14 +362,42 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
295 | 362 | ||
296 | lock (m_UserCache) | 363 | lock (m_UserCache) |
297 | m_UserCache[uuid] = user; | 364 | m_UserCache[uuid] = user; |
365 | |||
366 | return true; | ||
298 | } | 367 | } |
299 | else | 368 | else |
300 | { | 369 | { |
301 | returnstring[0] = "Unknown"; | 370 | // Let's try the GridUser service |
302 | returnstring[1] = "User"; | 371 | GridUserInfo uInfo = m_Scenes[0].GridUserService.GetGridUserInfo(uuid.ToString()); |
303 | } | 372 | if (uInfo != null) |
373 | { | ||
374 | string url, first, last, tmp; | ||
375 | UUID u; | ||
376 | if (Util.ParseUniversalUserIdentifier(uInfo.UserID, out u, out url, out first, out last, out tmp)) | ||
377 | { | ||
378 | AddUser(uuid, first, last, url); | ||
379 | |||
380 | if (m_UserCache.ContainsKey(uuid)) | ||
381 | { | ||
382 | names[0] = m_UserCache[uuid].FirstName; | ||
383 | names[1] = m_UserCache[uuid].LastName; | ||
384 | |||
385 | return true; | ||
386 | } | ||
387 | } | ||
388 | else | ||
389 | m_log.DebugFormat("[USER MANAGEMENT MODULE]: Unable to parse UUI {0}", uInfo.UserID); | ||
390 | } | ||
391 | else | ||
392 | { | ||
393 | m_log.DebugFormat("[USER MANAGEMENT MODULE]: No grid user found for {0}", uuid); | ||
394 | } | ||
304 | 395 | ||
305 | return returnstring; | 396 | names[0] = "Unknown"; |
397 | names[1] = "UserUMMTGUN9"; | ||
398 | |||
399 | return false; | ||
400 | } | ||
306 | } | 401 | } |
307 | 402 | ||
308 | #region IUserManagement | 403 | #region IUserManagement |
@@ -338,16 +433,11 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
338 | 433 | ||
339 | public string GetUserName(UUID uuid) | 434 | public string GetUserName(UUID uuid) |
340 | { | 435 | { |
341 | string[] names = GetUserNames(uuid); | 436 | string[] names = new string[2]; |
342 | if (names.Length == 2) | 437 | TryGetUserNames(uuid, names); |
343 | { | ||
344 | string firstname = names[0]; | ||
345 | string lastname = names[1]; | ||
346 | 438 | ||
347 | return firstname + " " + lastname; | 439 | return names[0] + " " + names[1]; |
348 | 440 | ||
349 | } | ||
350 | return "(hippos)"; | ||
351 | } | 441 | } |
352 | 442 | ||
353 | public string GetUserHomeURL(UUID userID) | 443 | public string GetUserHomeURL(UUID userID) |
@@ -376,7 +466,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
376 | return userdata.ServerURLs[serverType].ToString(); | 466 | return userdata.ServerURLs[serverType].ToString(); |
377 | } | 467 | } |
378 | 468 | ||
379 | if (userdata.HomeURL != null && userdata.HomeURL != string.Empty) | 469 | if (!string.IsNullOrEmpty(userdata.HomeURL)) |
380 | { | 470 | { |
381 | //m_log.DebugFormat( | 471 | //m_log.DebugFormat( |
382 | // "[USER MANAGEMENT MODULE]: Did not find url type {0} so requesting urls from '{1}' for {2}", | 472 | // "[USER MANAGEMENT MODULE]: Did not find url type {0} so requesting urls from '{1}' for {2}", |
@@ -394,14 +484,20 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
394 | 484 | ||
395 | public string GetUserUUI(UUID userID) | 485 | public string GetUserUUI(UUID userID) |
396 | { | 486 | { |
397 | UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, userID); | ||
398 | if (account != null) | ||
399 | return userID.ToString(); | ||
400 | |||
401 | UserData ud; | 487 | UserData ud; |
402 | lock (m_UserCache) | 488 | lock (m_UserCache) |
403 | m_UserCache.TryGetValue(userID, out ud); | 489 | m_UserCache.TryGetValue(userID, out ud); |
404 | 490 | ||
491 | if (ud == null) // It's not in the cache | ||
492 | { | ||
493 | string[] names = new string[2]; | ||
494 | // This will pull the data from either UserAccounts or GridUser | ||
495 | // and stick it into the cache | ||
496 | TryGetUserNamesFromServices(userID, names); | ||
497 | lock (m_UserCache) | ||
498 | m_UserCache.TryGetValue(userID, out ud); | ||
499 | } | ||
500 | |||
405 | if (ud != null) | 501 | if (ud != null) |
406 | { | 502 | { |
407 | string homeURL = ud.HomeURL; | 503 | string homeURL = ud.HomeURL; |
@@ -446,77 +542,81 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
446 | AddUser(uuid, homeURL + ";" + first + " " + last); | 542 | AddUser(uuid, homeURL + ";" + first + " " + last); |
447 | } | 543 | } |
448 | 544 | ||
449 | public void AddUser (UUID id, string creatorData) | 545 | public void AddUser(UUID id, string creatorData) |
450 | { | 546 | { |
451 | //m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, creatorData {1}", id, creatorData); | 547 | //m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, creatorData {1}", id, creatorData); |
452 | 548 | ||
453 | UserData oldUser; | 549 | UserData oldUser; |
454 | //lock the whole block - prevent concurrent update | ||
455 | lock (m_UserCache) | 550 | lock (m_UserCache) |
551 | m_UserCache.TryGetValue(id, out oldUser); | ||
552 | |||
553 | if (oldUser != null) | ||
456 | { | 554 | { |
457 | m_UserCache.TryGetValue (id, out oldUser); | 555 | if (string.IsNullOrEmpty(creatorData)) |
458 | if (oldUser != null) | ||
459 | { | 556 | { |
460 | if (creatorData == null || creatorData == String.Empty) | 557 | //ignore updates without creator data |
461 | { | 558 | return; |
462 | //ignore updates without creator data | ||
463 | return; | ||
464 | } | ||
465 | //try update unknown users | ||
466 | //and creator's home URL's | ||
467 | if ((oldUser.FirstName == "Unknown" && !creatorData.Contains ("Unknown")) || (oldUser.HomeURL != null && !creatorData.StartsWith (oldUser.HomeURL))) | ||
468 | { | ||
469 | m_UserCache.Remove (id); | ||
470 | // m_log.DebugFormat("[USER MANAGEMENT MODULE]: Re-adding user with id {0}, creatorData [{1}] and old HomeURL {2}", id, creatorData,oldUser.HomeURL); | ||
471 | } | ||
472 | else | ||
473 | { | ||
474 | //we have already a valid user within the cache | ||
475 | return; | ||
476 | } | ||
477 | } | 559 | } |
478 | 560 | ||
479 | UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount (m_Scenes [0].RegionInfo.ScopeID, id); | 561 | //try update unknown users, but don't update anyone else |
480 | 562 | if (oldUser.FirstName == "Unknown" && !creatorData.Contains("Unknown")) | |
481 | if (account != null) | ||
482 | { | 563 | { |
483 | AddUser (id, account.FirstName, account.LastName); | 564 | lock (m_UserCache) |
565 | m_UserCache.Remove(id); | ||
566 | m_log.DebugFormat("[USER MANAGEMENT MODULE]: Re-adding user with id {0}, creatorData [{1}] and old HomeURL {2}", id, creatorData, oldUser.HomeURL); | ||
484 | } | 567 | } |
485 | else | 568 | else |
486 | { | 569 | { |
487 | UserData user = new UserData (); | 570 | //we have already a valid user within the cache |
488 | user.Id = id; | 571 | return; |
572 | } | ||
573 | } | ||
489 | 574 | ||
490 | if (creatorData != null && creatorData != string.Empty) | 575 | UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, id); |
491 | { | ||
492 | //creatorData = <endpoint>;<name> | ||
493 | 576 | ||
494 | string[] parts = creatorData.Split (';'); | 577 | if (account != null) |
495 | if (parts.Length >= 1) | 578 | { |
579 | AddUser(id, account.FirstName, account.LastName); | ||
580 | } | ||
581 | else | ||
582 | { | ||
583 | UserData user = new UserData(); | ||
584 | user.Id = id; | ||
585 | |||
586 | if (!string.IsNullOrEmpty(creatorData)) | ||
587 | { | ||
588 | //creatorData = <endpoint>;<name> | ||
589 | |||
590 | string[] parts = creatorData.Split(';'); | ||
591 | if (parts.Length >= 1) | ||
592 | { | ||
593 | user.HomeURL = parts[0]; | ||
594 | try | ||
496 | { | 595 | { |
497 | user.HomeURL = parts [0]; | 596 | Uri uri = new Uri(parts[0]); |
498 | try | 597 | user.LastName = "@" + uri.Authority; |
499 | { | 598 | } |
500 | Uri uri = new Uri (parts [0]); | 599 | catch (UriFormatException) |
501 | user.LastName = "@" + uri.Authority; | 600 | { |
502 | } | 601 | m_log.DebugFormat("[SCENE]: Unable to parse Uri {0}", parts[0]); |
503 | catch (UriFormatException) | 602 | user.LastName = "@unknown"; |
504 | { | ||
505 | m_log.DebugFormat ("[SCENE]: Unable to parse Uri {0}", parts [0]); | ||
506 | user.LastName = "@unknown"; | ||
507 | } | ||
508 | } | 603 | } |
509 | if (parts.Length >= 2) | ||
510 | user.FirstName = parts [1].Replace (' ', '.'); | ||
511 | } | ||
512 | else | ||
513 | { | ||
514 | user.FirstName = "Unknown"; | ||
515 | user.LastName = "User"; | ||
516 | } | 604 | } |
517 | 605 | ||
518 | AddUserInternal (user); | 606 | if (parts.Length >= 2) |
607 | user.FirstName = parts[1].Replace(' ', '.'); | ||
608 | } | ||
609 | else | ||
610 | { | ||
611 | // Temporarily add unknown user entries of this type into the cache so that we can distinguish | ||
612 | // this source from other recent (hopefully resolved) bugs that fail to retrieve a user name binding | ||
613 | // TODO: Can be removed when GUN* unknown users have definitely dropped significantly or | ||
614 | // disappeared. | ||
615 | user.FirstName = "Unknown"; | ||
616 | user.LastName = "UserUMMAU4"; | ||
519 | } | 617 | } |
618 | |||
619 | AddUserInternal(user); | ||
520 | } | 620 | } |
521 | } | 621 | } |
522 | 622 | ||
@@ -541,9 +641,22 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
541 | 641 | ||
542 | #endregion IUserManagement | 642 | #endregion IUserManagement |
543 | 643 | ||
644 | protected void Init() | ||
645 | { | ||
646 | AddUser(UUID.Zero, "Unknown", "User"); | ||
647 | RegisterConsoleCmds(); | ||
648 | } | ||
649 | |||
544 | protected void RegisterConsoleCmds() | 650 | protected void RegisterConsoleCmds() |
545 | { | 651 | { |
546 | MainConsole.Instance.Commands.AddCommand("Users", true, | 652 | MainConsole.Instance.Commands.AddCommand("Users", true, |
653 | "show name", | ||
654 | "show name <uuid>", | ||
655 | "Show the bindings between a single user UUID and a user name", | ||
656 | String.Empty, | ||
657 | HandleShowUser); | ||
658 | |||
659 | MainConsole.Instance.Commands.AddCommand("Users", true, | ||
547 | "show names", | 660 | "show names", |
548 | "show names", | 661 | "show names", |
549 | "Show the bindings between user UUIDs and user names", | 662 | "Show the bindings between user UUIDs and user names", |
@@ -551,26 +664,56 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
551 | HandleShowUsers); | 664 | HandleShowUsers); |
552 | } | 665 | } |
553 | 666 | ||
554 | private void HandleShowUsers(string module, string[] cmd) | 667 | private void HandleShowUser(string module, string[] cmd) |
555 | { | 668 | { |
669 | if (cmd.Length < 3) | ||
670 | { | ||
671 | MainConsole.Instance.OutputFormat("Usage: show name <uuid>"); | ||
672 | return; | ||
673 | } | ||
674 | |||
675 | UUID userId; | ||
676 | if (!ConsoleUtil.TryParseConsoleUuid(MainConsole.Instance, cmd[2], out userId)) | ||
677 | return; | ||
678 | |||
679 | string[] names; | ||
680 | |||
681 | UserData ud; | ||
682 | |||
556 | lock (m_UserCache) | 683 | lock (m_UserCache) |
557 | { | 684 | { |
558 | if (m_UserCache.Count == 0) | 685 | if (!m_UserCache.TryGetValue(userId, out ud)) |
559 | { | 686 | { |
560 | MainConsole.Instance.Output("No users found"); | 687 | MainConsole.Instance.OutputFormat("No name known for user with id {0}", userId); |
561 | return; | 688 | return; |
562 | } | 689 | } |
563 | 690 | } | |
564 | MainConsole.Instance.Output("UUID User Name"); | 691 | |
565 | MainConsole.Instance.Output("-----------------------------------------------------------------------------"); | 692 | ConsoleDisplayTable cdt = new ConsoleDisplayTable(); |
693 | cdt.AddColumn("UUID", 36); | ||
694 | cdt.AddColumn("Name", 30); | ||
695 | cdt.AddColumn("HomeURL", 40); | ||
696 | cdt.AddRow(userId, string.Format("{0} {1}", ud.FirstName, ud.LastName), ud.HomeURL); | ||
697 | |||
698 | MainConsole.Instance.Output(cdt.ToString()); | ||
699 | } | ||
700 | |||
701 | private void HandleShowUsers(string module, string[] cmd) | ||
702 | { | ||
703 | ConsoleDisplayTable cdt = new ConsoleDisplayTable(); | ||
704 | cdt.AddColumn("UUID", 36); | ||
705 | cdt.AddColumn("Name", 30); | ||
706 | cdt.AddColumn("HomeURL", 40); | ||
707 | |||
708 | lock (m_UserCache) | ||
709 | { | ||
566 | foreach (KeyValuePair<UUID, UserData> kvp in m_UserCache) | 710 | foreach (KeyValuePair<UUID, UserData> kvp in m_UserCache) |
567 | { | 711 | cdt.AddRow(kvp.Key, string.Format("{0} {1}", kvp.Value.FirstName, kvp.Value.LastName), kvp.Value.HomeURL); |
568 | MainConsole.Instance.Output(String.Format("{0} {1} {2} ({3})", | ||
569 | kvp.Key, kvp.Value.FirstName, kvp.Value.LastName, kvp.Value.HomeURL)); | ||
570 | } | ||
571 | |||
572 | return; | ||
573 | } | 712 | } |
713 | |||
714 | MainConsole.Instance.Output(cdt.ToString()); | ||
574 | } | 715 | } |
716 | |||
575 | } | 717 | } |
718 | |||
576 | } \ No newline at end of file | 719 | } \ No newline at end of file |
diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs index 7b11658..8946b5c 100644 --- a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs +++ b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs | |||
@@ -31,6 +31,7 @@ using System.Reflection; | |||
31 | using log4net; | 31 | using log4net; |
32 | using Nini.Config; | 32 | using Nini.Config; |
33 | using OpenMetaverse; | 33 | using OpenMetaverse; |
34 | using OpenMetaverse.StructuredData; | ||
34 | using Mono.Addins; | 35 | using Mono.Addins; |
35 | using OpenSim.Framework; | 36 | using OpenSim.Framework; |
36 | using OpenSim.Region.CoreModules.World.WorldMap; | 37 | using OpenSim.Region.CoreModules.World.WorldMap; |
@@ -48,20 +49,63 @@ namespace OpenSim.Region.CoreModules.Hypergrid | |||
48 | // Remember the map area that each client has been exposed to in this region | 49 | // Remember the map area that each client has been exposed to in this region |
49 | private Dictionary<UUID, List<MapBlockData>> m_SeenMapBlocks = new Dictionary<UUID, List<MapBlockData>>(); | 50 | private Dictionary<UUID, List<MapBlockData>> m_SeenMapBlocks = new Dictionary<UUID, List<MapBlockData>>(); |
50 | 51 | ||
52 | private string m_MapImageServerURL = string.Empty; | ||
53 | |||
54 | private IUserManagement m_UserManagement; | ||
55 | |||
51 | #region INonSharedRegionModule Members | 56 | #region INonSharedRegionModule Members |
52 | 57 | ||
53 | public override void Initialise(IConfigSource config) | 58 | public override void Initialise(IConfigSource source) |
54 | { | 59 | { |
55 | if (Util.GetConfigVarFromSections<string>( | 60 | if (Util.GetConfigVarFromSections<string>( |
56 | config, "WorldMapModule", new string[] { "Map", "Startup" }, "WorldMap") == "HGWorldMap") | 61 | source, "WorldMapModule", new string[] { "Map", "Startup" }, "WorldMap") == "HGWorldMap") |
62 | { | ||
57 | m_Enabled = true; | 63 | m_Enabled = true; |
64 | |||
65 | m_MapImageServerURL = Util.GetConfigVarFromSections<string>(source, "MapTileURL", new string[] {"LoginService", "HGWorldMap", "SimulatorFeatures"}); | ||
66 | |||
67 | if (!string.IsNullOrEmpty(m_MapImageServerURL)) | ||
68 | { | ||
69 | m_MapImageServerURL = m_MapImageServerURL.Trim(); | ||
70 | if (!m_MapImageServerURL.EndsWith("/")) | ||
71 | m_MapImageServerURL = m_MapImageServerURL + "/"; | ||
72 | } | ||
73 | |||
74 | |||
75 | } | ||
58 | } | 76 | } |
59 | 77 | ||
60 | public override void AddRegion(Scene scene) | 78 | public override void AddRegion(Scene scene) |
61 | { | 79 | { |
80 | if (!m_Enabled) | ||
81 | return; | ||
82 | |||
62 | base.AddRegion(scene); | 83 | base.AddRegion(scene); |
63 | 84 | ||
64 | scene.EventManager.OnClientClosed += new EventManager.ClientClosed(EventManager_OnClientClosed); | 85 | scene.EventManager.OnClientClosed += EventManager_OnClientClosed; |
86 | } | ||
87 | |||
88 | public override void RegionLoaded(Scene scene) | ||
89 | { | ||
90 | if (!m_Enabled) | ||
91 | return; | ||
92 | |||
93 | base.RegionLoaded(scene); | ||
94 | ISimulatorFeaturesModule featuresModule = m_scene.RequestModuleInterface<ISimulatorFeaturesModule>(); | ||
95 | |||
96 | if (featuresModule != null) | ||
97 | featuresModule.OnSimulatorFeaturesRequest += OnSimulatorFeaturesRequest; | ||
98 | |||
99 | m_UserManagement = m_scene.RequestModuleInterface<IUserManagement>(); | ||
100 | |||
101 | } | ||
102 | |||
103 | public override void RemoveRegion(Scene scene) | ||
104 | { | ||
105 | if (!m_Enabled) | ||
106 | return; | ||
107 | |||
108 | scene.EventManager.OnClientClosed -= EventManager_OnClientClosed; | ||
65 | } | 109 | } |
66 | 110 | ||
67 | public override string Name | 111 | public override string Name |
@@ -85,7 +129,7 @@ namespace OpenSim.Region.CoreModules.Hypergrid | |||
85 | b.Access = 254; // means 'simulator is offline'. We need this because the viewer ignores 255's | 129 | b.Access = 254; // means 'simulator is offline'. We need this because the viewer ignores 255's |
86 | } | 130 | } |
87 | 131 | ||
88 | m_log.DebugFormat("[HG MAP]: Reseting {0} blocks", mapBlocks.Count); | 132 | m_log.DebugFormat("[HG MAP]: Resetting {0} blocks", mapBlocks.Count); |
89 | sp.ControllingClient.SendMapBlock(mapBlocks, 0); | 133 | sp.ControllingClient.SendMapBlock(mapBlocks, 0); |
90 | m_SeenMapBlocks.Remove(clientID); | 134 | m_SeenMapBlocks.Remove(clientID); |
91 | } | 135 | } |
@@ -115,6 +159,20 @@ namespace OpenSim.Region.CoreModules.Hypergrid | |||
115 | return mapBlocks; | 159 | return mapBlocks; |
116 | } | 160 | } |
117 | 161 | ||
162 | private void OnSimulatorFeaturesRequest(UUID agentID, ref OSDMap features) | ||
163 | { | ||
164 | if (m_UserManagement != null && !string.IsNullOrEmpty(m_MapImageServerURL) && !m_UserManagement.IsLocalGridUser(agentID)) | ||
165 | { | ||
166 | OSD extras = new OSDMap(); | ||
167 | if (features.ContainsKey("OpenSimExtras")) | ||
168 | extras = features["OpenSimExtras"]; | ||
169 | else | ||
170 | features["OpenSimExtras"] = extras; | ||
171 | |||
172 | ((OSDMap)extras)["map-server-url"] = m_MapImageServerURL; | ||
173 | |||
174 | } | ||
175 | } | ||
118 | } | 176 | } |
119 | 177 | ||
120 | class MapArea | 178 | class MapArea |
diff --git a/OpenSim/Region/CoreModules/Properties/AssemblyInfo.cs b/OpenSim/Region/CoreModules/Properties/AssemblyInfo.cs index bfe0383..9809c86 100644 --- a/OpenSim/Region/CoreModules/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/CoreModules/Properties/AssemblyInfo.cs | |||
@@ -30,7 +30,7 @@ using Mono.Addins; | |||
30 | // Build Number | 30 | // Build Number |
31 | // Revision | 31 | // Revision |
32 | // | 32 | // |
33 | [assembly: AssemblyVersion("0.7.6.*")] | 33 | [assembly: AssemblyVersion("0.8.0.*")] |
34 | 34 | ||
35 | 35 | ||
36 | [assembly: Addin("OpenSim.Region.CoreModules", "0.1")] | 36 | [assembly: Addin("OpenSim.Region.CoreModules", "0.1")] |
diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs index 2b13a8b..5541063 100644 --- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs +++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs | |||
@@ -412,7 +412,6 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
412 | //public bool HttpVerboseThrottle = true; // not implemented | 412 | //public bool HttpVerboseThrottle = true; // not implemented |
413 | public List<string> HttpCustomHeaders = null; | 413 | public List<string> HttpCustomHeaders = null; |
414 | public bool HttpPragmaNoCache = true; | 414 | public bool HttpPragmaNoCache = true; |
415 | private Thread httpThread; | ||
416 | 415 | ||
417 | // Request info | 416 | // Request info |
418 | private UUID _itemID; | 417 | private UUID _itemID; |
@@ -501,9 +500,9 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
501 | Request.Headers.Add(HttpCustomHeaders[i], | 500 | Request.Headers.Add(HttpCustomHeaders[i], |
502 | HttpCustomHeaders[i+1]); | 501 | HttpCustomHeaders[i+1]); |
503 | } | 502 | } |
504 | if (proxyurl != null && proxyurl.Length > 0) | 503 | if (!string.IsNullOrEmpty(proxyurl)) |
505 | { | 504 | { |
506 | if (proxyexcepts != null && proxyexcepts.Length > 0) | 505 | if (!string.IsNullOrEmpty(proxyexcepts)) |
507 | { | 506 | { |
508 | string[] elist = proxyexcepts.Split(';'); | 507 | string[] elist = proxyexcepts.Split(';'); |
509 | Request.Proxy = new WebProxy(proxyurl, true, elist); | 508 | Request.Proxy = new WebProxy(proxyurl, true, elist); |
@@ -521,7 +520,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
521 | Request.Headers[entry.Key] = entry.Value; | 520 | Request.Headers[entry.Key] = entry.Value; |
522 | 521 | ||
523 | // Encode outbound data | 522 | // Encode outbound data |
524 | if (OutboundBody.Length > 0) | 523 | if (!string.IsNullOrEmpty(OutboundBody)) |
525 | { | 524 | { |
526 | byte[] data = Util.UTF8.GetBytes(OutboundBody); | 525 | byte[] data = Util.UTF8.GetBytes(OutboundBody); |
527 | 526 | ||
@@ -622,7 +621,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest | |||
622 | { | 621 | { |
623 | if (!WorkItem.Cancel()) | 622 | if (!WorkItem.Cancel()) |
624 | { | 623 | { |
625 | WorkItem.Abort(); | 624 | WorkItem.Cancel(true); |
626 | } | 625 | } |
627 | } | 626 | } |
628 | catch (Exception) | 627 | catch (Exception) |
diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/Tests/ScriptsHttpRequestsTests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/Tests/ScriptsHttpRequestsTests.cs new file mode 100644 index 0000000..e812d81 --- /dev/null +++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/Tests/ScriptsHttpRequestsTests.cs | |||
@@ -0,0 +1,198 @@ | |||
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.IO; | ||
31 | using System.Net; | ||
32 | using System.Reflection; | ||
33 | using System.Runtime.Serialization; | ||
34 | using System.Text; | ||
35 | using System.Threading; | ||
36 | using log4net.Config; | ||
37 | using NUnit.Framework; | ||
38 | using OpenMetaverse; | ||
39 | using OpenMetaverse.Assets; | ||
40 | using OpenSim.Framework; | ||
41 | using OpenSim.Region.CoreModules.Scripting.HttpRequest; | ||
42 | using OpenSim.Region.Framework.Scenes; | ||
43 | using OpenSim.Tests.Common; | ||
44 | using OpenSim.Tests.Common.Mock; | ||
45 | |||
46 | namespace OpenSim.Region.CoreModules.Scripting.HttpRequest.Tests | ||
47 | { | ||
48 | class TestWebRequestCreate : IWebRequestCreate | ||
49 | { | ||
50 | public TestWebRequest NextRequest { get; set; } | ||
51 | |||
52 | public WebRequest Create(Uri uri) | ||
53 | { | ||
54 | // NextRequest.RequestUri = uri; | ||
55 | |||
56 | return NextRequest; | ||
57 | |||
58 | // return new TestWebRequest(new SerializationInfo(typeof(TestWebRequest), new FormatterConverter()), new StreamingContext()); | ||
59 | } | ||
60 | } | ||
61 | |||
62 | class TestWebRequest : WebRequest | ||
63 | { | ||
64 | public override string ContentType { get; set; } | ||
65 | public override string Method { get; set; } | ||
66 | |||
67 | public Func<IAsyncResult, WebResponse> OnEndGetResponse { get; set; } | ||
68 | |||
69 | public TestWebRequest() : base() | ||
70 | { | ||
71 | // Console.WriteLine("created"); | ||
72 | } | ||
73 | |||
74 | // public TestWebRequest(SerializationInfo serializationInfo, StreamingContext streamingContext) | ||
75 | // : base(serializationInfo, streamingContext) | ||
76 | // { | ||
77 | // Console.WriteLine("created"); | ||
78 | // } | ||
79 | |||
80 | public override IAsyncResult BeginGetResponse(AsyncCallback callback, object state) | ||
81 | { | ||
82 | // Console.WriteLine("bish"); | ||
83 | TestAsyncResult tasr = new TestAsyncResult(); | ||
84 | callback(tasr); | ||
85 | |||
86 | return tasr; | ||
87 | } | ||
88 | |||
89 | public override WebResponse EndGetResponse(IAsyncResult asyncResult) | ||
90 | { | ||
91 | // Console.WriteLine("bosh"); | ||
92 | return OnEndGetResponse(asyncResult); | ||
93 | } | ||
94 | } | ||
95 | |||
96 | class TestHttpWebResponse : HttpWebResponse | ||
97 | { | ||
98 | public string Response { get; set; } | ||
99 | |||
100 | public TestHttpWebResponse(SerializationInfo serializationInfo, StreamingContext streamingContext) | ||
101 | : base(serializationInfo, streamingContext) {} | ||
102 | |||
103 | public override Stream GetResponseStream() | ||
104 | { | ||
105 | return new MemoryStream(Encoding.UTF8.GetBytes(Response)); | ||
106 | } | ||
107 | } | ||
108 | |||
109 | class TestAsyncResult : IAsyncResult | ||
110 | { | ||
111 | WaitHandle m_wh = new ManualResetEvent(true); | ||
112 | |||
113 | object IAsyncResult.AsyncState | ||
114 | { | ||
115 | get { | ||
116 | throw new System.NotImplementedException (); | ||
117 | } | ||
118 | } | ||
119 | |||
120 | WaitHandle IAsyncResult.AsyncWaitHandle | ||
121 | { | ||
122 | get { return m_wh; } | ||
123 | } | ||
124 | |||
125 | bool IAsyncResult.CompletedSynchronously | ||
126 | { | ||
127 | get { return false; } | ||
128 | } | ||
129 | |||
130 | bool IAsyncResult.IsCompleted | ||
131 | { | ||
132 | get { return true; } | ||
133 | } | ||
134 | } | ||
135 | |||
136 | /// <summary> | ||
137 | /// Test script http request code. | ||
138 | /// </summary> | ||
139 | /// <remarks> | ||
140 | /// This class uses some very hacky workarounds in order to mock HttpWebResponse which are Mono dependent (though | ||
141 | /// alternative code can be written to make this work for Windows). However, the value of being able to | ||
142 | /// regression test this kind of code is very high. | ||
143 | /// </remarks> | ||
144 | [TestFixture] | ||
145 | public class ScriptsHttpRequestsTests : OpenSimTestCase | ||
146 | { | ||
147 | /// <summary> | ||
148 | /// Test what happens when we get a 404 response from a call. | ||
149 | /// </summary> | ||
150 | [Test] | ||
151 | public void Test404Response() | ||
152 | { | ||
153 | TestHelpers.InMethod(); | ||
154 | // TestHelpers.EnableLogging(); | ||
155 | |||
156 | if (!Util.IsPlatformMono) | ||
157 | Assert.Ignore("Ignoring test since can only currently run on Mono"); | ||
158 | |||
159 | string rawResponse = "boom"; | ||
160 | |||
161 | TestWebRequestCreate twrc = new TestWebRequestCreate(); | ||
162 | |||
163 | TestWebRequest twr = new TestWebRequest(); | ||
164 | //twr.OnEndGetResponse += ar => new TestHttpWebResponse(null, new StreamingContext()); | ||
165 | twr.OnEndGetResponse += ar => | ||
166 | { | ||
167 | SerializationInfo si = new SerializationInfo(typeof(HttpWebResponse), new FormatterConverter()); | ||
168 | StreamingContext sc = new StreamingContext(); | ||
169 | // WebHeaderCollection headers = new WebHeaderCollection(); | ||
170 | // si.AddValue("m_HttpResponseHeaders", headers); | ||
171 | si.AddValue("uri", new Uri("test://arrg")); | ||
172 | // si.AddValue("m_Certificate", null); | ||
173 | si.AddValue("version", HttpVersion.Version11); | ||
174 | si.AddValue("statusCode", HttpStatusCode.NotFound); | ||
175 | si.AddValue("contentLength", 0); | ||
176 | si.AddValue("method", "GET"); | ||
177 | si.AddValue("statusDescription", "Not Found"); | ||
178 | si.AddValue("contentType", null); | ||
179 | si.AddValue("cookieCollection", new CookieCollection()); | ||
180 | |||
181 | TestHttpWebResponse thwr = new TestHttpWebResponse(si, sc); | ||
182 | thwr.Response = rawResponse; | ||
183 | |||
184 | throw new WebException("no message", null, WebExceptionStatus.ProtocolError, thwr); | ||
185 | }; | ||
186 | |||
187 | twrc.NextRequest = twr; | ||
188 | |||
189 | WebRequest.RegisterPrefix("test", twrc); | ||
190 | HttpRequestClass hr = new HttpRequestClass(); | ||
191 | hr.Url = "test://something"; | ||
192 | hr.SendRequest(); | ||
193 | |||
194 | Assert.That(hr.Status, Is.EqualTo((int)HttpStatusCode.NotFound)); | ||
195 | Assert.That(hr.ResponseBody, Is.EqualTo(rawResponse)); | ||
196 | } | ||
197 | } | ||
198 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs index 2a4d440..1983fed 100644 --- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs | |||
@@ -219,7 +219,8 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
219 | 219 | ||
220 | string uri = "/lslhttp/" + urlcode.ToString(); | 220 | string uri = "/lslhttp/" + urlcode.ToString(); |
221 | 221 | ||
222 | PollServiceEventArgs args = new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode, 25000); | 222 | PollServiceEventArgs args |
223 | = new PollServiceEventArgs(HttpRequestHandler, uri, HasEvents, GetEvents, NoEvents, urlcode, 25000); | ||
223 | args.Type = PollServiceEventArgs.EventType.LslHttp; | 224 | args.Type = PollServiceEventArgs.EventType.LslHttp; |
224 | m_HttpServer.AddPollServiceHTTPHandler(uri, args); | 225 | m_HttpServer.AddPollServiceHTTPHandler(uri, args); |
225 | 226 | ||
@@ -266,7 +267,8 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp | |||
266 | 267 | ||
267 | string uri = "/lslhttps/" + urlcode.ToString(); | 268 | string uri = "/lslhttps/" + urlcode.ToString(); |
268 | 269 | ||
269 | PollServiceEventArgs args = new PollServiceEventArgs(HttpRequestHandler, HasEvents, GetEvents, NoEvents, urlcode, 25000); | 270 | PollServiceEventArgs args |
271 | = new PollServiceEventArgs(HttpRequestHandler, uri, HasEvents, GetEvents, NoEvents, urlcode, 25000); | ||
270 | args.Type = PollServiceEventArgs.EventType.LslHttp; | 272 | args.Type = PollServiceEventArgs.EventType.LslHttp; |
271 | m_HttpsServer.AddPollServiceHTTPHandler(uri, args); | 273 | m_HttpsServer.AddPollServiceHTTPHandler(uri, args); |
272 | 274 | ||
diff --git a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs index 65737fa..baf9f2f 100644 --- a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs | |||
@@ -161,9 +161,9 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL | |||
161 | { | 161 | { |
162 | WebRequest request = HttpWebRequest.Create(url); | 162 | WebRequest request = HttpWebRequest.Create(url); |
163 | 163 | ||
164 | if (m_proxyurl != null && m_proxyurl.Length > 0) | 164 | if (!string.IsNullOrEmpty(m_proxyurl)) |
165 | { | 165 | { |
166 | if (m_proxyexcepts != null && m_proxyexcepts.Length > 0) | 166 | if (!string.IsNullOrEmpty(m_proxyexcepts)) |
167 | { | 167 | { |
168 | string[] elist = m_proxyexcepts.Split(';'); | 168 | string[] elist = m_proxyexcepts.Split(';'); |
169 | request.Proxy = new WebProxy(m_proxyurl, true, elist); | 169 | request.Proxy = new WebProxy(m_proxyurl, true, elist); |
diff --git a/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs b/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs index fccf053..ad33f23 100644 --- a/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs | |||
@@ -45,6 +45,7 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms | |||
45 | { | 45 | { |
46 | private static readonly ILog m_log = | 46 | private static readonly ILog m_log = |
47 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 47 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
48 | private static string LogHeader = "[MODULE COMMS]"; | ||
48 | 49 | ||
49 | private Dictionary<string,object> m_constants = new Dictionary<string,object>(); | 50 | private Dictionary<string,object> m_constants = new Dictionary<string,object>(); |
50 | 51 | ||
@@ -148,7 +149,7 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms | |||
148 | MethodInfo mi = GetMethodInfoFromType(target.GetType(), meth, true); | 149 | MethodInfo mi = GetMethodInfoFromType(target.GetType(), meth, true); |
149 | if (mi == null) | 150 | if (mi == null) |
150 | { | 151 | { |
151 | m_log.WarnFormat("[MODULE COMMANDS] Failed to register method {0}", meth); | 152 | m_log.WarnFormat("{0} Failed to register method {1}", LogHeader, meth); |
152 | return; | 153 | return; |
153 | } | 154 | } |
154 | 155 | ||
@@ -163,9 +164,9 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms | |||
163 | 164 | ||
164 | public void RegisterScriptInvocation(object target, MethodInfo mi) | 165 | public void RegisterScriptInvocation(object target, MethodInfo mi) |
165 | { | 166 | { |
166 | m_log.DebugFormat("[MODULE COMMANDS] Register method {0} from type {1}", mi.Name, (target is Type) ? ((Type)target).Name : target.GetType().Name); | 167 | // m_log.DebugFormat("[MODULE COMMANDS] Register method {0} from type {1}", mi.Name, (target is Type) ? ((Type)target).Name : target.GetType().Name); |
167 | 168 | ||
168 | Type delegateType; | 169 | Type delegateType = typeof(void); |
169 | List<Type> typeArgs = mi.GetParameters() | 170 | List<Type> typeArgs = mi.GetParameters() |
170 | .Select(p => p.ParameterType) | 171 | .Select(p => p.ParameterType) |
171 | .ToList(); | 172 | .ToList(); |
@@ -176,8 +177,16 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms | |||
176 | } | 177 | } |
177 | else | 178 | else |
178 | { | 179 | { |
179 | typeArgs.Add(mi.ReturnType); | 180 | try |
180 | delegateType = Expression.GetFuncType(typeArgs.ToArray()); | 181 | { |
182 | typeArgs.Add(mi.ReturnType); | ||
183 | delegateType = Expression.GetFuncType(typeArgs.ToArray()); | ||
184 | } | ||
185 | catch (Exception e) | ||
186 | { | ||
187 | m_log.ErrorFormat("{0} Failed to create function signature. Most likely more than 5 parameters. Method={1}. Error={2}", | ||
188 | LogHeader, mi.Name, e); | ||
189 | } | ||
181 | } | 190 | } |
182 | 191 | ||
183 | Delegate fcall; | 192 | Delegate fcall; |
@@ -325,7 +334,7 @@ namespace OpenSim.Region.CoreModules.Scripting.ScriptModuleComms | |||
325 | /// </summary> | 334 | /// </summary> |
326 | public void RegisterConstant(string cname, object value) | 335 | public void RegisterConstant(string cname, object value) |
327 | { | 336 | { |
328 | m_log.DebugFormat("[MODULE COMMANDS] register constant <{0}> with value {1}",cname,value.ToString()); | 337 | // m_log.DebugFormat("[MODULE COMMANDS] register constant <{0}> with value {1}",cname,value.ToString()); |
329 | lock (m_constants) | 338 | lock (m_constants) |
330 | { | 339 | { |
331 | m_constants.Add(cname,value); | 340 | m_constants.Add(cname,value); |
diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs index 41baccc..7119137 100644 --- a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs +++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs | |||
@@ -152,7 +152,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests | |||
152 | TestHelpers.InMethod(); | 152 | TestHelpers.InMethod(); |
153 | 153 | ||
154 | string dtText | 154 | string dtText |
155 | = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World; Image http://localhost/shouldnotexist.png"; | 155 | = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World; Image http://0.0.0.0/shouldnotexist.png"; |
156 | 156 | ||
157 | SetupScene(false); | 157 | SetupScene(false); |
158 | SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene); | 158 | SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene); |
@@ -307,7 +307,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests | |||
307 | TestHelpers.InMethod(); | 307 | TestHelpers.InMethod(); |
308 | 308 | ||
309 | string dtText | 309 | string dtText |
310 | = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World; Image http://localhost/shouldnotexist.png"; | 310 | = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World; Image http://0.0.0.0/shouldnotexist.png"; |
311 | 311 | ||
312 | SetupScene(true); | 312 | SetupScene(true); |
313 | SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene); | 313 | SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene); |
diff --git a/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs b/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs index cbffca7..c6e05b1 100644 --- a/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs | |||
@@ -677,7 +677,7 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC | |||
677 | // if not, use as method name | 677 | // if not, use as method name |
678 | UUID parseUID; | 678 | UUID parseUID; |
679 | string mName = "llRemoteData"; | 679 | string mName = "llRemoteData"; |
680 | if ((Channel != null) && (Channel != "")) | 680 | if (!string.IsNullOrEmpty(Channel)) |
681 | if (!UUID.TryParse(Channel, out parseUID)) | 681 | if (!UUID.TryParse(Channel, out parseUID)) |
682 | mName = Channel; | 682 | mName = Channel; |
683 | else | 683 | else |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/UserProfiles/LocalUserProfilesServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/UserProfiles/LocalUserProfilesServiceConnector.cs new file mode 100644 index 0000000..323535a --- /dev/null +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/UserProfiles/LocalUserProfilesServiceConnector.cs | |||
@@ -0,0 +1,226 @@ | |||
1 | |||
2 | /* | ||
3 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
4 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
5 | * | ||
6 | * Redistribution and use in source and binary forms, with or without | ||
7 | * modification, are permitted provided that the following conditions are met: | ||
8 | * * Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * * Redistributions in binary form must reproduce the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer in the | ||
12 | * documentation and/or other materials provided with the distribution. | ||
13 | * * Neither the name of the OpenSimulator Project nor the | ||
14 | * names of its contributors may be used to endorse or promote products | ||
15 | * derived from this software without specific prior written permission. | ||
16 | * | ||
17 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
18 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
19 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
20 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
21 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
22 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
23 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
24 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
26 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
27 | */ | ||
28 | |||
29 | using log4net; | ||
30 | using Mono.Addins; | ||
31 | using Nini.Config; | ||
32 | using System; | ||
33 | using System.Collections.Generic; | ||
34 | using System.Reflection; | ||
35 | using OpenSim.Framework; | ||
36 | using OpenSim.Framework.Console; | ||
37 | using OpenSim.Server.Base; | ||
38 | using OpenSim.Server.Handlers; | ||
39 | using OpenSim.Region.Framework.Interfaces; | ||
40 | using OpenSim.Framework.Servers.HttpServer; | ||
41 | using OpenSim.Framework.Servers; | ||
42 | using OpenSim.Region.Framework.Scenes; | ||
43 | using OpenSim.Services.Interfaces; | ||
44 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; | ||
45 | using OpenMetaverse; | ||
46 | |||
47 | namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Profile | ||
48 | { | ||
49 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LocalUserProfilesServicesConnector")] | ||
50 | public class LocalUserProfilesServicesConnector : ISharedRegionModule | ||
51 | { | ||
52 | private static readonly ILog m_log = | ||
53 | LogManager.GetLogger( | ||
54 | MethodBase.GetCurrentMethod().DeclaringType); | ||
55 | |||
56 | private Dictionary<UUID, Scene> regions = new Dictionary<UUID, Scene>(); | ||
57 | |||
58 | public IUserProfilesService ServiceModule | ||
59 | { | ||
60 | get; private set; | ||
61 | } | ||
62 | |||
63 | public bool Enabled | ||
64 | { | ||
65 | get; private set; | ||
66 | } | ||
67 | |||
68 | public string Name | ||
69 | { | ||
70 | get | ||
71 | { | ||
72 | return "LocalUserProfilesServicesConnector"; | ||
73 | } | ||
74 | } | ||
75 | |||
76 | public string ConfigName | ||
77 | { | ||
78 | get; private set; | ||
79 | } | ||
80 | |||
81 | public Type ReplaceableInterface | ||
82 | { | ||
83 | get { return null; } | ||
84 | } | ||
85 | |||
86 | public LocalUserProfilesServicesConnector() | ||
87 | { | ||
88 | m_log.Debug("[LOCAL USERPROFILES SERVICE CONNECTOR]: LocalUserProfileServicesConnector no params"); | ||
89 | } | ||
90 | |||
91 | public LocalUserProfilesServicesConnector(IConfigSource source) | ||
92 | { | ||
93 | m_log.Debug("[LOCAL USERPROFILES SERVICE CONNECTOR]: LocalUserProfileServicesConnector instantiated directly."); | ||
94 | InitialiseService(source); | ||
95 | } | ||
96 | |||
97 | public void InitialiseService(IConfigSource source) | ||
98 | { | ||
99 | ConfigName = "UserProfilesService"; | ||
100 | |||
101 | // Instantiate the request handler | ||
102 | IHttpServer Server = MainServer.Instance; | ||
103 | |||
104 | IConfig config = source.Configs[ConfigName]; | ||
105 | if (config == null) | ||
106 | { | ||
107 | m_log.Error("[LOCAL USERPROFILES SERVICE CONNECTOR]: UserProfilesService missing from OpenSim.ini"); | ||
108 | return; | ||
109 | } | ||
110 | |||
111 | if(!config.GetBoolean("Enabled",false)) | ||
112 | { | ||
113 | Enabled = false; | ||
114 | return; | ||
115 | } | ||
116 | |||
117 | Enabled = true; | ||
118 | |||
119 | string serviceDll = config.GetString("LocalServiceModule", | ||
120 | String.Empty); | ||
121 | |||
122 | if (serviceDll == String.Empty) | ||
123 | { | ||
124 | m_log.Error("[LOCAL USERPROFILES SERVICE CONNECTOR]: No LocalServiceModule named in section UserProfilesService"); | ||
125 | return; | ||
126 | } | ||
127 | |||
128 | Object[] args = new Object[] { source, ConfigName }; | ||
129 | ServiceModule = | ||
130 | ServerUtils.LoadPlugin<IUserProfilesService>(serviceDll, | ||
131 | args); | ||
132 | |||
133 | if (ServiceModule == null) | ||
134 | { | ||
135 | m_log.Error("[LOCAL USERPROFILES SERVICE CONNECTOR]: Can't load user profiles service"); | ||
136 | return; | ||
137 | } | ||
138 | |||
139 | Enabled = true; | ||
140 | |||
141 | JsonRpcProfileHandlers handler = new JsonRpcProfileHandlers(ServiceModule); | ||
142 | |||
143 | Server.AddJsonRPCHandler("avatarclassifiedsrequest", handler.AvatarClassifiedsRequest); | ||
144 | Server.AddJsonRPCHandler("classified_update", handler.ClassifiedUpdate); | ||
145 | Server.AddJsonRPCHandler("classifieds_info_query", handler.ClassifiedInfoRequest); | ||
146 | Server.AddJsonRPCHandler("classified_delete", handler.ClassifiedDelete); | ||
147 | Server.AddJsonRPCHandler("avatarpicksrequest", handler.AvatarPicksRequest); | ||
148 | Server.AddJsonRPCHandler("pickinforequest", handler.PickInfoRequest); | ||
149 | Server.AddJsonRPCHandler("picks_update", handler.PicksUpdate); | ||
150 | Server.AddJsonRPCHandler("picks_delete", handler.PicksDelete); | ||
151 | Server.AddJsonRPCHandler("avatarnotesrequest", handler.AvatarNotesRequest); | ||
152 | Server.AddJsonRPCHandler("avatar_notes_update", handler.NotesUpdate); | ||
153 | Server.AddJsonRPCHandler("avatar_properties_request", handler.AvatarPropertiesRequest); | ||
154 | Server.AddJsonRPCHandler("avatar_properties_update", handler.AvatarPropertiesUpdate); | ||
155 | Server.AddJsonRPCHandler("avatar_interests_update", handler.AvatarInterestsUpdate); | ||
156 | Server.AddJsonRPCHandler("image_assets_request", handler.AvatarImageAssetsRequest); | ||
157 | Server.AddJsonRPCHandler("user_data_request", handler.RequestUserAppData); | ||
158 | Server.AddJsonRPCHandler("user_data_update", handler.UpdateUserAppData); | ||
159 | |||
160 | } | ||
161 | |||
162 | #region ISharedRegionModule implementation | ||
163 | |||
164 | void ISharedRegionModule.PostInitialise() | ||
165 | { | ||
166 | if(!Enabled) | ||
167 | return; | ||
168 | } | ||
169 | |||
170 | #endregion | ||
171 | |||
172 | #region IRegionModuleBase implementation | ||
173 | |||
174 | void IRegionModuleBase.Initialise(IConfigSource source) | ||
175 | { | ||
176 | IConfig moduleConfig = source.Configs["Modules"]; | ||
177 | if (moduleConfig != null) | ||
178 | { | ||
179 | string name = moduleConfig.GetString("UserProfilesServices", ""); | ||
180 | if (name == Name) | ||
181 | { | ||
182 | InitialiseService(source); | ||
183 | m_log.Info("[LOCAL USERPROFILES SERVICE CONNECTOR]: Local user profiles connector enabled"); | ||
184 | } | ||
185 | } | ||
186 | } | ||
187 | |||
188 | void IRegionModuleBase.Close() | ||
189 | { | ||
190 | return; | ||
191 | } | ||
192 | |||
193 | void IRegionModuleBase.AddRegion(Scene scene) | ||
194 | { | ||
195 | if (!Enabled) | ||
196 | return; | ||
197 | |||
198 | lock (regions) | ||
199 | { | ||
200 | if (regions.ContainsKey(scene.RegionInfo.RegionID)) | ||
201 | m_log.ErrorFormat("[LOCAL USERPROFILES SERVICE CONNECTOR]: simulator seems to have more than one region with the same UUID. Please correct this!"); | ||
202 | else | ||
203 | regions.Add(scene.RegionInfo.RegionID, scene); | ||
204 | } | ||
205 | } | ||
206 | |||
207 | void IRegionModuleBase.RemoveRegion(Scene scene) | ||
208 | { | ||
209 | if (!Enabled) | ||
210 | return; | ||
211 | |||
212 | lock (regions) | ||
213 | { | ||
214 | if (regions.ContainsKey(scene.RegionInfo.RegionID)) | ||
215 | regions.Remove(scene.RegionInfo.RegionID); | ||
216 | } | ||
217 | } | ||
218 | |||
219 | void IRegionModuleBase.RegionLoaded(Scene scene) | ||
220 | { | ||
221 | if (!Enabled) | ||
222 | return; | ||
223 | } | ||
224 | #endregion | ||
225 | } | ||
226 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs index d221d68..9f58175 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs | |||
@@ -322,7 +322,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset | |||
322 | // a copy of the local asset. | 322 | // a copy of the local asset. |
323 | m_Cache.Cache(asset); | 323 | m_Cache.Cache(asset); |
324 | 324 | ||
325 | if (asset.Temporary || asset.Local) | 325 | if (asset.Local) |
326 | { | 326 | { |
327 | if (m_Cache != null) | 327 | if (m_Cache != null) |
328 | m_Cache.Cache(asset); | 328 | m_Cache.Cache(asset); |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs index 480cd69..52b1039 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs | |||
@@ -258,7 +258,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset | |||
258 | if (m_Cache != null) | 258 | if (m_Cache != null) |
259 | m_Cache.Cache(asset); | 259 | m_Cache.Cache(asset); |
260 | 260 | ||
261 | if (asset.Temporary || asset.Local) | 261 | if (asset.Local) |
262 | { | 262 | { |
263 | // m_log.DebugFormat( | 263 | // m_log.DebugFormat( |
264 | // "[LOCAL ASSET SERVICE CONNECTOR]: Returning asset {0} {1} without querying database since status Temporary = {2}, Local = {3}", | 264 | // "[LOCAL ASSET SERVICE CONNECTOR]: Returning asset {0} {1} without querying database since status Temporary = {2}, Local = {3}", |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/Tests/AssetConnectorTests.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/Tests/AssetConnectorTests.cs index 1982473..4f75191 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/Tests/AssetConnectorTests.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/Tests/AssetConnectorTests.cs | |||
@@ -42,7 +42,7 @@ using OpenSim.Tests.Common; | |||
42 | namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset.Tests | 42 | namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset.Tests |
43 | { | 43 | { |
44 | [TestFixture] | 44 | [TestFixture] |
45 | public class AssetConnectorsTests : OpenSimTestCase | 45 | public class AssetConnectorTests : OpenSimTestCase |
46 | { | 46 | { |
47 | [Test] | 47 | [Test] |
48 | public void TestAddAsset() | 48 | public void TestAddAsset() |
@@ -77,7 +77,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset.Tests | |||
77 | // TODO: Add cache and check that this does receive a copy of the asset | 77 | // TODO: Add cache and check that this does receive a copy of the asset |
78 | } | 78 | } |
79 | 79 | ||
80 | [Test] | ||
81 | public void TestAddTemporaryAsset() | 80 | public void TestAddTemporaryAsset() |
82 | { | 81 | { |
83 | TestHelpers.InMethod(); | 82 | TestHelpers.InMethod(); |
@@ -93,8 +92,45 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset.Tests | |||
93 | LocalAssetServicesConnector lasc = new LocalAssetServicesConnector(); | 92 | LocalAssetServicesConnector lasc = new LocalAssetServicesConnector(); |
94 | lasc.Initialise(config); | 93 | lasc.Initialise(config); |
95 | 94 | ||
95 | // If it is remote, it should be stored | ||
96 | AssetBase a2 = AssetHelpers.CreateNotecardAsset(); | ||
97 | a2.Local = false; | ||
98 | a2.Temporary = true; | ||
99 | |||
100 | lasc.Store(a2); | ||
101 | |||
102 | AssetBase retreivedA2 = lasc.Get(a2.ID); | ||
103 | Assert.That(retreivedA2.ID, Is.EqualTo(a2.ID)); | ||
104 | Assert.That(retreivedA2.Metadata.ID, Is.EqualTo(a2.Metadata.ID)); | ||
105 | Assert.That(retreivedA2.Data.Length, Is.EqualTo(a2.Data.Length)); | ||
106 | |||
107 | AssetMetadata retrievedA2Metadata = lasc.GetMetadata(a2.ID); | ||
108 | Assert.That(retrievedA2Metadata.ID, Is.EqualTo(a2.ID)); | ||
109 | |||
110 | byte[] retrievedA2Data = lasc.GetData(a2.ID); | ||
111 | Assert.That(retrievedA2Data.Length, Is.EqualTo(a2.Data.Length)); | ||
112 | |||
113 | // TODO: Add cache and check that this does receive a copy of the asset | ||
114 | } | ||
115 | |||
116 | [Test] | ||
117 | public void TestAddLocalAsset() | ||
118 | { | ||
119 | TestHelpers.InMethod(); | ||
120 | // TestHelpers.EnableLogging(); | ||
121 | |||
122 | IConfigSource config = new IniConfigSource(); | ||
123 | config.AddConfig("Modules"); | ||
124 | config.Configs["Modules"].Set("AssetServices", "LocalAssetServicesConnector"); | ||
125 | config.AddConfig("AssetService"); | ||
126 | config.Configs["AssetService"].Set("LocalServiceModule", "OpenSim.Services.AssetService.dll:AssetService"); | ||
127 | config.Configs["AssetService"].Set("StorageProvider", "OpenSim.Tests.Common.dll"); | ||
128 | |||
129 | LocalAssetServicesConnector lasc = new LocalAssetServicesConnector(); | ||
130 | lasc.Initialise(config); | ||
131 | |||
96 | AssetBase a1 = AssetHelpers.CreateNotecardAsset(); | 132 | AssetBase a1 = AssetHelpers.CreateNotecardAsset(); |
97 | a1.Temporary = true; | 133 | a1.Local = true; |
98 | 134 | ||
99 | lasc.Store(a1); | 135 | lasc.Store(a1); |
100 | 136 | ||
@@ -106,7 +142,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset.Tests | |||
106 | } | 142 | } |
107 | 143 | ||
108 | [Test] | 144 | [Test] |
109 | public void TestAddLocalAsset() | 145 | public void TestAddTemporaryLocalAsset() |
110 | { | 146 | { |
111 | TestHelpers.InMethod(); | 147 | TestHelpers.InMethod(); |
112 | // TestHelpers.EnableLogging(); | 148 | // TestHelpers.EnableLogging(); |
@@ -121,8 +157,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset.Tests | |||
121 | LocalAssetServicesConnector lasc = new LocalAssetServicesConnector(); | 157 | LocalAssetServicesConnector lasc = new LocalAssetServicesConnector(); |
122 | lasc.Initialise(config); | 158 | lasc.Initialise(config); |
123 | 159 | ||
160 | // If it is local, it should not be stored | ||
124 | AssetBase a1 = AssetHelpers.CreateNotecardAsset(); | 161 | AssetBase a1 = AssetHelpers.CreateNotecardAsset(); |
125 | a1.Local = true; | 162 | a1.Local = true; |
163 | a1.Temporary = true; | ||
126 | 164 | ||
127 | lasc.Store(a1); | 165 | lasc.Store(a1); |
128 | 166 | ||
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs index c0c2ca7..31ef79b 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/LocalGridServiceConnector.cs | |||
@@ -56,6 +56,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
56 | 56 | ||
57 | public LocalGridServicesConnector() | 57 | public LocalGridServicesConnector() |
58 | { | 58 | { |
59 | m_log.Debug("[LOCAL GRID SERVICE CONNECTOR]: LocalGridServicesConnector no parms."); | ||
59 | } | 60 | } |
60 | 61 | ||
61 | public LocalGridServicesConnector(IConfigSource source) | 62 | public LocalGridServicesConnector(IConfigSource source) |
@@ -142,10 +143,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
142 | 143 | ||
143 | scene.RegisterModuleInterface<IGridService>(this); | 144 | scene.RegisterModuleInterface<IGridService>(this); |
144 | 145 | ||
145 | if (m_LocalCache.ContainsKey(scene.RegionInfo.RegionID)) | 146 | lock (m_LocalCache) |
146 | m_log.ErrorFormat("[LOCAL GRID SERVICE CONNECTOR]: simulator seems to have more than one region with the same UUID. Please correct this!"); | 147 | { |
147 | else | 148 | if (m_LocalCache.ContainsKey(scene.RegionInfo.RegionID)) |
148 | m_LocalCache.Add(scene.RegionInfo.RegionID, new RegionCache(scene)); | 149 | m_log.ErrorFormat("[LOCAL GRID SERVICE CONNECTOR]: simulator seems to have more than one region with the same UUID. Please correct this!"); |
150 | else | ||
151 | m_LocalCache.Add(scene.RegionInfo.RegionID, new RegionCache(scene)); | ||
152 | } | ||
149 | } | 153 | } |
150 | 154 | ||
151 | public void RemoveRegion(Scene scene) | 155 | public void RemoveRegion(Scene scene) |
@@ -153,8 +157,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
153 | if (!m_Enabled) | 157 | if (!m_Enabled) |
154 | return; | 158 | return; |
155 | 159 | ||
156 | m_LocalCache[scene.RegionInfo.RegionID].Clear(); | 160 | lock (m_LocalCache) |
157 | m_LocalCache.Remove(scene.RegionInfo.RegionID); | 161 | { |
162 | m_LocalCache[scene.RegionInfo.RegionID].Clear(); | ||
163 | m_LocalCache.Remove(scene.RegionInfo.RegionID); | ||
164 | } | ||
158 | } | 165 | } |
159 | 166 | ||
160 | public void RegionLoaded(Scene scene) | 167 | public void RegionLoaded(Scene scene) |
@@ -191,12 +198,16 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
191 | 198 | ||
192 | // First see if it's a neighbour, even if it isn't on this sim. | 199 | // First see if it's a neighbour, even if it isn't on this sim. |
193 | // Neighbour data is cached in memory, so this is fast | 200 | // Neighbour data is cached in memory, so this is fast |
194 | foreach (RegionCache rcache in m_LocalCache.Values) | 201 | |
202 | lock (m_LocalCache) | ||
195 | { | 203 | { |
196 | region = rcache.GetRegionByPosition(x, y); | 204 | foreach (RegionCache rcache in m_LocalCache.Values) |
197 | if (region != null) | ||
198 | { | 205 | { |
199 | return region; | 206 | region = rcache.GetRegionByPosition(x, y); |
207 | if (region != null) | ||
208 | { | ||
209 | return region; | ||
210 | } | ||
200 | } | 211 | } |
201 | } | 212 | } |
202 | 213 | ||
@@ -224,6 +235,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
224 | return m_GridService.GetDefaultRegions(scopeID); | 235 | return m_GridService.GetDefaultRegions(scopeID); |
225 | } | 236 | } |
226 | 237 | ||
238 | public List<GridRegion> GetDefaultHypergridRegions(UUID scopeID) | ||
239 | { | ||
240 | return m_GridService.GetDefaultHypergridRegions(scopeID); | ||
241 | } | ||
242 | |||
227 | public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y) | 243 | public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y) |
228 | { | 244 | { |
229 | return m_GridService.GetFallbackRegions(scopeID, x, y); | 245 | return m_GridService.GetFallbackRegions(scopeID, x, y); |
@@ -245,12 +261,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
245 | { | 261 | { |
246 | System.Text.StringBuilder caps = new System.Text.StringBuilder(); | 262 | System.Text.StringBuilder caps = new System.Text.StringBuilder(); |
247 | 263 | ||
248 | foreach (KeyValuePair<UUID, RegionCache> kvp in m_LocalCache) | 264 | lock (m_LocalCache) |
249 | { | 265 | { |
250 | caps.AppendFormat("*** Neighbours of {0} ({1}) ***\n", kvp.Value.RegionName, kvp.Key); | 266 | foreach (KeyValuePair<UUID, RegionCache> kvp in m_LocalCache) |
251 | List<GridRegion> regions = kvp.Value.GetNeighbours(); | 267 | { |
252 | foreach (GridRegion r in regions) | 268 | caps.AppendFormat("*** Neighbours of {0} ({1}) ***\n", kvp.Value.RegionName, kvp.Key); |
253 | caps.AppendFormat(" {0} @ {1}-{2}\n", r.RegionName, r.RegionLocX / Constants.RegionSize, r.RegionLocY / Constants.RegionSize); | 269 | List<GridRegion> regions = kvp.Value.GetNeighbours(); |
270 | foreach (GridRegion r in regions) | ||
271 | caps.AppendFormat(" {0} @ {1}-{2}\n", r.RegionName, r.RegionLocX / Constants.RegionSize, r.RegionLocY / Constants.RegionSize); | ||
272 | } | ||
254 | } | 273 | } |
255 | 274 | ||
256 | MainConsole.Instance.Output(caps.ToString()); | 275 | MainConsole.Instance.Output(caps.ToString()); |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs index b2646ba..6a57d1f 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RemoteGridServiceConnector.cs | |||
@@ -277,6 +277,26 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid | |||
277 | return rinfo; | 277 | return rinfo; |
278 | } | 278 | } |
279 | 279 | ||
280 | public List<GridRegion> GetDefaultHypergridRegions(UUID scopeID) | ||
281 | { | ||
282 | List<GridRegion> rinfo = m_LocalGridService.GetDefaultHypergridRegions(scopeID); | ||
283 | //m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Local GetDefaultHypergridRegions {0} found {1} regions", name, rinfo.Count); | ||
284 | List<GridRegion> grinfo = m_RemoteGridService.GetDefaultHypergridRegions(scopeID); | ||
285 | |||
286 | if (grinfo != null) | ||
287 | { | ||
288 | //m_log.DebugFormat("[REMOTE GRID CONNECTOR]: Remote GetDefaultHypergridRegions {0} found {1} regions", name, grinfo.Count); | ||
289 | foreach (GridRegion r in grinfo) | ||
290 | { | ||
291 | m_RegionInfoCache.Cache(r); | ||
292 | if (rinfo.Find(delegate(GridRegion gr) { return gr.RegionID == r.RegionID; }) == null) | ||
293 | rinfo.Add(r); | ||
294 | } | ||
295 | } | ||
296 | |||
297 | return rinfo; | ||
298 | } | ||
299 | |||
280 | public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y) | 300 | public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y) |
281 | { | 301 | { |
282 | List<GridRegion> rinfo = m_LocalGridService.GetFallbackRegions(scopeID, x, y); | 302 | List<GridRegion> rinfo = m_LocalGridService.GetFallbackRegions(scopeID, x, y); |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs index 221f815..e05d186 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs | |||
@@ -81,6 +81,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser | |||
81 | 81 | ||
82 | public void OnConnectionClose(IClientAPI client) | 82 | public void OnConnectionClose(IClientAPI client) |
83 | { | 83 | { |
84 | if (client == null) | ||
85 | return; | ||
86 | if (client.SceneAgent == null) | ||
87 | return; | ||
88 | |||
84 | if (client.SceneAgent.IsChildAgent) | 89 | if (client.SceneAgent.IsChildAgent) |
85 | return; | 90 | return; |
86 | 91 | ||
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs index e474ef6..77a3c82 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs | |||
@@ -233,6 +233,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
233 | if (sp != null) | 233 | if (sp != null) |
234 | { | 234 | { |
235 | AgentCircuitData aCircuit = scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); | 235 | AgentCircuitData aCircuit = scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); |
236 | if (aCircuit == null) | ||
237 | return; | ||
238 | if (aCircuit.ServiceURLs == null) | ||
239 | return; | ||
240 | |||
236 | if (aCircuit.ServiceURLs.ContainsKey("InventoryServerURI")) | 241 | if (aCircuit.ServiceURLs.ContainsKey("InventoryServerURI")) |
237 | { | 242 | { |
238 | inventoryURL = aCircuit.ServiceURLs["InventoryServerURI"].ToString(); | 243 | inventoryURL = aCircuit.ServiceURLs["InventoryServerURI"].ToString(); |
@@ -254,7 +259,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
254 | if (sp == null) | 259 | if (sp == null) |
255 | { | 260 | { |
256 | inventoryURL = UserManagementModule.GetUserServerURL(userID, "InventoryServerURI"); | 261 | inventoryURL = UserManagementModule.GetUserServerURL(userID, "InventoryServerURI"); |
257 | if (inventoryURL != null && inventoryURL != string.Empty) | 262 | if (!string.IsNullOrEmpty(inventoryURL)) |
258 | { | 263 | { |
259 | inventoryURL = inventoryURL.Trim(new char[] { '/' }); | 264 | inventoryURL = inventoryURL.Trim(new char[] { '/' }); |
260 | m_InventoryURLs.Add(userID, inventoryURL); | 265 | m_InventoryURLs.Add(userID, inventoryURL); |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs index 1e434b9..2fc8ee3 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs | |||
@@ -1,11 +1,41 @@ | |||
1 | using System; | 1 | /* |
2 | using System.Collections.Generic; | 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 | */ | ||
3 | 27 | ||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Threading; | ||
4 | using OpenSim.Framework; | 31 | using OpenSim.Framework; |
5 | using OpenMetaverse; | 32 | using OpenMetaverse; |
6 | 33 | ||
7 | namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | 34 | namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory |
8 | { | 35 | { |
36 | /// <summary> | ||
37 | /// Cache root and system inventory folders to reduce number of potentially remote inventory calls and associated holdups. | ||
38 | /// </summary> | ||
9 | public class InventoryCache | 39 | public class InventoryCache |
10 | { | 40 | { |
11 | private const double CACHE_EXPIRATION_SECONDS = 3600.0; // 1 hour | 41 | private const double CACHE_EXPIRATION_SECONDS = 3600.0; // 1 hour |
@@ -16,8 +46,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
16 | 46 | ||
17 | public void Cache(UUID userID, InventoryFolderBase root) | 47 | public void Cache(UUID userID, InventoryFolderBase root) |
18 | { | 48 | { |
19 | lock (m_RootFolders) | 49 | m_RootFolders.AddOrUpdate(userID, root, CACHE_EXPIRATION_SECONDS); |
20 | m_RootFolders.AddOrUpdate(userID, root, CACHE_EXPIRATION_SECONDS); | ||
21 | } | 50 | } |
22 | 51 | ||
23 | public InventoryFolderBase GetRootFolder(UUID userID) | 52 | public InventoryFolderBase GetRootFolder(UUID userID) |
@@ -31,14 +60,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
31 | 60 | ||
32 | public void Cache(UUID userID, AssetType type, InventoryFolderBase folder) | 61 | public void Cache(UUID userID, AssetType type, InventoryFolderBase folder) |
33 | { | 62 | { |
34 | lock (m_FolderTypes) | 63 | Dictionary<AssetType, InventoryFolderBase> ff = null; |
64 | if (!m_FolderTypes.TryGetValue(userID, out ff)) | ||
65 | { | ||
66 | ff = new Dictionary<AssetType, InventoryFolderBase>(); | ||
67 | m_FolderTypes.Add(userID, ff, CACHE_EXPIRATION_SECONDS); | ||
68 | } | ||
69 | |||
70 | // We need to lock here since two threads could potentially retrieve the same dictionary | ||
71 | // and try to add a folder for that type simultaneously. Dictionary<>.Add() is not described as thread-safe in the SDK | ||
72 | // even if the folders are identical. | ||
73 | lock (ff) | ||
35 | { | 74 | { |
36 | Dictionary<AssetType, InventoryFolderBase> ff = null; | ||
37 | if (!m_FolderTypes.TryGetValue(userID, out ff)) | ||
38 | { | ||
39 | ff = new Dictionary<AssetType, InventoryFolderBase>(); | ||
40 | m_FolderTypes.Add(userID, ff, CACHE_EXPIRATION_SECONDS); | ||
41 | } | ||
42 | if (!ff.ContainsKey(type)) | 75 | if (!ff.ContainsKey(type)) |
43 | ff.Add(type, folder); | 76 | ff.Add(type, folder); |
44 | } | 77 | } |
@@ -50,8 +83,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
50 | if (m_FolderTypes.TryGetValue(userID, out ff)) | 83 | if (m_FolderTypes.TryGetValue(userID, out ff)) |
51 | { | 84 | { |
52 | InventoryFolderBase f = null; | 85 | InventoryFolderBase f = null; |
53 | if (ff.TryGetValue(type, out f)) | 86 | |
54 | return f; | 87 | lock (ff) |
88 | { | ||
89 | if (ff.TryGetValue(type, out f)) | ||
90 | return f; | ||
91 | } | ||
55 | } | 92 | } |
56 | 93 | ||
57 | return null; | 94 | return null; |
@@ -59,8 +96,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
59 | 96 | ||
60 | public void Cache(UUID userID, InventoryCollection inv) | 97 | public void Cache(UUID userID, InventoryCollection inv) |
61 | { | 98 | { |
62 | lock (m_Inventories) | 99 | m_Inventories.AddOrUpdate(userID, inv, 120); |
63 | m_Inventories.AddOrUpdate(userID, inv, 120); | ||
64 | } | 100 | } |
65 | 101 | ||
66 | public InventoryCollection GetUserInventory(UUID userID) | 102 | public InventoryCollection GetUserInventory(UUID userID) |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs index ec5751d..99913a9 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs | |||
@@ -196,7 +196,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
196 | Util.FireAndForget(delegate | 196 | Util.FireAndForget(delegate |
197 | { | 197 | { |
198 | foreach (InventoryItemBase item in items) | 198 | foreach (InventoryItemBase item in items) |
199 | UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData); | 199 | if (!string.IsNullOrEmpty(item.CreatorData)) |
200 | UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData); | ||
200 | }); | 201 | }); |
201 | } | 202 | } |
202 | 203 | ||
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs index 2d3ba82..7f78076 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs | |||
@@ -195,18 +195,20 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
195 | { | 195 | { |
196 | InventoryCollection invCol = m_RemoteConnector.GetFolderContent(userID, folderID); | 196 | InventoryCollection invCol = m_RemoteConnector.GetFolderContent(userID, folderID); |
197 | 197 | ||
198 | if (invCol != null && UserManager != null) | 198 | // Commenting this for now, because it's causing more grief than good |
199 | { | 199 | //if (invCol != null && UserManager != null) |
200 | // Protect ourselves against the caller subsequently modifying the items list | 200 | //{ |
201 | List<InventoryItemBase> items = new List<InventoryItemBase>(invCol.Items); | 201 | // // Protect ourselves against the caller subsequently modifying the items list |
202 | 202 | // List<InventoryItemBase> items = new List<InventoryItemBase>(invCol.Items); | |
203 | if (items != null && items.Count > 0) | 203 | |
204 | Util.FireAndForget(delegate | 204 | // if (items != null && items.Count > 0) |
205 | { | 205 | // //Util.FireAndForget(delegate |
206 | foreach (InventoryItemBase item in items) | 206 | // //{ |
207 | UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData); | 207 | // foreach (InventoryItemBase item in items) |
208 | }); | 208 | // if (!string.IsNullOrEmpty(item.CreatorData)) |
209 | } | 209 | // UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData); |
210 | // //}); | ||
211 | //} | ||
210 | 212 | ||
211 | return invCol; | 213 | return invCol; |
212 | } | 214 | } |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs index 172bea1..516ad40 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs | |||
@@ -79,7 +79,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence | |||
79 | 79 | ||
80 | public void OnConnectionClose(IClientAPI client) | 80 | public void OnConnectionClose(IClientAPI client) |
81 | { | 81 | { |
82 | if (!client.SceneAgent.IsChildAgent) | 82 | if (client != null && client.SceneAgent != null && !client.SceneAgent.IsChildAgent) |
83 | { | 83 | { |
84 | // 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); |
85 | m_PresenceService.LogoutAgent(client.SessionId); | 85 | m_PresenceService.LogoutAgent(client.SessionId); |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs index 8b8bb37..7a6a174 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs | |||
@@ -46,9 +46,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
46 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 46 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
47 | 47 | ||
48 | /// <summary> | 48 | /// <summary> |
49 | /// Version of this service | 49 | /// Version of this service. |
50 | /// </summary> | 50 | /// </summary> |
51 | private const string m_Version = "SIMULATION/0.1"; | 51 | /// <remarks> |
52 | /// Currently valid versions are "SIMULATION/0.1" and "SIMULATION/0.2" | ||
53 | /// </remarks> | ||
54 | public string ServiceVersion { get; set; } | ||
52 | 55 | ||
53 | /// <summary> | 56 | /// <summary> |
54 | /// Map region ID to scene. | 57 | /// Map region ID to scene. |
@@ -62,28 +65,39 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
62 | 65 | ||
63 | #region Region Module interface | 66 | #region Region Module interface |
64 | 67 | ||
65 | public void Initialise(IConfigSource config) | 68 | public void Initialise(IConfigSource configSource) |
66 | { | 69 | { |
67 | IConfig moduleConfig = config.Configs["Modules"]; | 70 | IConfig moduleConfig = configSource.Configs["Modules"]; |
68 | if (moduleConfig != null) | 71 | if (moduleConfig != null) |
69 | { | 72 | { |
70 | string name = moduleConfig.GetString("SimulationServices", ""); | 73 | string name = moduleConfig.GetString("SimulationServices", ""); |
71 | if (name == Name) | 74 | if (name == Name) |
72 | { | 75 | { |
73 | //IConfig userConfig = config.Configs["SimulationService"]; | 76 | InitialiseService(configSource); |
74 | //if (userConfig == null) | ||
75 | //{ | ||
76 | // m_log.Error("[AVATAR CONNECTOR]: SimulationService missing from OpenSim.ini"); | ||
77 | // return; | ||
78 | //} | ||
79 | 77 | ||
80 | m_ModuleEnabled = true; | 78 | m_ModuleEnabled = true; |
81 | 79 | ||
82 | m_log.Info("[SIMULATION CONNECTOR]: Local simulation enabled"); | 80 | m_log.Info("[LOCAL SIMULATION CONNECTOR]: Local simulation enabled."); |
83 | } | 81 | } |
84 | } | 82 | } |
85 | } | 83 | } |
86 | 84 | ||
85 | public void InitialiseService(IConfigSource configSource) | ||
86 | { | ||
87 | ServiceVersion = "SIMULATION/0.2"; | ||
88 | IConfig config = configSource.Configs["SimulationService"]; | ||
89 | if (config != null) | ||
90 | { | ||
91 | ServiceVersion = config.GetString("ConnectorProtocolVersion", ServiceVersion); | ||
92 | |||
93 | if (ServiceVersion != "SIMULATION/0.1" && ServiceVersion != "SIMULATION/0.2") | ||
94 | throw new Exception(string.Format("Invalid ConnectorProtocolVersion {0}", ServiceVersion)); | ||
95 | |||
96 | m_log.InfoFormat( | ||
97 | "[LOCAL SIMULATION CONNECTOR]: Initialized with connector protocol version {0}", ServiceVersion); | ||
98 | } | ||
99 | } | ||
100 | |||
87 | public void PostInitialise() | 101 | public void PostInitialise() |
88 | { | 102 | { |
89 | } | 103 | } |
@@ -160,7 +174,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
160 | 174 | ||
161 | #endregion | 175 | #endregion |
162 | 176 | ||
163 | #region ISimulation | 177 | #region ISimulationService |
164 | 178 | ||
165 | public IScene GetScene(UUID regionId) | 179 | public IScene GetScene(UUID regionId) |
166 | { | 180 | { |
@@ -221,7 +235,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
221 | // "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", | 235 | // "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", |
222 | // destination.RegionName, destination.RegionID); | 236 | // destination.RegionName, destination.RegionID); |
223 | 237 | ||
224 | return m_scenes[destination.RegionID].IncomingChildAgentDataUpdate(cAgentData); | 238 | return m_scenes[destination.RegionID].IncomingUpdateChildAgent(cAgentData); |
225 | } | 239 | } |
226 | 240 | ||
227 | // m_log.DebugFormat( | 241 | // m_log.DebugFormat( |
@@ -231,7 +245,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
231 | return false; | 245 | return false; |
232 | } | 246 | } |
233 | 247 | ||
234 | public bool UpdateAgent(GridRegion destination, AgentPosition cAgentData) | 248 | public bool UpdateAgent(GridRegion destination, AgentPosition agentPosition) |
235 | { | 249 | { |
236 | if (destination == null) | 250 | if (destination == null) |
237 | return false; | 251 | return false; |
@@ -243,37 +257,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
243 | foreach (Scene s in m_scenes.Values) | 257 | foreach (Scene s in m_scenes.Values) |
244 | { | 258 | { |
245 | // m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate"); | 259 | // m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate"); |
246 | s.IncomingChildAgentDataUpdate(cAgentData); | 260 | s.IncomingUpdateChildAgent(agentPosition); |
247 | } | 261 | } |
248 | 262 | ||
249 | //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate"); | 263 | //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate"); |
250 | return true; | 264 | return true; |
251 | } | 265 | } |
252 | 266 | ||
253 | public bool RetrieveAgent(GridRegion destination, UUID id, out IAgentData agent) | ||
254 | { | ||
255 | agent = null; | ||
256 | |||
257 | if (destination == null) | ||
258 | return false; | ||
259 | |||
260 | if (m_scenes.ContainsKey(destination.RegionID)) | ||
261 | { | ||
262 | // m_log.DebugFormat( | ||
263 | // "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", | ||
264 | // s.RegionInfo.RegionName, destination.RegionHandle); | ||
265 | |||
266 | return m_scenes[destination.RegionID].IncomingRetrieveRootAgent(id, out agent); | ||
267 | } | ||
268 | |||
269 | //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate"); | ||
270 | return false; | ||
271 | } | ||
272 | |||
273 | public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason) | 267 | public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason) |
274 | { | 268 | { |
275 | reason = "Communications failure"; | 269 | reason = "Communications failure"; |
276 | version = m_Version; | 270 | version = ServiceVersion; |
277 | if (destination == null) | 271 | if (destination == null) |
278 | return false; | 272 | return false; |
279 | 273 | ||
@@ -306,12 +300,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
306 | return false; | 300 | return false; |
307 | } | 301 | } |
308 | 302 | ||
309 | public bool CloseChildAgent(GridRegion destination, UUID id) | 303 | public bool CloseAgent(GridRegion destination, UUID id, string auth_token) |
310 | { | ||
311 | return CloseAgent(destination, id); | ||
312 | } | ||
313 | |||
314 | public bool CloseAgent(GridRegion destination, UUID id) | ||
315 | { | 304 | { |
316 | if (destination == null) | 305 | if (destination == null) |
317 | return false; | 306 | return false; |
@@ -322,7 +311,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
322 | // "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", | 311 | // "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", |
323 | // s.RegionInfo.RegionName, destination.RegionHandle); | 312 | // s.RegionInfo.RegionName, destination.RegionHandle); |
324 | 313 | ||
325 | Util.FireAndForget(delegate { m_scenes[destination.RegionID].IncomingCloseAgent(id, false); }); | 314 | m_scenes[destination.RegionID].CloseAgent(id, false, auth_token); |
326 | return true; | 315 | return true; |
327 | } | 316 | } |
328 | //m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent"); | 317 | //m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent"); |
@@ -363,7 +352,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
363 | return false; | 352 | return false; |
364 | } | 353 | } |
365 | 354 | ||
366 | #endregion /* IInterregionComms */ | 355 | #endregion |
367 | 356 | ||
368 | #region Misc | 357 | #region Misc |
369 | 358 | ||
@@ -383,4 +372,4 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
383 | 372 | ||
384 | #endregion | 373 | #endregion |
385 | } | 374 | } |
386 | } | 375 | } \ No newline at end of file |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs index c8698ca..ab912ed 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs | |||
@@ -50,9 +50,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
50 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RemoteSimulationConnectorModule")] | 50 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RemoteSimulationConnectorModule")] |
51 | public class RemoteSimulationConnectorModule : ISharedRegionModule, ISimulationService | 51 | public class RemoteSimulationConnectorModule : ISharedRegionModule, ISimulationService |
52 | { | 52 | { |
53 | private bool initialized = false; | ||
54 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 53 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
55 | 54 | ||
55 | private bool initialized = false; | ||
56 | protected bool m_enabled = false; | 56 | protected bool m_enabled = false; |
57 | protected Scene m_aScene; | 57 | protected Scene m_aScene; |
58 | // RemoteSimulationConnector does not care about local regions; it delegates that to the Local module | 58 | // RemoteSimulationConnector does not care about local regions; it delegates that to the Local module |
@@ -64,27 +64,23 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
64 | 64 | ||
65 | #region Region Module interface | 65 | #region Region Module interface |
66 | 66 | ||
67 | public virtual void Initialise(IConfigSource config) | 67 | public virtual void Initialise(IConfigSource configSource) |
68 | { | 68 | { |
69 | 69 | IConfig moduleConfig = configSource.Configs["Modules"]; | |
70 | IConfig moduleConfig = config.Configs["Modules"]; | ||
71 | if (moduleConfig != null) | 70 | if (moduleConfig != null) |
72 | { | 71 | { |
73 | string name = moduleConfig.GetString("SimulationServices", ""); | 72 | string name = moduleConfig.GetString("SimulationServices", ""); |
74 | if (name == Name) | 73 | if (name == Name) |
75 | { | 74 | { |
76 | //IConfig userConfig = config.Configs["SimulationService"]; | 75 | m_localBackend = new LocalSimulationConnectorModule(); |
77 | //if (userConfig == null) | 76 | |
78 | //{ | 77 | m_localBackend.InitialiseService(configSource); |
79 | // m_log.Error("[AVATAR CONNECTOR]: SimulationService missing from OpenSim.ini"); | ||
80 | // return; | ||
81 | //} | ||
82 | 78 | ||
83 | m_remoteConnector = new SimulationServiceConnector(); | 79 | m_remoteConnector = new SimulationServiceConnector(); |
84 | 80 | ||
85 | m_enabled = true; | 81 | m_enabled = true; |
86 | 82 | ||
87 | m_log.Info("[SIMULATION CONNECTOR]: Remote simulation enabled"); | 83 | m_log.Info("[REMOTE SIMULATION CONNECTOR]: Remote simulation enabled."); |
88 | } | 84 | } |
89 | } | 85 | } |
90 | } | 86 | } |
@@ -142,8 +138,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
142 | } | 138 | } |
143 | 139 | ||
144 | protected virtual void InitOnce(Scene scene) | 140 | protected virtual void InitOnce(Scene scene) |
145 | { | 141 | { |
146 | m_localBackend = new LocalSimulationConnectorModule(); | ||
147 | m_aScene = scene; | 142 | m_aScene = scene; |
148 | //m_regionClient = new RegionToRegionClient(m_aScene, m_hyperlinkService); | 143 | //m_regionClient = new RegionToRegionClient(m_aScene, m_hyperlinkService); |
149 | m_thisIP = Util.GetHostFromDNS(scene.RegionInfo.ExternalHostName); | 144 | m_thisIP = Util.GetHostFromDNS(scene.RegionInfo.ExternalHostName); |
@@ -151,7 +146,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
151 | 146 | ||
152 | #endregion | 147 | #endregion |
153 | 148 | ||
154 | #region IInterregionComms | 149 | #region ISimulationService |
155 | 150 | ||
156 | public IScene GetScene(UUID regionId) | 151 | public IScene GetScene(UUID regionId) |
157 | { | 152 | { |
@@ -194,7 +189,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
194 | return false; | 189 | return false; |
195 | 190 | ||
196 | // Try local first | 191 | // Try local first |
197 | if (m_localBackend.IsLocalRegion(destination.RegionHandle)) | 192 | if (m_localBackend.IsLocalRegion(destination.RegionID)) |
198 | return m_localBackend.UpdateAgent(destination, cAgentData); | 193 | return m_localBackend.UpdateAgent(destination, cAgentData); |
199 | 194 | ||
200 | return m_remoteConnector.UpdateAgent(destination, cAgentData); | 195 | return m_remoteConnector.UpdateAgent(destination, cAgentData); |
@@ -206,30 +201,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
206 | return false; | 201 | return false; |
207 | 202 | ||
208 | // Try local first | 203 | // Try local first |
209 | if (m_localBackend.IsLocalRegion(destination.RegionHandle)) | 204 | if (m_localBackend.IsLocalRegion(destination.RegionID)) |
210 | return m_localBackend.UpdateAgent(destination, cAgentData); | 205 | return m_localBackend.UpdateAgent(destination, cAgentData); |
211 | 206 | ||
212 | return m_remoteConnector.UpdateAgent(destination, cAgentData); | 207 | return m_remoteConnector.UpdateAgent(destination, cAgentData); |
213 | } | 208 | } |
214 | 209 | ||
215 | public bool RetrieveAgent(GridRegion destination, UUID id, out IAgentData agent) | ||
216 | { | ||
217 | agent = null; | ||
218 | |||
219 | if (destination == null) | ||
220 | return false; | ||
221 | |||
222 | // Try local first | ||
223 | if (m_localBackend.RetrieveAgent(destination, id, out agent)) | ||
224 | return true; | ||
225 | |||
226 | // else do the remote thing | ||
227 | if (!m_localBackend.IsLocalRegion(destination.RegionHandle)) | ||
228 | return m_remoteConnector.RetrieveAgent(destination, id, out agent); | ||
229 | |||
230 | return false; | ||
231 | } | ||
232 | |||
233 | public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason) | 210 | public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason) |
234 | { | 211 | { |
235 | reason = "Communications failure"; | 212 | reason = "Communications failure"; |
@@ -262,34 +239,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
262 | return false; | 239 | return false; |
263 | } | 240 | } |
264 | 241 | ||
265 | public bool CloseChildAgent(GridRegion destination, UUID id) | 242 | public bool CloseAgent(GridRegion destination, UUID id, string auth_token) |
266 | { | ||
267 | if (destination == null) | ||
268 | return false; | ||
269 | |||
270 | // Try local first | ||
271 | if (m_localBackend.CloseChildAgent(destination, id)) | ||
272 | return true; | ||
273 | |||
274 | // else do the remote thing | ||
275 | if (!m_localBackend.IsLocalRegion(destination.RegionHandle)) | ||
276 | return m_remoteConnector.CloseChildAgent(destination, id); | ||
277 | |||
278 | return false; | ||
279 | } | ||
280 | |||
281 | public bool CloseAgent(GridRegion destination, UUID id) | ||
282 | { | 243 | { |
283 | if (destination == null) | 244 | if (destination == null) |
284 | return false; | 245 | return false; |
285 | 246 | ||
286 | // Try local first | 247 | // Try local first |
287 | if (m_localBackend.CloseAgent(destination, id)) | 248 | if (m_localBackend.CloseAgent(destination, id, auth_token)) |
288 | return true; | 249 | return true; |
289 | 250 | ||
290 | // else do the remote thing | 251 | // else do the remote thing |
291 | if (!m_localBackend.IsLocalRegion(destination.RegionHandle)) | 252 | if (!m_localBackend.IsLocalRegion(destination.RegionID)) |
292 | return m_remoteConnector.CloseAgent(destination, id); | 253 | return m_remoteConnector.CloseAgent(destination, id, auth_token); |
293 | 254 | ||
294 | return false; | 255 | return false; |
295 | } | 256 | } |
@@ -311,12 +272,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
311 | } | 272 | } |
312 | 273 | ||
313 | // else do the remote thing | 274 | // else do the remote thing |
314 | if (!m_localBackend.IsLocalRegion(destination.RegionHandle)) | 275 | if (!m_localBackend.IsLocalRegion(destination.RegionID)) |
315 | return m_remoteConnector.CreateObject(destination, newPosition, sog, isLocalCall); | 276 | return m_remoteConnector.CreateObject(destination, newPosition, sog, isLocalCall); |
316 | 277 | ||
317 | return false; | 278 | return false; |
318 | } | 279 | } |
319 | 280 | ||
320 | #endregion /* IInterregionComms */ | 281 | #endregion |
321 | } | 282 | } |
322 | } | 283 | } |
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs index fcfdf7c..efc4998 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs | |||
@@ -464,7 +464,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
464 | // or creator data is present. Otherwise, use the estate owner instead. | 464 | // or creator data is present. Otherwise, use the estate owner instead. |
465 | foreach (SceneObjectPart part in sceneObject.Parts) | 465 | foreach (SceneObjectPart part in sceneObject.Parts) |
466 | { | 466 | { |
467 | if (part.CreatorData == null || part.CreatorData == string.Empty) | 467 | if (string.IsNullOrEmpty(part.CreatorData)) |
468 | { | 468 | { |
469 | if (!ResolveUserUuid(scene, part.CreatorID)) | 469 | if (!ResolveUserUuid(scene, part.CreatorID)) |
470 | part.CreatorID = scene.RegionInfo.EstateSettings.EstateOwner; | 470 | part.CreatorID = scene.RegionInfo.EstateSettings.EstateOwner; |
@@ -515,7 +515,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
515 | kvp.Value.OwnerID = scene.RegionInfo.EstateSettings.EstateOwner; | 515 | kvp.Value.OwnerID = scene.RegionInfo.EstateSettings.EstateOwner; |
516 | } | 516 | } |
517 | 517 | ||
518 | if (kvp.Value.CreatorData == null || kvp.Value.CreatorData == string.Empty) | 518 | if (string.IsNullOrEmpty(kvp.Value.CreatorData)) |
519 | { | 519 | { |
520 | if (!ResolveUserUuid(scene, kvp.Value.CreatorID)) | 520 | if (!ResolveUserUuid(scene, kvp.Value.CreatorID)) |
521 | kvp.Value.CreatorID = scene.RegionInfo.EstateSettings.EstateOwner; | 521 | kvp.Value.CreatorID = scene.RegionInfo.EstateSettings.EstateOwner; |
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs index a990898..7a844f4 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs | |||
@@ -178,7 +178,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
178 | 178 | ||
179 | // Archive the regions | 179 | // Archive the regions |
180 | 180 | ||
181 | Dictionary<UUID, AssetType> assetUuids = new Dictionary<UUID, AssetType>(); | 181 | Dictionary<UUID, sbyte> assetUuids = new Dictionary<UUID, sbyte>(); |
182 | 182 | ||
183 | scenesGroup.ForEachScene(delegate(Scene scene) | 183 | scenesGroup.ForEachScene(delegate(Scene scene) |
184 | { | 184 | { |
@@ -216,7 +216,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
216 | } | 216 | } |
217 | } | 217 | } |
218 | 218 | ||
219 | private void ArchiveOneRegion(Scene scene, string regionDir, Dictionary<UUID, AssetType> assetUuids) | 219 | private void ArchiveOneRegion(Scene scene, string regionDir, Dictionary<UUID, sbyte> assetUuids) |
220 | { | 220 | { |
221 | m_log.InfoFormat("[ARCHIVER]: Writing region {0}", scene.RegionInfo.RegionName); | 221 | m_log.InfoFormat("[ARCHIVER]: Writing region {0}", scene.RegionInfo.RegionName); |
222 | 222 | ||
@@ -276,16 +276,16 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
276 | RegionSettings regionSettings = scene.RegionInfo.RegionSettings; | 276 | RegionSettings regionSettings = scene.RegionInfo.RegionSettings; |
277 | 277 | ||
278 | if (regionSettings.TerrainTexture1 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_1) | 278 | if (regionSettings.TerrainTexture1 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_1) |
279 | assetUuids[regionSettings.TerrainTexture1] = AssetType.Texture; | 279 | assetUuids[regionSettings.TerrainTexture1] = (sbyte)AssetType.Texture; |
280 | 280 | ||
281 | if (regionSettings.TerrainTexture2 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_2) | 281 | if (regionSettings.TerrainTexture2 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_2) |
282 | assetUuids[regionSettings.TerrainTexture2] = AssetType.Texture; | 282 | assetUuids[regionSettings.TerrainTexture2] = (sbyte)AssetType.Texture; |
283 | 283 | ||
284 | if (regionSettings.TerrainTexture3 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_3) | 284 | if (regionSettings.TerrainTexture3 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_3) |
285 | assetUuids[regionSettings.TerrainTexture3] = AssetType.Texture; | 285 | assetUuids[regionSettings.TerrainTexture3] = (sbyte)AssetType.Texture; |
286 | 286 | ||
287 | if (regionSettings.TerrainTexture4 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_4) | 287 | if (regionSettings.TerrainTexture4 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_4) |
288 | assetUuids[regionSettings.TerrainTexture4] = AssetType.Texture; | 288 | assetUuids[regionSettings.TerrainTexture4] = (sbyte)AssetType.Texture; |
289 | 289 | ||
290 | Save(scene, sceneObjects, regionDir); | 290 | Save(scene, sceneObjects, regionDir); |
291 | } | 291 | } |
diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs index ada7ecc..6c2a631 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs | |||
@@ -81,7 +81,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
81 | /// <value> | 81 | /// <value> |
82 | /// uuids to request | 82 | /// uuids to request |
83 | /// </value> | 83 | /// </value> |
84 | protected IDictionary<UUID, AssetType> m_uuids; | 84 | protected IDictionary<UUID, sbyte> m_uuids; |
85 | 85 | ||
86 | /// <value> | 86 | /// <value> |
87 | /// Callback used when all the assets requested have been received. | 87 | /// Callback used when all the assets requested have been received. |
@@ -115,7 +115,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
115 | protected Dictionary<string, object> m_options; | 115 | protected Dictionary<string, object> m_options; |
116 | 116 | ||
117 | protected internal AssetsRequest( | 117 | protected internal AssetsRequest( |
118 | AssetsArchiver assetsArchiver, IDictionary<UUID, AssetType> uuids, | 118 | AssetsArchiver assetsArchiver, IDictionary<UUID, sbyte> uuids, |
119 | IAssetService assetService, IUserAccountService userService, | 119 | IAssetService assetService, IUserAccountService userService, |
120 | UUID scope, Dictionary<string, object> options, | 120 | UUID scope, Dictionary<string, object> options, |
121 | AssetsRequestCallback assetsRequestCallback) | 121 | AssetsRequestCallback assetsRequestCallback) |
@@ -154,7 +154,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
154 | 154 | ||
155 | m_requestCallbackTimer.Enabled = true; | 155 | m_requestCallbackTimer.Enabled = true; |
156 | 156 | ||
157 | foreach (KeyValuePair<UUID, AssetType> kvp in m_uuids) | 157 | foreach (KeyValuePair<UUID, sbyte> kvp in m_uuids) |
158 | { | 158 | { |
159 | // m_log.DebugFormat("[ARCHIVER]: Requesting asset {0}", kvp.Key); | 159 | // m_log.DebugFormat("[ARCHIVER]: Requesting asset {0}", kvp.Key); |
160 | 160 | ||
@@ -235,9 +235,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
235 | // Check for broken asset types and fix them with the AssetType gleaned by UuidGatherer | 235 | // Check for broken asset types and fix them with the AssetType gleaned by UuidGatherer |
236 | if (fetchedAsset != null && fetchedAsset.Type == (sbyte)AssetType.Unknown) | 236 | if (fetchedAsset != null && fetchedAsset.Type == (sbyte)AssetType.Unknown) |
237 | { | 237 | { |
238 | AssetType type = (AssetType)assetType; | 238 | m_log.InfoFormat("[ARCHIVER]: Rewriting broken asset type for {0} to {1}", fetchedAsset.ID, SLUtil.AssetTypeFromCode((sbyte)assetType)); |
239 | m_log.InfoFormat("[ARCHIVER]: Rewriting broken asset type for {0} to {1}", fetchedAsset.ID, type); | 239 | fetchedAsset.Type = (sbyte)assetType; |
240 | fetchedAsset.Type = (sbyte)type; | ||
241 | } | 240 | } |
242 | 241 | ||
243 | AssetRequestCallback(fetchedAssetID, this, fetchedAsset); | 242 | AssetRequestCallback(fetchedAssetID, this, fetchedAsset); |
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs index 4d49794..1659493 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementCommands.cs | |||
@@ -60,7 +60,7 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
60 | 60 | ||
61 | public void Initialise() | 61 | public void Initialise() |
62 | { | 62 | { |
63 | m_log.DebugFormat("[ESTATE MODULE]: Setting up estate commands for region {0}", m_module.Scene.RegionInfo.RegionName); | 63 | // m_log.DebugFormat("[ESTATE MODULE]: Setting up estate commands for region {0}", m_module.Scene.RegionInfo.RegionName); |
64 | 64 | ||
65 | m_module.Scene.AddCommand("Regions", m_module, "set terrain texture", | 65 | m_module.Scene.AddCommand("Regions", m_module, "set terrain texture", |
66 | "set terrain texture <number> <uuid> [<x>] [<y>]", | 66 | "set terrain texture <number> <uuid> [<x>] [<y>]", |
@@ -76,6 +76,13 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
76 | " that coordinate. Corner # SW = 0, NW = 1, SE = 2, NE = 3, all corners = -1.", | 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("Regions", m_module, "set water height", | ||
80 | "set water height <height> [<x>] [<y>]", | ||
81 | "Sets the water height in meters. If <x> and <y> are specified, it will only set it on regions with a matching coordinate. " + | ||
82 | "Specify -1 in <x> or <y> to wildcard that coordinate.", | ||
83 | consoleSetWaterHeight); | ||
84 | |||
85 | |||
79 | m_module.Scene.AddCommand( | 86 | m_module.Scene.AddCommand( |
80 | "Estates", m_module, "estate show", "estate show", "Shows all estates on the simulator.", ShowEstatesCommand); | 87 | "Estates", m_module, "estate show", "estate show", "Shows all estates on the simulator.", ShowEstatesCommand); |
81 | } | 88 | } |
@@ -121,7 +128,29 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
121 | } | 128 | } |
122 | } | 129 | } |
123 | } | 130 | } |
124 | 131 | protected void consoleSetWaterHeight(string module, string[] args) | |
132 | { | ||
133 | string heightstring = args[3]; | ||
134 | |||
135 | int x = (args.Length > 4 ? int.Parse(args[4]) : -1); | ||
136 | int y = (args.Length > 5 ? int.Parse(args[5]) : -1); | ||
137 | |||
138 | if (x == -1 || m_module.Scene.RegionInfo.RegionLocX == x) | ||
139 | { | ||
140 | if (y == -1 || m_module.Scene.RegionInfo.RegionLocY == y) | ||
141 | { | ||
142 | double selectedheight = double.Parse(heightstring); | ||
143 | |||
144 | m_log.Debug("[ESTATEMODULE]: Setting water height in " + m_module.Scene.RegionInfo.RegionName + " to " + | ||
145 | string.Format(" {0}", selectedheight)); | ||
146 | m_module.Scene.RegionInfo.RegionSettings.WaterHeight = selectedheight; | ||
147 | |||
148 | m_module.Scene.RegionInfo.RegionSettings.Save(); | ||
149 | m_module.TriggerRegionInfoChange(); | ||
150 | m_module.sendRegionHandshakeToAll(); | ||
151 | } | ||
152 | } | ||
153 | } | ||
125 | protected void consoleSetTerrainHeights(string module, string[] args) | 154 | protected void consoleSetTerrainHeights(string module, string[] args) |
126 | { | 155 | { |
127 | string num = args[3]; | 156 | string num = args[3]; |
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index 834fd77..47390e7 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs | |||
@@ -576,7 +576,7 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
576 | if (!Scene.TeleportClientHome(user, s.ControllingClient)) | 576 | if (!Scene.TeleportClientHome(user, s.ControllingClient)) |
577 | { | 577 | { |
578 | s.ControllingClient.Kick("Your access to the region was revoked and TP home failed - you have been logged out."); | 578 | s.ControllingClient.Kick("Your access to the region was revoked and TP home failed - you have been logged out."); |
579 | s.ControllingClient.Close(); | 579 | Scene.CloseAgent(s.UUID, false); |
580 | } | 580 | } |
581 | } | 581 | } |
582 | } | 582 | } |
@@ -716,7 +716,7 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
716 | } | 716 | } |
717 | } | 717 | } |
718 | 718 | ||
719 | public void handleOnEstateManageTelehub(IClientAPI client, UUID invoice, UUID senderID, string cmd, uint param1) | 719 | public void HandleOnEstateManageTelehub(IClientAPI client, UUID invoice, UUID senderID, string cmd, uint param1) |
720 | { | 720 | { |
721 | SceneObjectPart part; | 721 | SceneObjectPart part; |
722 | 722 | ||
@@ -756,7 +756,9 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
756 | default: | 756 | default: |
757 | break; | 757 | break; |
758 | } | 758 | } |
759 | SendTelehubInfo(client); | 759 | |
760 | if (client != null) | ||
761 | SendTelehubInfo(client); | ||
760 | } | 762 | } |
761 | 763 | ||
762 | private void SendSimulatorBlueBoxMessage( | 764 | private void SendSimulatorBlueBoxMessage( |
@@ -811,7 +813,7 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
811 | if (!Scene.TeleportClientHome(prey, s.ControllingClient)) | 813 | if (!Scene.TeleportClientHome(prey, s.ControllingClient)) |
812 | { | 814 | { |
813 | s.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed - you have been logged out."); | 815 | s.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed - you have been logged out."); |
814 | s.ControllingClient.Close(); | 816 | Scene.CloseAgent(s.UUID, false); |
815 | } | 817 | } |
816 | } | 818 | } |
817 | } | 819 | } |
@@ -834,7 +836,7 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
834 | if (!Scene.TeleportClientHome(p.UUID, p.ControllingClient)) | 836 | if (!Scene.TeleportClientHome(p.UUID, p.ControllingClient)) |
835 | { | 837 | { |
836 | p.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed - you have been logged out."); | 838 | p.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed - you have been logged out."); |
837 | p.ControllingClient.Close(); | 839 | Scene.CloseAgent(p.UUID, false); |
838 | } | 840 | } |
839 | } | 841 | } |
840 | } | 842 | } |
@@ -843,26 +845,23 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
843 | 845 | ||
844 | private void AbortTerrainXferHandler(IClientAPI remoteClient, ulong XferID) | 846 | private void AbortTerrainXferHandler(IClientAPI remoteClient, ulong XferID) |
845 | { | 847 | { |
846 | if (TerrainUploader != null) | 848 | lock (this) |
847 | { | 849 | { |
848 | lock (TerrainUploader) | 850 | if ((TerrainUploader != null) && (XferID == TerrainUploader.XferID)) |
849 | { | 851 | { |
850 | if (XferID == TerrainUploader.XferID) | 852 | remoteClient.OnXferReceive -= TerrainUploader.XferReceive; |
851 | { | 853 | remoteClient.OnAbortXfer -= AbortTerrainXferHandler; |
852 | remoteClient.OnXferReceive -= TerrainUploader.XferReceive; | 854 | TerrainUploader.TerrainUploadDone -= HandleTerrainApplication; |
853 | remoteClient.OnAbortXfer -= AbortTerrainXferHandler; | ||
854 | TerrainUploader.TerrainUploadDone -= HandleTerrainApplication; | ||
855 | 855 | ||
856 | TerrainUploader = null; | 856 | TerrainUploader = null; |
857 | remoteClient.SendAlertMessage("Terrain Upload aborted by the client"); | 857 | remoteClient.SendAlertMessage("Terrain Upload aborted by the client"); |
858 | } | ||
859 | } | 858 | } |
860 | } | 859 | } |
861 | |||
862 | } | 860 | } |
861 | |||
863 | private void HandleTerrainApplication(string filename, byte[] terrainData, IClientAPI remoteClient) | 862 | private void HandleTerrainApplication(string filename, byte[] terrainData, IClientAPI remoteClient) |
864 | { | 863 | { |
865 | lock (TerrainUploader) | 864 | lock (this) |
866 | { | 865 | { |
867 | remoteClient.OnXferReceive -= TerrainUploader.XferReceive; | 866 | remoteClient.OnXferReceive -= TerrainUploader.XferReceive; |
868 | remoteClient.OnAbortXfer -= AbortTerrainXferHandler; | 867 | remoteClient.OnAbortXfer -= AbortTerrainXferHandler; |
@@ -921,22 +920,32 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
921 | 920 | ||
922 | private void handleUploadTerrain(IClientAPI remote_client, string clientFileName) | 921 | private void handleUploadTerrain(IClientAPI remote_client, string clientFileName) |
923 | { | 922 | { |
924 | if (TerrainUploader == null) | 923 | lock (this) |
925 | { | 924 | { |
926 | 925 | if (TerrainUploader == null) | |
927 | TerrainUploader = new EstateTerrainXferHandler(remote_client, clientFileName); | ||
928 | lock (TerrainUploader) | ||
929 | { | 926 | { |
927 | m_log.DebugFormat("Starting to receive uploaded terrain"); | ||
928 | TerrainUploader = new EstateTerrainXferHandler(remote_client, clientFileName); | ||
930 | remote_client.OnXferReceive += TerrainUploader.XferReceive; | 929 | remote_client.OnXferReceive += TerrainUploader.XferReceive; |
931 | remote_client.OnAbortXfer += AbortTerrainXferHandler; | 930 | remote_client.OnAbortXfer += AbortTerrainXferHandler; |
932 | TerrainUploader.TerrainUploadDone += HandleTerrainApplication; | 931 | TerrainUploader.TerrainUploadDone += HandleTerrainApplication; |
932 | TerrainUploader.RequestStartXfer(remote_client); | ||
933 | } | ||
934 | else | ||
935 | { | ||
936 | remote_client.SendAlertMessage("Another Terrain Upload is in progress. Please wait your turn!"); | ||
933 | } | 937 | } |
934 | TerrainUploader.RequestStartXfer(remote_client); | ||
935 | |||
936 | } | 938 | } |
937 | else | 939 | } |
940 | |||
941 | public bool IsTerrainXfer(ulong xferID) | ||
942 | { | ||
943 | lock (this) | ||
938 | { | 944 | { |
939 | remote_client.SendAlertMessage("Another Terrain Upload is in progress. Please wait your turn!"); | 945 | if (TerrainUploader == null) |
946 | return false; | ||
947 | else | ||
948 | return TerrainUploader.XferID == xferID; | ||
940 | } | 949 | } |
941 | } | 950 | } |
942 | 951 | ||
@@ -1221,7 +1230,7 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
1221 | client.OnEstateRestartSimRequest += handleEstateRestartSimRequest; | 1230 | client.OnEstateRestartSimRequest += handleEstateRestartSimRequest; |
1222 | client.OnEstateChangeCovenantRequest += handleChangeEstateCovenantRequest; | 1231 | client.OnEstateChangeCovenantRequest += handleChangeEstateCovenantRequest; |
1223 | client.OnEstateChangeInfo += handleEstateChangeInfo; | 1232 | client.OnEstateChangeInfo += handleEstateChangeInfo; |
1224 | client.OnEstateManageTelehub += handleOnEstateManageTelehub; | 1233 | client.OnEstateManageTelehub += HandleOnEstateManageTelehub; |
1225 | client.OnUpdateEstateAccessDeltaRequest += handleEstateAccessDeltaRequest; | 1234 | client.OnUpdateEstateAccessDeltaRequest += handleEstateAccessDeltaRequest; |
1226 | client.OnSimulatorBlueBoxMessageRequest += SendSimulatorBlueBoxMessage; | 1235 | client.OnSimulatorBlueBoxMessageRequest += SendSimulatorBlueBoxMessage; |
1227 | client.OnEstateBlueBoxMessageRequest += SendEstateBlueBoxMessage; | 1236 | client.OnEstateBlueBoxMessageRequest += SendEstateBlueBoxMessage; |
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateTerrainXferHandler.cs b/OpenSim/Region/CoreModules/World/Estate/EstateTerrainXferHandler.cs index b8d8b10..2d74eaf 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateTerrainXferHandler.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateTerrainXferHandler.cs | |||
@@ -78,7 +78,10 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
78 | /// <param name="data"></param> | 78 | /// <param name="data"></param> |
79 | public void XferReceive(IClientAPI remoteClient, ulong xferID, uint packetID, byte[] data) | 79 | public void XferReceive(IClientAPI remoteClient, ulong xferID, uint packetID, byte[] data) |
80 | { | 80 | { |
81 | if (mXferID == xferID) | 81 | if (mXferID != xferID) |
82 | return; | ||
83 | |||
84 | lock (this) | ||
82 | { | 85 | { |
83 | if (m_asset.Data.Length > 1) | 86 | if (m_asset.Data.Length > 1) |
84 | { | 87 | { |
@@ -99,7 +102,6 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
99 | if ((packetID & 0x80000000) != 0) | 102 | if ((packetID & 0x80000000) != 0) |
100 | { | 103 | { |
101 | SendCompleteMessage(remoteClient); | 104 | SendCompleteMessage(remoteClient); |
102 | |||
103 | } | 105 | } |
104 | } | 106 | } |
105 | } | 107 | } |
diff --git a/OpenSim/Region/CoreModules/World/Estate/XEstateConnector.cs b/OpenSim/Region/CoreModules/World/Estate/XEstateConnector.cs new file mode 100644 index 0000000..73e706c --- /dev/null +++ b/OpenSim/Region/CoreModules/World/Estate/XEstateConnector.cs | |||
@@ -0,0 +1,218 @@ | |||
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 | |||
32 | using OpenSim.Services.Interfaces; | ||
33 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; | ||
34 | using OpenSim.Server.Base; | ||
35 | using OpenSim.Framework.Servers.HttpServer; | ||
36 | using OpenSim.Framework; | ||
37 | using OpenSim.Region.Framework.Scenes; | ||
38 | |||
39 | using OpenMetaverse; | ||
40 | using log4net; | ||
41 | |||
42 | namespace OpenSim.Region.CoreModules.World.Estate | ||
43 | { | ||
44 | public class EstateConnector | ||
45 | { | ||
46 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
47 | |||
48 | protected XEstateModule m_EstateModule; | ||
49 | |||
50 | public EstateConnector(XEstateModule module) | ||
51 | { | ||
52 | m_EstateModule = module; | ||
53 | } | ||
54 | |||
55 | public void SendTeleportHomeOneUser(uint EstateID, UUID PreyID) | ||
56 | { | ||
57 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
58 | sendData["METHOD"] = "teleport_home_one_user"; | ||
59 | |||
60 | sendData["EstateID"] = EstateID.ToString(); | ||
61 | sendData["PreyID"] = PreyID.ToString(); | ||
62 | |||
63 | SendToEstate(EstateID, sendData); | ||
64 | } | ||
65 | |||
66 | public void SendTeleportHomeAllUsers(uint EstateID) | ||
67 | { | ||
68 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
69 | sendData["METHOD"] = "teleport_home_all_users"; | ||
70 | |||
71 | sendData["EstateID"] = EstateID.ToString(); | ||
72 | |||
73 | SendToEstate(EstateID, sendData); | ||
74 | } | ||
75 | |||
76 | public bool SendUpdateCovenant(uint EstateID, UUID CovenantID) | ||
77 | { | ||
78 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
79 | sendData["METHOD"] = "update_covenant"; | ||
80 | |||
81 | sendData["CovenantID"] = CovenantID.ToString(); | ||
82 | sendData["EstateID"] = EstateID.ToString(); | ||
83 | |||
84 | // Handle local regions locally | ||
85 | // | ||
86 | foreach (Scene s in m_EstateModule.Scenes) | ||
87 | { | ||
88 | if (s.RegionInfo.EstateSettings.EstateID == EstateID) | ||
89 | s.RegionInfo.RegionSettings.Covenant = CovenantID; | ||
90 | // s.ReloadEstateData(); | ||
91 | } | ||
92 | |||
93 | SendToEstate(EstateID, sendData); | ||
94 | |||
95 | return true; | ||
96 | } | ||
97 | |||
98 | public bool SendUpdateEstate(uint EstateID) | ||
99 | { | ||
100 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
101 | sendData["METHOD"] = "update_estate"; | ||
102 | |||
103 | sendData["EstateID"] = EstateID.ToString(); | ||
104 | |||
105 | // Handle local regions locally | ||
106 | // | ||
107 | foreach (Scene s in m_EstateModule.Scenes) | ||
108 | { | ||
109 | if (s.RegionInfo.EstateSettings.EstateID == EstateID) | ||
110 | s.ReloadEstateData(); | ||
111 | } | ||
112 | |||
113 | SendToEstate(EstateID, sendData); | ||
114 | |||
115 | return true; | ||
116 | } | ||
117 | |||
118 | public void SendEstateMessage(uint EstateID, UUID FromID, string FromName, string Message) | ||
119 | { | ||
120 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
121 | sendData["METHOD"] = "estate_message"; | ||
122 | |||
123 | sendData["EstateID"] = EstateID.ToString(); | ||
124 | sendData["FromID"] = FromID.ToString(); | ||
125 | sendData["FromName"] = FromName; | ||
126 | sendData["Message"] = Message; | ||
127 | |||
128 | SendToEstate(EstateID, sendData); | ||
129 | } | ||
130 | |||
131 | private void SendToEstate(uint EstateID, Dictionary<string, object> sendData) | ||
132 | { | ||
133 | List<UUID> regions = m_EstateModule.Scenes[0].GetEstateRegions((int)EstateID); | ||
134 | |||
135 | UUID ScopeID = UUID.Zero; | ||
136 | |||
137 | // Handle local regions locally | ||
138 | // | ||
139 | lock (m_EstateModule.Scenes) | ||
140 | { | ||
141 | foreach (Scene s in m_EstateModule.Scenes) | ||
142 | { | ||
143 | if (regions.Contains(s.RegionInfo.RegionID)) | ||
144 | { | ||
145 | // All regions in one estate are in the same scope. | ||
146 | // Use that scope. | ||
147 | // | ||
148 | ScopeID = s.RegionInfo.ScopeID; | ||
149 | regions.Remove(s.RegionInfo.RegionID); | ||
150 | } | ||
151 | } | ||
152 | } | ||
153 | |||
154 | // Our own region should always be in the above list. | ||
155 | // In a standalone this would not be true. But then, | ||
156 | // Scope ID is not relevat there. Use first scope. | ||
157 | // | ||
158 | if (ScopeID == UUID.Zero) | ||
159 | ScopeID = m_EstateModule.Scenes[0].RegionInfo.ScopeID; | ||
160 | |||
161 | // Don't send to the same instance twice | ||
162 | // | ||
163 | List<string> done = new List<string>(); | ||
164 | |||
165 | // Send to remote regions | ||
166 | // | ||
167 | foreach (UUID regionID in regions) | ||
168 | { | ||
169 | GridRegion region = m_EstateModule.Scenes[0].GridService.GetRegionByUUID(ScopeID, regionID); | ||
170 | if (region != null) | ||
171 | { | ||
172 | string url = "http://" + region.ExternalHostName + ":" + region.HttpPort; | ||
173 | if (done.Contains(url)) | ||
174 | continue; | ||
175 | |||
176 | Call(region, sendData); | ||
177 | done.Add(url); | ||
178 | } | ||
179 | } | ||
180 | } | ||
181 | |||
182 | private bool Call(GridRegion region, Dictionary<string, object> sendData) | ||
183 | { | ||
184 | string reqString = ServerUtils.BuildQueryString(sendData); | ||
185 | // m_log.DebugFormat("[XESTATE CONNECTOR]: queryString = {0}", reqString); | ||
186 | try | ||
187 | { | ||
188 | string url = "http://" + region.ExternalHostName + ":" + region.HttpPort; | ||
189 | string reply = SynchronousRestFormsRequester.MakeRequest("POST", | ||
190 | url + "/estate", | ||
191 | reqString); | ||
192 | if (reply != string.Empty) | ||
193 | { | ||
194 | Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply); | ||
195 | |||
196 | if (replyData.ContainsKey("RESULT")) | ||
197 | { | ||
198 | if (replyData["RESULT"].ToString().ToLower() == "true") | ||
199 | return true; | ||
200 | else | ||
201 | return false; | ||
202 | } | ||
203 | else | ||
204 | m_log.DebugFormat("[XESTATE CONNECTOR]: reply data does not contain result field"); | ||
205 | |||
206 | } | ||
207 | else | ||
208 | m_log.DebugFormat("[XESTATE CONNECTOR]: received empty reply"); | ||
209 | } | ||
210 | catch (Exception e) | ||
211 | { | ||
212 | m_log.DebugFormat("[XESTATE CONNECTOR]: Exception when contacting remote sim: {0}", e.Message); | ||
213 | } | ||
214 | |||
215 | return false; | ||
216 | } | ||
217 | } | ||
218 | } | ||
diff --git a/OpenSim/Region/CoreModules/World/Estate/XEstateModule.cs b/OpenSim/Region/CoreModules/World/Estate/XEstateModule.cs new file mode 100644 index 0000000..f54ab2c --- /dev/null +++ b/OpenSim/Region/CoreModules/World/Estate/XEstateModule.cs | |||
@@ -0,0 +1,256 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections; | ||
30 | using System.Collections.Generic; | ||
31 | using System.Reflection; | ||
32 | using log4net; | ||
33 | using Nini.Config; | ||
34 | using Nwc.XmlRpc; | ||
35 | using OpenMetaverse; | ||
36 | using OpenSim.Framework; | ||
37 | using OpenSim.Framework.Communications; | ||
38 | using OpenSim.Region.Framework.Interfaces; | ||
39 | using OpenSim.Region.Framework.Scenes; | ||
40 | using OpenSim.Services.Interfaces; | ||
41 | using OpenSim.Server.Base; | ||
42 | using OpenSim.Framework.Servers; | ||
43 | using OpenSim.Framework.Servers.HttpServer; | ||
44 | using Mono.Addins; | ||
45 | |||
46 | namespace OpenSim.Region.CoreModules.World.Estate | ||
47 | { | ||
48 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "XEstate")] | ||
49 | public class XEstateModule : ISharedRegionModule | ||
50 | { | ||
51 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
52 | |||
53 | protected List<Scene> m_Scenes = new List<Scene>(); | ||
54 | protected bool m_InInfoUpdate = false; | ||
55 | |||
56 | public bool InInfoUpdate | ||
57 | { | ||
58 | get { return m_InInfoUpdate; } | ||
59 | set { m_InInfoUpdate = value; } | ||
60 | } | ||
61 | |||
62 | public List<Scene> Scenes | ||
63 | { | ||
64 | get { return m_Scenes; } | ||
65 | } | ||
66 | |||
67 | protected EstateConnector m_EstateConnector; | ||
68 | |||
69 | public void Initialise(IConfigSource config) | ||
70 | { | ||
71 | int port = 0; | ||
72 | |||
73 | IConfig estateConfig = config.Configs["Estate"]; | ||
74 | if (estateConfig != null) | ||
75 | { | ||
76 | port = estateConfig.GetInt("Port", 0); | ||
77 | } | ||
78 | |||
79 | m_EstateConnector = new EstateConnector(this); | ||
80 | |||
81 | // Instantiate the request handler | ||
82 | IHttpServer server = MainServer.GetHttpServer((uint)port); | ||
83 | server.AddStreamHandler(new EstateRequestHandler(this)); | ||
84 | } | ||
85 | |||
86 | public void PostInitialise() | ||
87 | { | ||
88 | } | ||
89 | |||
90 | public void Close() | ||
91 | { | ||
92 | } | ||
93 | |||
94 | public void AddRegion(Scene scene) | ||
95 | { | ||
96 | lock (m_Scenes) | ||
97 | m_Scenes.Add(scene); | ||
98 | |||
99 | scene.EventManager.OnNewClient += OnNewClient; | ||
100 | } | ||
101 | |||
102 | public void RegionLoaded(Scene scene) | ||
103 | { | ||
104 | IEstateModule em = scene.RequestModuleInterface<IEstateModule>(); | ||
105 | |||
106 | em.OnRegionInfoChange += OnRegionInfoChange; | ||
107 | em.OnEstateInfoChange += OnEstateInfoChange; | ||
108 | em.OnEstateMessage += OnEstateMessage; | ||
109 | } | ||
110 | |||
111 | public void RemoveRegion(Scene scene) | ||
112 | { | ||
113 | scene.EventManager.OnNewClient -= OnNewClient; | ||
114 | |||
115 | lock (m_Scenes) | ||
116 | m_Scenes.Remove(scene); | ||
117 | } | ||
118 | |||
119 | public string Name | ||
120 | { | ||
121 | get { return "EstateModule"; } | ||
122 | } | ||
123 | |||
124 | public Type ReplaceableInterface | ||
125 | { | ||
126 | get { return null; } | ||
127 | } | ||
128 | |||
129 | private Scene FindScene(UUID RegionID) | ||
130 | { | ||
131 | foreach (Scene s in Scenes) | ||
132 | { | ||
133 | if (s.RegionInfo.RegionID == RegionID) | ||
134 | return s; | ||
135 | } | ||
136 | |||
137 | return null; | ||
138 | } | ||
139 | |||
140 | private void OnRegionInfoChange(UUID RegionID) | ||
141 | { | ||
142 | Scene s = FindScene(RegionID); | ||
143 | if (s == null) | ||
144 | return; | ||
145 | |||
146 | if (!m_InInfoUpdate) | ||
147 | m_EstateConnector.SendUpdateCovenant(s.RegionInfo.EstateSettings.EstateID, s.RegionInfo.RegionSettings.Covenant); | ||
148 | } | ||
149 | |||
150 | private void OnEstateInfoChange(UUID RegionID) | ||
151 | { | ||
152 | Scene s = FindScene(RegionID); | ||
153 | if (s == null) | ||
154 | return; | ||
155 | |||
156 | if (!m_InInfoUpdate) | ||
157 | m_EstateConnector.SendUpdateEstate(s.RegionInfo.EstateSettings.EstateID); | ||
158 | } | ||
159 | |||
160 | private void OnEstateMessage(UUID RegionID, UUID FromID, string FromName, string Message) | ||
161 | { | ||
162 | Scene senderScenes = FindScene(RegionID); | ||
163 | if (senderScenes == null) | ||
164 | return; | ||
165 | |||
166 | uint estateID = senderScenes.RegionInfo.EstateSettings.EstateID; | ||
167 | |||
168 | foreach (Scene s in Scenes) | ||
169 | { | ||
170 | if (s.RegionInfo.EstateSettings.EstateID == estateID) | ||
171 | { | ||
172 | IDialogModule dm = s.RequestModuleInterface<IDialogModule>(); | ||
173 | |||
174 | if (dm != null) | ||
175 | { | ||
176 | dm.SendNotificationToUsersInRegion(FromID, FromName, | ||
177 | Message); | ||
178 | } | ||
179 | } | ||
180 | } | ||
181 | if (!m_InInfoUpdate) | ||
182 | m_EstateConnector.SendEstateMessage(estateID, FromID, FromName, Message); | ||
183 | } | ||
184 | |||
185 | private void OnNewClient(IClientAPI client) | ||
186 | { | ||
187 | client.OnEstateTeleportOneUserHomeRequest += OnEstateTeleportOneUserHomeRequest; | ||
188 | client.OnEstateTeleportAllUsersHomeRequest += OnEstateTeleportAllUsersHomeRequest; | ||
189 | |||
190 | } | ||
191 | |||
192 | private void OnEstateTeleportOneUserHomeRequest(IClientAPI client, UUID invoice, UUID senderID, UUID prey) | ||
193 | { | ||
194 | if (prey == UUID.Zero) | ||
195 | return; | ||
196 | |||
197 | if (!(client.Scene is Scene)) | ||
198 | return; | ||
199 | |||
200 | Scene scene = (Scene)client.Scene; | ||
201 | |||
202 | uint estateID = scene.RegionInfo.EstateSettings.EstateID; | ||
203 | |||
204 | if (!scene.Permissions.CanIssueEstateCommand(client.AgentId, false)) | ||
205 | return; | ||
206 | |||
207 | foreach (Scene s in Scenes) | ||
208 | { | ||
209 | if (s == scene) | ||
210 | continue; // Already handles by estate module | ||
211 | if (s.RegionInfo.EstateSettings.EstateID != estateID) | ||
212 | continue; | ||
213 | |||
214 | ScenePresence p = scene.GetScenePresence(prey); | ||
215 | if (p != null && !p.IsChildAgent) | ||
216 | { | ||
217 | p.ControllingClient.SendTeleportStart(16); | ||
218 | scene.TeleportClientHome(prey, p.ControllingClient); | ||
219 | } | ||
220 | } | ||
221 | |||
222 | m_EstateConnector.SendTeleportHomeOneUser(estateID, prey); | ||
223 | } | ||
224 | |||
225 | private void OnEstateTeleportAllUsersHomeRequest(IClientAPI client, UUID invoice, UUID senderID) | ||
226 | { | ||
227 | if (!(client.Scene is Scene)) | ||
228 | return; | ||
229 | |||
230 | Scene scene = (Scene)client.Scene; | ||
231 | |||
232 | uint estateID = scene.RegionInfo.EstateSettings.EstateID; | ||
233 | |||
234 | if (!scene.Permissions.CanIssueEstateCommand(client.AgentId, false)) | ||
235 | return; | ||
236 | |||
237 | foreach (Scene s in Scenes) | ||
238 | { | ||
239 | if (s == scene) | ||
240 | continue; // Already handles by estate module | ||
241 | if (s.RegionInfo.EstateSettings.EstateID != estateID) | ||
242 | continue; | ||
243 | |||
244 | scene.ForEachScenePresence(delegate(ScenePresence p) { | ||
245 | if (p != null && !p.IsChildAgent) | ||
246 | { | ||
247 | p.ControllingClient.SendTeleportStart(16); | ||
248 | scene.TeleportClientHome(p.ControllingClient.AgentId, p.ControllingClient); | ||
249 | } | ||
250 | }); | ||
251 | } | ||
252 | |||
253 | m_EstateConnector.SendTeleportHomeAllUsers(estateID); | ||
254 | } | ||
255 | } | ||
256 | } | ||
diff --git a/OpenSim/Region/CoreModules/World/Estate/XEstateRequestHandler.cs b/OpenSim/Region/CoreModules/World/Estate/XEstateRequestHandler.cs new file mode 100644 index 0000000..2366767 --- /dev/null +++ b/OpenSim/Region/CoreModules/World/Estate/XEstateRequestHandler.cs | |||
@@ -0,0 +1,298 @@ | |||
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.IO; | ||
31 | using System.Reflection; | ||
32 | using System.Xml; | ||
33 | |||
34 | using OpenSim.Framework; | ||
35 | using OpenSim.Server.Base; | ||
36 | using OpenSim.Framework.Servers.HttpServer; | ||
37 | using OpenSim.Region.Framework.Scenes; | ||
38 | using OpenSim.Region.Framework.Interfaces; | ||
39 | |||
40 | using OpenMetaverse; | ||
41 | using log4net; | ||
42 | |||
43 | namespace OpenSim.Region.CoreModules.World.Estate | ||
44 | { | ||
45 | public class EstateRequestHandler : BaseStreamHandler | ||
46 | { | ||
47 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
48 | |||
49 | protected XEstateModule m_EstateModule; | ||
50 | protected Object m_RequestLock = new Object(); | ||
51 | |||
52 | public EstateRequestHandler(XEstateModule fmodule) | ||
53 | : base("POST", "/estate") | ||
54 | { | ||
55 | m_EstateModule = fmodule; | ||
56 | } | ||
57 | |||
58 | protected override byte[] ProcessRequest(string path, Stream requestData, | ||
59 | IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) | ||
60 | { | ||
61 | StreamReader sr = new StreamReader(requestData); | ||
62 | string body = sr.ReadToEnd(); | ||
63 | sr.Close(); | ||
64 | body = body.Trim(); | ||
65 | |||
66 | m_log.DebugFormat("[XESTATE HANDLER]: query String: {0}", body); | ||
67 | |||
68 | try | ||
69 | { | ||
70 | lock (m_RequestLock) | ||
71 | { | ||
72 | Dictionary<string, object> request = | ||
73 | ServerUtils.ParseQueryString(body); | ||
74 | |||
75 | if (!request.ContainsKey("METHOD")) | ||
76 | return FailureResult(); | ||
77 | |||
78 | string method = request["METHOD"].ToString(); | ||
79 | request.Remove("METHOD"); | ||
80 | |||
81 | try | ||
82 | { | ||
83 | m_EstateModule.InInfoUpdate = false; | ||
84 | |||
85 | switch (method) | ||
86 | { | ||
87 | case "update_covenant": | ||
88 | return UpdateCovenant(request); | ||
89 | case "update_estate": | ||
90 | return UpdateEstate(request); | ||
91 | case "estate_message": | ||
92 | return EstateMessage(request); | ||
93 | case "teleport_home_one_user": | ||
94 | return TeleportHomeOneUser(request); | ||
95 | case "teleport_home_all_users": | ||
96 | return TeleportHomeAllUsers(request); | ||
97 | } | ||
98 | } | ||
99 | finally | ||
100 | { | ||
101 | m_EstateModule.InInfoUpdate = false; | ||
102 | } | ||
103 | } | ||
104 | } | ||
105 | catch (Exception e) | ||
106 | { | ||
107 | m_log.Debug("[XESTATE]: Exception {0}" + e.ToString()); | ||
108 | } | ||
109 | |||
110 | return FailureResult(); | ||
111 | } | ||
112 | |||
113 | byte[] TeleportHomeAllUsers(Dictionary<string, object> request) | ||
114 | { | ||
115 | UUID PreyID = UUID.Zero; | ||
116 | int EstateID = 0; | ||
117 | |||
118 | if (!request.ContainsKey("EstateID")) | ||
119 | return FailureResult(); | ||
120 | |||
121 | if (!Int32.TryParse(request["EstateID"].ToString(), out EstateID)) | ||
122 | return FailureResult(); | ||
123 | |||
124 | foreach (Scene s in m_EstateModule.Scenes) | ||
125 | { | ||
126 | if (s.RegionInfo.EstateSettings.EstateID == EstateID) | ||
127 | { | ||
128 | s.ForEachScenePresence(delegate(ScenePresence p) { | ||
129 | if (p != null && !p.IsChildAgent) | ||
130 | { | ||
131 | p.ControllingClient.SendTeleportStart(16); | ||
132 | s.TeleportClientHome(p.ControllingClient.AgentId, p.ControllingClient); | ||
133 | } | ||
134 | }); | ||
135 | } | ||
136 | } | ||
137 | |||
138 | return SuccessResult(); | ||
139 | } | ||
140 | |||
141 | byte[] TeleportHomeOneUser(Dictionary<string, object> request) | ||
142 | { | ||
143 | UUID PreyID = UUID.Zero; | ||
144 | int EstateID = 0; | ||
145 | |||
146 | if (!request.ContainsKey("PreyID") || | ||
147 | !request.ContainsKey("EstateID")) | ||
148 | { | ||
149 | return FailureResult(); | ||
150 | } | ||
151 | |||
152 | if (!UUID.TryParse(request["PreyID"].ToString(), out PreyID)) | ||
153 | return FailureResult(); | ||
154 | |||
155 | if (!Int32.TryParse(request["EstateID"].ToString(), out EstateID)) | ||
156 | return FailureResult(); | ||
157 | |||
158 | foreach (Scene s in m_EstateModule.Scenes) | ||
159 | { | ||
160 | if (s.RegionInfo.EstateSettings.EstateID == EstateID) | ||
161 | { | ||
162 | ScenePresence p = s.GetScenePresence(PreyID); | ||
163 | if (p != null && !p.IsChildAgent) | ||
164 | { | ||
165 | p.ControllingClient.SendTeleportStart(16); | ||
166 | s.TeleportClientHome(PreyID, p.ControllingClient); | ||
167 | } | ||
168 | } | ||
169 | } | ||
170 | |||
171 | return SuccessResult(); | ||
172 | } | ||
173 | |||
174 | byte[] EstateMessage(Dictionary<string, object> request) | ||
175 | { | ||
176 | UUID FromID = UUID.Zero; | ||
177 | string FromName = String.Empty; | ||
178 | string Message = String.Empty; | ||
179 | int EstateID = 0; | ||
180 | |||
181 | if (!request.ContainsKey("FromID") || | ||
182 | !request.ContainsKey("FromName") || | ||
183 | !request.ContainsKey("Message") || | ||
184 | !request.ContainsKey("EstateID")) | ||
185 | { | ||
186 | return FailureResult(); | ||
187 | } | ||
188 | |||
189 | if (!UUID.TryParse(request["FromID"].ToString(), out FromID)) | ||
190 | return FailureResult(); | ||
191 | |||
192 | if (!Int32.TryParse(request["EstateID"].ToString(), out EstateID)) | ||
193 | return FailureResult(); | ||
194 | |||
195 | FromName = request["FromName"].ToString(); | ||
196 | Message = request["Message"].ToString(); | ||
197 | |||
198 | foreach (Scene s in m_EstateModule.Scenes) | ||
199 | { | ||
200 | if (s.RegionInfo.EstateSettings.EstateID == EstateID) | ||
201 | { | ||
202 | IDialogModule dm = s.RequestModuleInterface<IDialogModule>(); | ||
203 | |||
204 | if (dm != null) | ||
205 | { | ||
206 | dm.SendNotificationToUsersInRegion(FromID, FromName, | ||
207 | Message); | ||
208 | } | ||
209 | } | ||
210 | } | ||
211 | |||
212 | return SuccessResult(); | ||
213 | } | ||
214 | |||
215 | byte[] UpdateCovenant(Dictionary<string, object> request) | ||
216 | { | ||
217 | UUID CovenantID = UUID.Zero; | ||
218 | int EstateID = 0; | ||
219 | |||
220 | if (!request.ContainsKey("CovenantID") || !request.ContainsKey("EstateID")) | ||
221 | return FailureResult(); | ||
222 | |||
223 | if (!UUID.TryParse(request["CovenantID"].ToString(), out CovenantID)) | ||
224 | return FailureResult(); | ||
225 | |||
226 | if (!Int32.TryParse(request["EstateID"].ToString(), out EstateID)) | ||
227 | return FailureResult(); | ||
228 | |||
229 | foreach (Scene s in m_EstateModule.Scenes) | ||
230 | { | ||
231 | if (s.RegionInfo.EstateSettings.EstateID == (uint)EstateID) | ||
232 | s.RegionInfo.RegionSettings.Covenant = CovenantID; | ||
233 | } | ||
234 | |||
235 | return SuccessResult(); | ||
236 | } | ||
237 | |||
238 | byte[] UpdateEstate(Dictionary<string, object> request) | ||
239 | { | ||
240 | int EstateID = 0; | ||
241 | |||
242 | if (!request.ContainsKey("EstateID")) | ||
243 | return FailureResult(); | ||
244 | if (!Int32.TryParse(request["EstateID"].ToString(), out EstateID)) | ||
245 | return FailureResult(); | ||
246 | |||
247 | foreach (Scene s in m_EstateModule.Scenes) | ||
248 | { | ||
249 | if (s.RegionInfo.EstateSettings.EstateID == (uint)EstateID) | ||
250 | s.ReloadEstateData(); | ||
251 | } | ||
252 | return SuccessResult(); | ||
253 | } | ||
254 | |||
255 | private byte[] FailureResult() | ||
256 | { | ||
257 | return BoolResult(false); | ||
258 | } | ||
259 | |||
260 | private byte[] SuccessResult() | ||
261 | { | ||
262 | return BoolResult(true); | ||
263 | } | ||
264 | |||
265 | private byte[] BoolResult(bool value) | ||
266 | { | ||
267 | XmlDocument doc = new XmlDocument(); | ||
268 | |||
269 | XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration, | ||
270 | "", ""); | ||
271 | |||
272 | doc.AppendChild(xmlnode); | ||
273 | |||
274 | XmlElement rootElement = doc.CreateElement("", "ServerResponse", | ||
275 | ""); | ||
276 | |||
277 | doc.AppendChild(rootElement); | ||
278 | |||
279 | XmlElement result = doc.CreateElement("", "RESULT", ""); | ||
280 | result.AppendChild(doc.CreateTextNode(value.ToString())); | ||
281 | |||
282 | rootElement.AppendChild(result); | ||
283 | |||
284 | return DocToBytes(doc); | ||
285 | } | ||
286 | |||
287 | private byte[] DocToBytes(XmlDocument doc) | ||
288 | { | ||
289 | MemoryStream ms = new MemoryStream(); | ||
290 | XmlTextWriter xw = new XmlTextWriter(ms, null); | ||
291 | xw.Formatting = Formatting.Indented; | ||
292 | doc.WriteTo(xw); | ||
293 | xw.Flush(); | ||
294 | |||
295 | return ms.ToArray(); | ||
296 | } | ||
297 | } | ||
298 | } | ||
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 4e21724..0e2aba9 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs | |||
@@ -42,7 +42,6 @@ using OpenSim.Framework.Capabilities; | |||
42 | using OpenSim.Framework.Console; | 42 | using OpenSim.Framework.Console; |
43 | using OpenSim.Framework.Servers; | 43 | using OpenSim.Framework.Servers; |
44 | using OpenSim.Framework.Servers.HttpServer; | 44 | using OpenSim.Framework.Servers.HttpServer; |
45 | using OpenSim.Region.CoreModules.Framework.InterfaceCommander; | ||
46 | using OpenSim.Region.Framework.Interfaces; | 45 | using OpenSim.Region.Framework.Interfaces; |
47 | using OpenSim.Region.Framework.Scenes; | 46 | using OpenSim.Region.Framework.Scenes; |
48 | using OpenSim.Region.Physics.Manager; | 47 | using OpenSim.Region.Physics.Manager; |
@@ -70,10 +69,10 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
70 | 69 | ||
71 | private LandChannel landChannel; | 70 | private LandChannel landChannel; |
72 | private Scene m_scene; | 71 | private Scene m_scene; |
73 | protected Commander m_commander = new Commander("land"); | ||
74 | 72 | ||
75 | protected IUserManagement m_userManager; | 73 | protected IUserManagement m_userManager; |
76 | protected IPrimCountModule m_primCountModule; | 74 | protected IPrimCountModule m_primCountModule; |
75 | protected IDialogModule m_Dialog; | ||
77 | 76 | ||
78 | // Minimum for parcels to work is 64m even if we don't actually use them. | 77 | // Minimum for parcels to work is 64m even if we don't actually use them. |
79 | #pragma warning disable 0429 | 78 | #pragma warning disable 0429 |
@@ -147,52 +146,33 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
147 | m_scene.EventManager.OnIncomingLandDataFromStorage += EventManagerOnIncomingLandDataFromStorage; | 146 | m_scene.EventManager.OnIncomingLandDataFromStorage += EventManagerOnIncomingLandDataFromStorage; |
148 | m_scene.EventManager.OnSetAllowForcefulBan += EventManagerOnSetAllowedForcefulBan; | 147 | m_scene.EventManager.OnSetAllowForcefulBan += EventManagerOnSetAllowedForcefulBan; |
149 | m_scene.EventManager.OnRegisterCaps += EventManagerOnRegisterCaps; | 148 | m_scene.EventManager.OnRegisterCaps += EventManagerOnRegisterCaps; |
150 | m_scene.EventManager.OnPluginConsole += EventManagerOnPluginConsole; | ||
151 | 149 | ||
152 | lock (m_scene) | 150 | lock (m_scene) |
153 | { | 151 | { |
154 | m_scene.LandChannel = (ILandChannel)landChannel; | 152 | m_scene.LandChannel = (ILandChannel)landChannel; |
155 | } | 153 | } |
156 | 154 | ||
157 | InstallInterfaces(); | 155 | RegisterCommands(); |
158 | } | 156 | } |
159 | 157 | ||
160 | public void RegionLoaded(Scene scene) | 158 | public void RegionLoaded(Scene scene) |
161 | { | 159 | { |
162 | m_userManager = m_scene.RequestModuleInterface<IUserManagement>(); | 160 | m_userManager = m_scene.RequestModuleInterface<IUserManagement>(); |
163 | m_primCountModule = m_scene.RequestModuleInterface<IPrimCountModule>(); | 161 | m_primCountModule = m_scene.RequestModuleInterface<IPrimCountModule>(); |
162 | m_Dialog = m_scene.RequestModuleInterface<IDialogModule>(); | ||
164 | } | 163 | } |
165 | 164 | ||
166 | public void RemoveRegion(Scene scene) | 165 | public void RemoveRegion(Scene scene) |
167 | { | 166 | { |
168 | // TODO: Also release other event manager listeners here | 167 | // TODO: Release event manager listeners here |
169 | |||
170 | m_scene.EventManager.OnPluginConsole -= EventManagerOnPluginConsole; | ||
171 | m_scene.UnregisterModuleCommander(m_commander.Name); | ||
172 | } | 168 | } |
173 | 169 | ||
174 | /// <summary> | 170 | // private bool OnVerifyUserConnection(ScenePresence scenePresence, out string reason) |
175 | /// Processes commandline input. Do not call directly. | 171 | // { |
176 | /// </summary> | 172 | // ILandObject nearestParcel = m_scene.GetNearestAllowedParcel(scenePresence.UUID, scenePresence.AbsolutePosition.X, scenePresence.AbsolutePosition.Y); |
177 | /// <param name="args">Commandline arguments</param> | 173 | // reason = "You are not allowed to enter this sim."; |
178 | protected void EventManagerOnPluginConsole(string[] args) | 174 | // return nearestParcel != null; |
179 | { | 175 | // } |
180 | if (args[0] == "land") | ||
181 | { | ||
182 | if (args.Length == 1) | ||
183 | { | ||
184 | m_commander.ProcessConsoleCommand("help", new string[0]); | ||
185 | return; | ||
186 | } | ||
187 | |||
188 | string[] tmpArgs = new string[args.Length - 2]; | ||
189 | int i; | ||
190 | for (i = 2; i < args.Length; i++) | ||
191 | tmpArgs[i - 2] = args[i]; | ||
192 | |||
193 | m_commander.ProcessConsoleCommand(args[1], tmpArgs); | ||
194 | } | ||
195 | } | ||
196 | 176 | ||
197 | void EventManagerOnNewClient(IClientAPI client) | 177 | void EventManagerOnNewClient(IClientAPI client) |
198 | { | 178 | { |
@@ -213,6 +193,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
213 | client.OnPreAgentUpdate += ClientOnPreAgentUpdate; | 193 | client.OnPreAgentUpdate += ClientOnPreAgentUpdate; |
214 | client.OnParcelEjectUser += ClientOnParcelEjectUser; | 194 | client.OnParcelEjectUser += ClientOnParcelEjectUser; |
215 | client.OnParcelFreezeUser += ClientOnParcelFreezeUser; | 195 | client.OnParcelFreezeUser += ClientOnParcelFreezeUser; |
196 | client.OnSetStartLocationRequest += ClientOnSetHome; | ||
216 | 197 | ||
217 | EntityBase presenceEntity; | 198 | EntityBase presenceEntity; |
218 | if (m_scene.Entities.TryGetValue(client.AgentId, out presenceEntity) && presenceEntity is ScenePresence) | 199 | if (m_scene.Entities.TryGetValue(client.AgentId, out presenceEntity) && presenceEntity is ScenePresence) |
@@ -1896,44 +1877,131 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1896 | land.LandData.ParcelAccessList.Add(entry); | 1877 | land.LandData.ParcelAccessList.Add(entry); |
1897 | } | 1878 | } |
1898 | } | 1879 | } |
1899 | 1880 | ||
1900 | protected void InstallInterfaces() | 1881 | /// <summary> |
1882 | /// Sets the Home Point. The LoginService uses this to know where to put a user when they log-in | ||
1883 | /// </summary> | ||
1884 | /// <param name="remoteClient"></param> | ||
1885 | /// <param name="regionHandle"></param> | ||
1886 | /// <param name="position"></param> | ||
1887 | /// <param name="lookAt"></param> | ||
1888 | /// <param name="flags"></param> | ||
1889 | public virtual void ClientOnSetHome(IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags) | ||
1890 | { | ||
1891 | // Let's find the parcel in question | ||
1892 | ILandObject land = landChannel.GetLandObject(position); | ||
1893 | if (land == null || m_scene.GridUserService == null) | ||
1894 | { | ||
1895 | m_Dialog.SendAlertToUser(remoteClient, "Set Home request failed."); | ||
1896 | return; | ||
1897 | } | ||
1898 | |||
1899 | // Gather some data | ||
1900 | ulong gpowers = remoteClient.GetGroupPowers(land.LandData.GroupID); | ||
1901 | SceneObjectGroup telehub = null; | ||
1902 | if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero) | ||
1903 | // Does the telehub exist in the scene? | ||
1904 | telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject); | ||
1905 | |||
1906 | // Can the user set home here? | ||
1907 | if (// (a) gods and land managers can set home | ||
1908 | m_scene.Permissions.IsAdministrator(remoteClient.AgentId) || | ||
1909 | m_scene.Permissions.IsGod(remoteClient.AgentId) || | ||
1910 | // (b) land owners can set home | ||
1911 | remoteClient.AgentId == land.LandData.OwnerID || | ||
1912 | // (c) members of the land-associated group in roles that can set home | ||
1913 | ((gpowers & (ulong)GroupPowers.AllowSetHome) == (ulong)GroupPowers.AllowSetHome) || | ||
1914 | // (d) parcels with telehubs can be the home of anyone | ||
1915 | (telehub != null && land.ContainsPoint((int)telehub.AbsolutePosition.X, (int)telehub.AbsolutePosition.Y))) | ||
1916 | { | ||
1917 | if (m_scene.GridUserService.SetHome(remoteClient.AgentId.ToString(), land.RegionUUID, position, lookAt)) | ||
1918 | // FUBAR ALERT: this needs to be "Home position set." so the viewer saves a home-screenshot. | ||
1919 | m_Dialog.SendAlertToUser(remoteClient, "Home position set."); | ||
1920 | else | ||
1921 | m_Dialog.SendAlertToUser(remoteClient, "Set Home request failed."); | ||
1922 | } | ||
1923 | else | ||
1924 | m_Dialog.SendAlertToUser(remoteClient, "You are not allowed to set your home location in this parcel."); | ||
1925 | } | ||
1926 | |||
1927 | protected void RegisterCommands() | ||
1901 | { | 1928 | { |
1902 | Command clearCommand | 1929 | ICommands commands = MainConsole.Instance.Commands; |
1903 | = new Command("clear", CommandIntentions.COMMAND_HAZARDOUS, ClearCommand, "Clears all the parcels from the region."); | ||
1904 | Command showCommand | ||
1905 | = new Command("show", CommandIntentions.COMMAND_STATISTICAL, ShowParcelsCommand, "Shows all parcels on the region."); | ||
1906 | 1930 | ||
1907 | m_commander.RegisterCommand("clear", clearCommand); | 1931 | commands.AddCommand( |
1908 | m_commander.RegisterCommand("show", showCommand); | 1932 | "Land", false, "land clear", |
1933 | "land clear", | ||
1934 | "Clear all the parcels from the region.", | ||
1935 | "Command will ask for confirmation before proceeding.", | ||
1936 | HandleClearCommand); | ||
1909 | 1937 | ||
1910 | // Add this to our scene so scripts can call these functions | 1938 | commands.AddCommand( |
1911 | m_scene.RegisterModuleCommander(m_commander); | 1939 | "Land", false, "land show", |
1940 | "land show [<local-land-id>]", | ||
1941 | "Show information about the parcels on the region.", | ||
1942 | "If no local land ID is given, then summary information about all the parcels is shown.\n" | ||
1943 | + "If a local land ID is given then full information about that parcel is shown.", | ||
1944 | HandleShowCommand); | ||
1912 | } | 1945 | } |
1913 | 1946 | ||
1914 | protected void ClearCommand(Object[] args) | 1947 | protected void HandleClearCommand(string module, string[] args) |
1915 | { | 1948 | { |
1949 | if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_scene)) | ||
1950 | return; | ||
1951 | |||
1916 | string response = MainConsole.Instance.CmdPrompt( | 1952 | string response = MainConsole.Instance.CmdPrompt( |
1917 | string.Format( | 1953 | string.Format( |
1918 | "Are you sure that you want to clear all land parcels from {0} (y or n)", | 1954 | "Are you sure that you want to clear all land parcels from {0} (y or n)", m_scene.Name), |
1919 | m_scene.RegionInfo.RegionName), | ||
1920 | "n"); | 1955 | "n"); |
1921 | 1956 | ||
1922 | if (response.ToLower() == "y") | 1957 | if (response.ToLower() == "y") |
1923 | { | 1958 | { |
1924 | Clear(true); | 1959 | Clear(true); |
1925 | MainConsole.Instance.OutputFormat("Cleared all parcels from {0}", m_scene.RegionInfo.RegionName); | 1960 | MainConsole.Instance.OutputFormat("Cleared all parcels from {0}", m_scene.Name); |
1926 | } | 1961 | } |
1927 | else | 1962 | else |
1928 | { | 1963 | { |
1929 | MainConsole.Instance.OutputFormat("Aborting clear of all parcels from {0}", m_scene.RegionInfo.RegionName); | 1964 | MainConsole.Instance.OutputFormat("Aborting clear of all parcels from {0}", m_scene.Name); |
1930 | } | 1965 | } |
1931 | } | 1966 | } |
1932 | 1967 | ||
1933 | protected void ShowParcelsCommand(Object[] args) | 1968 | protected void HandleShowCommand(string module, string[] args) |
1934 | { | 1969 | { |
1935 | StringBuilder report = new StringBuilder(); | 1970 | if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_scene)) |
1936 | 1971 | return; | |
1972 | |||
1973 | StringBuilder report = new StringBuilder(); | ||
1974 | |||
1975 | if (args.Length <= 2) | ||
1976 | { | ||
1977 | AppendParcelsSummaryReport(report); | ||
1978 | } | ||
1979 | else | ||
1980 | { | ||
1981 | int landLocalId; | ||
1982 | |||
1983 | if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[2], out landLocalId)) | ||
1984 | return; | ||
1985 | |||
1986 | ILandObject lo; | ||
1987 | |||
1988 | lock (m_landList) | ||
1989 | { | ||
1990 | if (!m_landList.TryGetValue(landLocalId, out lo)) | ||
1991 | { | ||
1992 | MainConsole.Instance.OutputFormat("No parcel found with local ID {0}", landLocalId); | ||
1993 | return; | ||
1994 | } | ||
1995 | } | ||
1996 | |||
1997 | AppendParcelReport(report, lo); | ||
1998 | } | ||
1999 | |||
2000 | MainConsole.Instance.Output(report.ToString()); | ||
2001 | } | ||
2002 | |||
2003 | private void AppendParcelsSummaryReport(StringBuilder report) | ||
2004 | { | ||
1937 | report.AppendFormat("Land information for {0}\n", m_scene.RegionInfo.RegionName); | 2005 | report.AppendFormat("Land information for {0}\n", m_scene.RegionInfo.RegionName); |
1938 | report.AppendFormat( | 2006 | report.AppendFormat( |
1939 | "{0,-20} {1,-10} {2,-9} {3,-18} {4,-18} {5,-20}\n", | 2007 | "{0,-20} {1,-10} {2,-9} {3,-18} {4,-18} {5,-20}\n", |
@@ -1979,6 +2047,69 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1979 | ForceAvatarToPosition(avatar, avatar.lastKnownAllowedPosition); | 2047 | ForceAvatarToPosition(avatar, avatar.lastKnownAllowedPosition); |
1980 | } | 2048 | } |
1981 | } | 2049 | } |
2050 | } | ||
2051 | |||
2052 | private void AppendParcelReport(StringBuilder report, ILandObject lo) | ||
2053 | { | ||
2054 | LandData ld = lo.LandData; | ||
2055 | |||
2056 | ConsoleDisplayList cdl = new ConsoleDisplayList(); | ||
2057 | cdl.AddRow("Parcel name", ld.Name); | ||
2058 | cdl.AddRow("Local ID", ld.LocalID); | ||
2059 | cdl.AddRow("Description", ld.Description); | ||
2060 | cdl.AddRow("Snapshot ID", ld.SnapshotID); | ||
2061 | cdl.AddRow("Area", ld.Area); | ||
2062 | cdl.AddRow("Starts", lo.StartPoint); | ||
2063 | cdl.AddRow("Ends", lo.EndPoint); | ||
2064 | cdl.AddRow("AABB Min", ld.AABBMin); | ||
2065 | cdl.AddRow("AABB Max", ld.AABBMax); | ||
2066 | |||
2067 | cdl.AddRow("Owner", m_userManager.GetUserName(ld.OwnerID)); | ||
2068 | cdl.AddRow("Is group owned?", ld.IsGroupOwned); | ||
2069 | cdl.AddRow("GroupID", ld.GroupID); | ||
2070 | |||
2071 | cdl.AddRow("Status", ld.Status); | ||
2072 | cdl.AddRow("Flags", (ParcelFlags)ld.Flags); | ||
2073 | |||
2074 | cdl.AddRow("Landing Type", (LandingType)ld.LandingType); | ||
2075 | cdl.AddRow("User Location", ld.UserLocation); | ||
2076 | cdl.AddRow("User look at", ld.UserLookAt); | ||
2077 | |||
2078 | cdl.AddRow("Other clean time", ld.OtherCleanTime); | ||
2079 | |||
2080 | cdl.AddRow("Max Prims", lo.GetParcelMaxPrimCount()); | ||
2081 | IPrimCounts pc = lo.PrimCounts; | ||
2082 | cdl.AddRow("Owner Prims", pc.Owner); | ||
2083 | cdl.AddRow("Group Prims", pc.Group); | ||
2084 | cdl.AddRow("Other Prims", pc.Others); | ||
2085 | cdl.AddRow("Selected Prims", pc.Selected); | ||
2086 | cdl.AddRow("Total Prims", pc.Total); | ||
2087 | |||
2088 | cdl.AddRow("Music URL", ld.MusicURL); | ||
2089 | cdl.AddRow("Obscure Music", ld.ObscureMusic); | ||
2090 | |||
2091 | cdl.AddRow("Media ID", ld.MediaID); | ||
2092 | cdl.AddRow("Media Autoscale", Convert.ToBoolean(ld.MediaAutoScale)); | ||
2093 | cdl.AddRow("Media URL", ld.MediaURL); | ||
2094 | cdl.AddRow("Media Type", ld.MediaType); | ||
2095 | cdl.AddRow("Media Description", ld.MediaDescription); | ||
2096 | cdl.AddRow("Media Width", ld.MediaWidth); | ||
2097 | cdl.AddRow("Media Height", ld.MediaHeight); | ||
2098 | cdl.AddRow("Media Loop", ld.MediaLoop); | ||
2099 | cdl.AddRow("Obscure Media", ld.ObscureMedia); | ||
2100 | |||
2101 | cdl.AddRow("Parcel Category", ld.Category); | ||
2102 | |||
2103 | cdl.AddRow("Claim Date", ld.ClaimDate); | ||
2104 | cdl.AddRow("Claim Price", ld.ClaimPrice); | ||
2105 | cdl.AddRow("Pass Hours", ld.PassHours); | ||
2106 | cdl.AddRow("Pass Price", ld.PassPrice); | ||
2107 | |||
2108 | cdl.AddRow("Auction ID", ld.AuctionID); | ||
2109 | cdl.AddRow("Authorized Buyer ID", ld.AuthBuyerID); | ||
2110 | cdl.AddRow("Sale Price", ld.SalePrice); | ||
2111 | |||
2112 | cdl.AddToStringBuilder(report); | ||
1982 | } | 2113 | } |
1983 | } | 2114 | } |
1984 | } | 2115 | } |
diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index 2eafd44..74c2144 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs | |||
@@ -82,14 +82,14 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
82 | 82 | ||
83 | set { m_landData = value; } | 83 | set { m_landData = value; } |
84 | } | 84 | } |
85 | 85 | ||
86 | public IPrimCounts PrimCounts { get; set; } | 86 | public IPrimCounts PrimCounts { get; set; } |
87 | 87 | ||
88 | public UUID RegionUUID | 88 | public UUID RegionUUID |
89 | { | 89 | { |
90 | get { return m_scene.RegionInfo.RegionID; } | 90 | get { return m_scene.RegionInfo.RegionID; } |
91 | } | 91 | } |
92 | 92 | ||
93 | public Vector3 StartPoint | 93 | public Vector3 StartPoint |
94 | { | 94 | { |
95 | get | 95 | get |
@@ -102,11 +102,11 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
102 | return new Vector3(x * 4, y * 4, 0); | 102 | return new Vector3(x * 4, y * 4, 0); |
103 | } | 103 | } |
104 | } | 104 | } |
105 | 105 | ||
106 | return new Vector3(-1, -1, -1); | 106 | return new Vector3(-1, -1, -1); |
107 | } | 107 | } |
108 | } | 108 | } |
109 | 109 | ||
110 | public Vector3 EndPoint | 110 | public Vector3 EndPoint |
111 | { | 111 | { |
112 | get | 112 | get |
@@ -117,15 +117,15 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
117 | { | 117 | { |
118 | if (LandBitmap[x, y]) | 118 | if (LandBitmap[x, y]) |
119 | { | 119 | { |
120 | return new Vector3(x * 4, y * 4, 0); | 120 | return new Vector3(x * 4 + 4, y * 4 + 4, 0); |
121 | } | 121 | } |
122 | } | 122 | } |
123 | } | 123 | } |
124 | 124 | ||
125 | return new Vector3(-1, -1, -1); | 125 | return new Vector3(-1, -1, -1); |
126 | } | 126 | } |
127 | } | 127 | } |
128 | 128 | ||
129 | #region Constructors | 129 | #region Constructors |
130 | 130 | ||
131 | public LandObject(UUID owner_id, bool is_group_owned, Scene scene) | 131 | public LandObject(UUID owner_id, bool is_group_owned, Scene scene) |
@@ -249,13 +249,6 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
249 | if (estateModule != null) | 249 | if (estateModule != null) |
250 | regionFlags = estateModule.GetRegionFlags(); | 250 | regionFlags = estateModule.GetRegionFlags(); |
251 | 251 | ||
252 | // In a perfect world, this would have worked. | ||
253 | // | ||
254 | // if ((landData.Flags & (uint)ParcelFlags.AllowLandmark) != 0) | ||
255 | // regionFlags |= (uint)RegionFlags.AllowLandmark; | ||
256 | // if (landData.OwnerID == remote_client.AgentId) | ||
257 | // regionFlags |= (uint)RegionFlags.AllowSetHome; | ||
258 | |||
259 | int seq_id; | 252 | int seq_id; |
260 | if (snap_selection && (sequence_id == 0)) | 253 | if (snap_selection && (sequence_id == 0)) |
261 | { | 254 | { |
diff --git a/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs b/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs index 40638f8..bc52a43 100644 --- a/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs +++ b/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs | |||
@@ -55,7 +55,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
55 | public struct DrawStruct | 55 | public struct DrawStruct |
56 | { | 56 | { |
57 | public DrawRoutine dr; | 57 | public DrawRoutine dr; |
58 | public Rectangle rect; | 58 | // public Rectangle rect; |
59 | public SolidBrush brush; | 59 | public SolidBrush brush; |
60 | public face[] trns; | 60 | public face[] trns; |
61 | } | 61 | } |
@@ -119,6 +119,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
119 | { | 119 | { |
120 | mapbmp = FetchTexture(m_scene.RegionInfo.RegionSettings.TerrainImageID); | 120 | mapbmp = FetchTexture(m_scene.RegionInfo.RegionSettings.TerrainImageID); |
121 | } | 121 | } |
122 | |||
122 | return mapbmp; | 123 | return mapbmp; |
123 | } | 124 | } |
124 | 125 | ||
@@ -127,7 +128,10 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
127 | try | 128 | try |
128 | { | 129 | { |
129 | using (Bitmap mapbmp = CreateMapTile()) | 130 | using (Bitmap mapbmp = CreateMapTile()) |
130 | return OpenJPEG.EncodeFromImage(mapbmp, true); | 131 | { |
132 | if (mapbmp != null) | ||
133 | return OpenJPEG.EncodeFromImage(mapbmp, true); | ||
134 | } | ||
131 | } | 135 | } |
132 | catch (Exception e) // LEGIT: Catching problems caused by OpenJPEG p/invoke | 136 | catch (Exception e) // LEGIT: Catching problems caused by OpenJPEG p/invoke |
133 | { | 137 | { |
@@ -277,321 +281,331 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
277 | tc = Environment.TickCount; | 281 | tc = Environment.TickCount; |
278 | m_log.Debug("[MAPTILE]: Generating Maptile Step 2: Object Volume Profile"); | 282 | m_log.Debug("[MAPTILE]: Generating Maptile Step 2: Object Volume Profile"); |
279 | EntityBase[] objs = whichScene.GetEntities(); | 283 | EntityBase[] objs = whichScene.GetEntities(); |
280 | Dictionary<uint, DrawStruct> z_sort = new Dictionary<uint, DrawStruct>(); | ||
281 | //SortedList<float, RectangleDrawStruct> z_sort = new SortedList<float, RectangleDrawStruct>(); | ||
282 | List<float> z_sortheights = new List<float>(); | 284 | List<float> z_sortheights = new List<float>(); |
283 | List<uint> z_localIDs = new List<uint>(); | 285 | List<uint> z_localIDs = new List<uint>(); |
286 | Dictionary<uint, DrawStruct> z_sort = new Dictionary<uint, DrawStruct>(); | ||
284 | 287 | ||
285 | lock (objs) | 288 | try |
286 | { | 289 | { |
287 | foreach (EntityBase obj in objs) | 290 | //SortedList<float, RectangleDrawStruct> z_sort = new SortedList<float, RectangleDrawStruct>(); |
291 | |||
292 | lock (objs) | ||
288 | { | 293 | { |
289 | // Only draw the contents of SceneObjectGroup | 294 | foreach (EntityBase obj in objs) |
290 | if (obj is SceneObjectGroup) | ||
291 | { | 295 | { |
292 | SceneObjectGroup mapdot = (SceneObjectGroup)obj; | 296 | // Only draw the contents of SceneObjectGroup |
293 | Color mapdotspot = Color.Gray; // Default color when prim color is white | 297 | if (obj is SceneObjectGroup) |
294 | |||
295 | // Loop over prim in group | ||
296 | foreach (SceneObjectPart part in mapdot.Parts) | ||
297 | { | 298 | { |
298 | if (part == null) | 299 | SceneObjectGroup mapdot = (SceneObjectGroup)obj; |
299 | continue; | 300 | Color mapdotspot = Color.Gray; // Default color when prim color is white |
300 | 301 | ||
301 | // Draw if the object is at least 1 meter wide in any direction | 302 | // Loop over prim in group |
302 | if (part.Scale.X > 1f || part.Scale.Y > 1f || part.Scale.Z > 1f) | 303 | foreach (SceneObjectPart part in mapdot.Parts) |
303 | { | 304 | { |
304 | // Try to get the RGBA of the default texture entry.. | 305 | if (part == null) |
305 | // | 306 | continue; |
306 | try | 307 | |
308 | // Draw if the object is at least 1 meter wide in any direction | ||
309 | if (part.Scale.X > 1f || part.Scale.Y > 1f || part.Scale.Z > 1f) | ||
307 | { | 310 | { |
308 | // get the null checks out of the way | 311 | // Try to get the RGBA of the default texture entry.. |
309 | // skip the ones that break | 312 | // |
310 | if (part == null) | 313 | try |
311 | continue; | 314 | { |
315 | // get the null checks out of the way | ||
316 | // skip the ones that break | ||
317 | if (part == null) | ||
318 | continue; | ||
312 | 319 | ||
313 | if (part.Shape == null) | 320 | if (part.Shape == null) |
314 | continue; | 321 | continue; |
315 | 322 | ||
316 | if (part.Shape.PCode == (byte)PCode.Tree || part.Shape.PCode == (byte)PCode.NewTree || part.Shape.PCode == (byte)PCode.Grass) | 323 | if (part.Shape.PCode == (byte)PCode.Tree || part.Shape.PCode == (byte)PCode.NewTree || part.Shape.PCode == (byte)PCode.Grass) |
317 | continue; // eliminates trees from this since we don't really have a good tree representation | 324 | continue; // eliminates trees from this since we don't really have a good tree representation |
318 | // if you want tree blocks on the map comment the above line and uncomment the below line | 325 | // if you want tree blocks on the map comment the above line and uncomment the below line |
319 | //mapdotspot = Color.PaleGreen; | 326 | //mapdotspot = Color.PaleGreen; |
320 | 327 | ||
321 | Primitive.TextureEntry textureEntry = part.Shape.Textures; | 328 | Primitive.TextureEntry textureEntry = part.Shape.Textures; |
322 | 329 | ||
323 | if (textureEntry == null || textureEntry.DefaultTexture == null) | 330 | if (textureEntry == null || textureEntry.DefaultTexture == null) |
324 | continue; | 331 | continue; |
325 | 332 | ||
326 | Color4 texcolor = textureEntry.DefaultTexture.RGBA; | 333 | Color4 texcolor = textureEntry.DefaultTexture.RGBA; |
327 | 334 | ||
328 | // Not sure why some of these are null, oh well. | 335 | // Not sure why some of these are null, oh well. |
329 | 336 | ||
330 | int colorr = 255 - (int)(texcolor.R * 255f); | 337 | int colorr = 255 - (int)(texcolor.R * 255f); |
331 | int colorg = 255 - (int)(texcolor.G * 255f); | 338 | int colorg = 255 - (int)(texcolor.G * 255f); |
332 | int colorb = 255 - (int)(texcolor.B * 255f); | 339 | int colorb = 255 - (int)(texcolor.B * 255f); |
333 | 340 | ||
334 | if (!(colorr == 255 && colorg == 255 && colorb == 255)) | 341 | if (!(colorr == 255 && colorg == 255 && colorb == 255)) |
335 | { | ||
336 | //Try to set the map spot color | ||
337 | try | ||
338 | { | ||
339 | // If the color gets goofy somehow, skip it *shakes fist at Color4 | ||
340 | mapdotspot = Color.FromArgb(colorr, colorg, colorb); | ||
341 | } | ||
342 | catch (ArgumentException) | ||
343 | { | 342 | { |
343 | //Try to set the map spot color | ||
344 | try | ||
345 | { | ||
346 | // If the color gets goofy somehow, skip it *shakes fist at Color4 | ||
347 | mapdotspot = Color.FromArgb(colorr, colorg, colorb); | ||
348 | } | ||
349 | catch (ArgumentException) | ||
350 | { | ||
351 | } | ||
344 | } | 352 | } |
345 | } | 353 | } |
346 | } | 354 | catch (IndexOutOfRangeException) |
347 | catch (IndexOutOfRangeException) | 355 | { |
348 | { | 356 | // Windows Array |
349 | // Windows Array | 357 | } |
350 | } | 358 | catch (ArgumentOutOfRangeException) |
351 | catch (ArgumentOutOfRangeException) | 359 | { |
352 | { | 360 | // Mono Array |
353 | // Mono Array | 361 | } |
354 | } | ||
355 | |||
356 | Vector3 pos = part.GetWorldPosition(); | ||
357 | |||
358 | // skip prim outside of retion | ||
359 | if (pos.X < 0f || pos.X > 256f || pos.Y < 0f || pos.Y > 256f) | ||
360 | continue; | ||
361 | |||
362 | // skip prim in non-finite position | ||
363 | if (Single.IsNaN(pos.X) || Single.IsNaN(pos.Y) || | ||
364 | Single.IsInfinity(pos.X) || Single.IsInfinity(pos.Y)) | ||
365 | continue; | ||
366 | |||
367 | // Figure out if object is under 256m above the height of the terrain | ||
368 | bool isBelow256AboveTerrain = false; | ||
369 | 362 | ||
370 | try | 363 | Vector3 pos = part.GetWorldPosition(); |
371 | { | ||
372 | isBelow256AboveTerrain = (pos.Z < ((float)hm[(int)pos.X, (int)pos.Y] + 256f)); | ||
373 | } | ||
374 | catch (Exception) | ||
375 | { | ||
376 | } | ||
377 | 364 | ||
378 | if (isBelow256AboveTerrain) | 365 | // skip prim outside of retion |
379 | { | 366 | if (pos.X < 0f || pos.X > 256f || pos.Y < 0f || pos.Y > 256f) |
380 | // Translate scale by rotation so scale is represented properly when object is rotated | ||
381 | Vector3 lscale = new Vector3(part.Shape.Scale.X, part.Shape.Scale.Y, part.Shape.Scale.Z); | ||
382 | Vector3 scale = new Vector3(); | ||
383 | Vector3 tScale = new Vector3(); | ||
384 | Vector3 axPos = new Vector3(pos.X,pos.Y,pos.Z); | ||
385 | |||
386 | Quaternion llrot = part.GetWorldRotation(); | ||
387 | Quaternion rot = new Quaternion(llrot.W, llrot.X, llrot.Y, llrot.Z); | ||
388 | scale = lscale * rot; | ||
389 | |||
390 | // negative scales don't work in this situation | ||
391 | scale.X = Math.Abs(scale.X); | ||
392 | scale.Y = Math.Abs(scale.Y); | ||
393 | scale.Z = Math.Abs(scale.Z); | ||
394 | |||
395 | // This scaling isn't very accurate and doesn't take into account the face rotation :P | ||
396 | int mapdrawstartX = (int)(pos.X - scale.X); | ||
397 | int mapdrawstartY = (int)(pos.Y - scale.Y); | ||
398 | int mapdrawendX = (int)(pos.X + scale.X); | ||
399 | int mapdrawendY = (int)(pos.Y + scale.Y); | ||
400 | |||
401 | // If object is beyond the edge of the map, don't draw it to avoid errors | ||
402 | if (mapdrawstartX < 0 || mapdrawstartX > ((int)Constants.RegionSize - 1) || mapdrawendX < 0 || mapdrawendX > ((int)Constants.RegionSize - 1) | ||
403 | || mapdrawstartY < 0 || mapdrawstartY > ((int)Constants.RegionSize - 1) || mapdrawendY < 0 | ||
404 | || mapdrawendY > ((int)Constants.RegionSize - 1)) | ||
405 | continue; | 367 | continue; |
406 | 368 | ||
407 | #region obb face reconstruction part duex | 369 | // skip prim in non-finite position |
408 | Vector3[] vertexes = new Vector3[8]; | 370 | if (Single.IsNaN(pos.X) || Single.IsNaN(pos.Y) || |
409 | 371 | Single.IsInfinity(pos.X) || Single.IsInfinity(pos.Y)) | |
410 | // float[] distance = new float[6]; | 372 | continue; |
411 | Vector3[] FaceA = new Vector3[6]; // vertex A for Facei | ||
412 | Vector3[] FaceB = new Vector3[6]; // vertex B for Facei | ||
413 | Vector3[] FaceC = new Vector3[6]; // vertex C for Facei | ||
414 | Vector3[] FaceD = new Vector3[6]; // vertex D for Facei | ||
415 | |||
416 | tScale = new Vector3(lscale.X, -lscale.Y, lscale.Z); | ||
417 | scale = ((tScale * rot)); | ||
418 | vertexes[0] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
419 | // vertexes[0].x = pos.X + vertexes[0].x; | ||
420 | //vertexes[0].y = pos.Y + vertexes[0].y; | ||
421 | //vertexes[0].z = pos.Z + vertexes[0].z; | ||
422 | |||
423 | FaceA[0] = vertexes[0]; | ||
424 | FaceB[3] = vertexes[0]; | ||
425 | FaceA[4] = vertexes[0]; | ||
426 | |||
427 | tScale = lscale; | ||
428 | scale = ((tScale * rot)); | ||
429 | vertexes[1] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
430 | |||
431 | // vertexes[1].x = pos.X + vertexes[1].x; | ||
432 | // vertexes[1].y = pos.Y + vertexes[1].y; | ||
433 | //vertexes[1].z = pos.Z + vertexes[1].z; | ||
434 | |||
435 | FaceB[0] = vertexes[1]; | ||
436 | FaceA[1] = vertexes[1]; | ||
437 | FaceC[4] = vertexes[1]; | ||
438 | |||
439 | tScale = new Vector3(lscale.X, -lscale.Y, -lscale.Z); | ||
440 | scale = ((tScale * rot)); | ||
441 | |||
442 | vertexes[2] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
443 | |||
444 | //vertexes[2].x = pos.X + vertexes[2].x; | ||
445 | //vertexes[2].y = pos.Y + vertexes[2].y; | ||
446 | //vertexes[2].z = pos.Z + vertexes[2].z; | ||
447 | |||
448 | FaceC[0] = vertexes[2]; | ||
449 | FaceD[3] = vertexes[2]; | ||
450 | FaceC[5] = vertexes[2]; | ||
451 | |||
452 | tScale = new Vector3(lscale.X, lscale.Y, -lscale.Z); | ||
453 | scale = ((tScale * rot)); | ||
454 | vertexes[3] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
455 | |||
456 | //vertexes[3].x = pos.X + vertexes[3].x; | ||
457 | // vertexes[3].y = pos.Y + vertexes[3].y; | ||
458 | // vertexes[3].z = pos.Z + vertexes[3].z; | ||
459 | |||
460 | FaceD[0] = vertexes[3]; | ||
461 | FaceC[1] = vertexes[3]; | ||
462 | FaceA[5] = vertexes[3]; | ||
463 | |||
464 | tScale = new Vector3(-lscale.X, lscale.Y, lscale.Z); | ||
465 | scale = ((tScale * rot)); | ||
466 | vertexes[4] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
467 | |||
468 | // vertexes[4].x = pos.X + vertexes[4].x; | ||
469 | // vertexes[4].y = pos.Y + vertexes[4].y; | ||
470 | // vertexes[4].z = pos.Z + vertexes[4].z; | ||
471 | |||
472 | FaceB[1] = vertexes[4]; | ||
473 | FaceA[2] = vertexes[4]; | ||
474 | FaceD[4] = vertexes[4]; | ||
475 | |||
476 | tScale = new Vector3(-lscale.X, lscale.Y, -lscale.Z); | ||
477 | scale = ((tScale * rot)); | ||
478 | vertexes[5] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
479 | |||
480 | // vertexes[5].x = pos.X + vertexes[5].x; | ||
481 | // vertexes[5].y = pos.Y + vertexes[5].y; | ||
482 | // vertexes[5].z = pos.Z + vertexes[5].z; | ||
483 | |||
484 | FaceD[1] = vertexes[5]; | ||
485 | FaceC[2] = vertexes[5]; | ||
486 | FaceB[5] = vertexes[5]; | ||
487 | 373 | ||
488 | tScale = new Vector3(-lscale.X, -lscale.Y, lscale.Z); | 374 | // Figure out if object is under 256m above the height of the terrain |
489 | scale = ((tScale * rot)); | 375 | bool isBelow256AboveTerrain = false; |
490 | vertexes[6] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
491 | 376 | ||
492 | // vertexes[6].x = pos.X + vertexes[6].x; | 377 | try |
493 | // vertexes[6].y = pos.Y + vertexes[6].y; | 378 | { |
494 | // vertexes[6].z = pos.Z + vertexes[6].z; | 379 | isBelow256AboveTerrain = (pos.Z < ((float)hm[(int)pos.X, (int)pos.Y] + 256f)); |
380 | } | ||
381 | catch (Exception) | ||
382 | { | ||
383 | } | ||
495 | 384 | ||
496 | FaceB[2] = vertexes[6]; | 385 | if (isBelow256AboveTerrain) |
497 | FaceA[3] = vertexes[6]; | 386 | { |
498 | FaceB[4] = vertexes[6]; | 387 | // Translate scale by rotation so scale is represented properly when object is rotated |
388 | Vector3 lscale = new Vector3(part.Shape.Scale.X, part.Shape.Scale.Y, part.Shape.Scale.Z); | ||
389 | Vector3 scale = new Vector3(); | ||
390 | Vector3 tScale = new Vector3(); | ||
391 | Vector3 axPos = new Vector3(pos.X,pos.Y,pos.Z); | ||
392 | |||
393 | Quaternion llrot = part.GetWorldRotation(); | ||
394 | Quaternion rot = new Quaternion(llrot.W, llrot.X, llrot.Y, llrot.Z); | ||
395 | scale = lscale * rot; | ||
396 | |||
397 | // negative scales don't work in this situation | ||
398 | scale.X = Math.Abs(scale.X); | ||
399 | scale.Y = Math.Abs(scale.Y); | ||
400 | scale.Z = Math.Abs(scale.Z); | ||
401 | |||
402 | // This scaling isn't very accurate and doesn't take into account the face rotation :P | ||
403 | int mapdrawstartX = (int)(pos.X - scale.X); | ||
404 | int mapdrawstartY = (int)(pos.Y - scale.Y); | ||
405 | int mapdrawendX = (int)(pos.X + scale.X); | ||
406 | int mapdrawendY = (int)(pos.Y + scale.Y); | ||
407 | |||
408 | // If object is beyond the edge of the map, don't draw it to avoid errors | ||
409 | if (mapdrawstartX < 0 || mapdrawstartX > ((int)Constants.RegionSize - 1) || mapdrawendX < 0 || mapdrawendX > ((int)Constants.RegionSize - 1) | ||
410 | || mapdrawstartY < 0 || mapdrawstartY > ((int)Constants.RegionSize - 1) || mapdrawendY < 0 | ||
411 | || mapdrawendY > ((int)Constants.RegionSize - 1)) | ||
412 | continue; | ||
413 | |||
414 | #region obb face reconstruction part duex | ||
415 | Vector3[] vertexes = new Vector3[8]; | ||
416 | |||
417 | // float[] distance = new float[6]; | ||
418 | Vector3[] FaceA = new Vector3[6]; // vertex A for Facei | ||
419 | Vector3[] FaceB = new Vector3[6]; // vertex B for Facei | ||
420 | Vector3[] FaceC = new Vector3[6]; // vertex C for Facei | ||
421 | Vector3[] FaceD = new Vector3[6]; // vertex D for Facei | ||
422 | |||
423 | tScale = new Vector3(lscale.X, -lscale.Y, lscale.Z); | ||
424 | scale = ((tScale * rot)); | ||
425 | vertexes[0] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
426 | // vertexes[0].x = pos.X + vertexes[0].x; | ||
427 | //vertexes[0].y = pos.Y + vertexes[0].y; | ||
428 | //vertexes[0].z = pos.Z + vertexes[0].z; | ||
429 | |||
430 | FaceA[0] = vertexes[0]; | ||
431 | FaceB[3] = vertexes[0]; | ||
432 | FaceA[4] = vertexes[0]; | ||
433 | |||
434 | tScale = lscale; | ||
435 | scale = ((tScale * rot)); | ||
436 | vertexes[1] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
437 | |||
438 | // vertexes[1].x = pos.X + vertexes[1].x; | ||
439 | // vertexes[1].y = pos.Y + vertexes[1].y; | ||
440 | //vertexes[1].z = pos.Z + vertexes[1].z; | ||
441 | |||
442 | FaceB[0] = vertexes[1]; | ||
443 | FaceA[1] = vertexes[1]; | ||
444 | FaceC[4] = vertexes[1]; | ||
445 | |||
446 | tScale = new Vector3(lscale.X, -lscale.Y, -lscale.Z); | ||
447 | scale = ((tScale * rot)); | ||
448 | |||
449 | vertexes[2] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
450 | |||
451 | //vertexes[2].x = pos.X + vertexes[2].x; | ||
452 | //vertexes[2].y = pos.Y + vertexes[2].y; | ||
453 | //vertexes[2].z = pos.Z + vertexes[2].z; | ||
454 | |||
455 | FaceC[0] = vertexes[2]; | ||
456 | FaceD[3] = vertexes[2]; | ||
457 | FaceC[5] = vertexes[2]; | ||
458 | |||
459 | tScale = new Vector3(lscale.X, lscale.Y, -lscale.Z); | ||
460 | scale = ((tScale * rot)); | ||
461 | vertexes[3] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
462 | |||
463 | //vertexes[3].x = pos.X + vertexes[3].x; | ||
464 | // vertexes[3].y = pos.Y + vertexes[3].y; | ||
465 | // vertexes[3].z = pos.Z + vertexes[3].z; | ||
466 | |||
467 | FaceD[0] = vertexes[3]; | ||
468 | FaceC[1] = vertexes[3]; | ||
469 | FaceA[5] = vertexes[3]; | ||
470 | |||
471 | tScale = new Vector3(-lscale.X, lscale.Y, lscale.Z); | ||
472 | scale = ((tScale * rot)); | ||
473 | vertexes[4] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
474 | |||
475 | // vertexes[4].x = pos.X + vertexes[4].x; | ||
476 | // vertexes[4].y = pos.Y + vertexes[4].y; | ||
477 | // vertexes[4].z = pos.Z + vertexes[4].z; | ||
478 | |||
479 | FaceB[1] = vertexes[4]; | ||
480 | FaceA[2] = vertexes[4]; | ||
481 | FaceD[4] = vertexes[4]; | ||
482 | |||
483 | tScale = new Vector3(-lscale.X, lscale.Y, -lscale.Z); | ||
484 | scale = ((tScale * rot)); | ||
485 | vertexes[5] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
486 | |||
487 | // vertexes[5].x = pos.X + vertexes[5].x; | ||
488 | // vertexes[5].y = pos.Y + vertexes[5].y; | ||
489 | // vertexes[5].z = pos.Z + vertexes[5].z; | ||
490 | |||
491 | FaceD[1] = vertexes[5]; | ||
492 | FaceC[2] = vertexes[5]; | ||
493 | FaceB[5] = vertexes[5]; | ||
494 | |||
495 | tScale = new Vector3(-lscale.X, -lscale.Y, lscale.Z); | ||
496 | scale = ((tScale * rot)); | ||
497 | vertexes[6] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | ||
498 | |||
499 | // vertexes[6].x = pos.X + vertexes[6].x; | ||
500 | // vertexes[6].y = pos.Y + vertexes[6].y; | ||
501 | // vertexes[6].z = pos.Z + vertexes[6].z; | ||
502 | |||
503 | FaceB[2] = vertexes[6]; | ||
504 | FaceA[3] = vertexes[6]; | ||
505 | FaceB[4] = vertexes[6]; | ||
499 | 506 | ||
500 | tScale = new Vector3(-lscale.X, -lscale.Y, -lscale.Z); | 507 | tScale = new Vector3(-lscale.X, -lscale.Y, -lscale.Z); |
501 | scale = ((tScale * rot)); | 508 | scale = ((tScale * rot)); |
502 | vertexes[7] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); | 509 | vertexes[7] = (new Vector3((pos.X + scale.X), (pos.Y + scale.Y), (pos.Z + scale.Z))); |
503 | 510 | ||
504 | // vertexes[7].x = pos.X + vertexes[7].x; | 511 | // vertexes[7].x = pos.X + vertexes[7].x; |
505 | // vertexes[7].y = pos.Y + vertexes[7].y; | 512 | // vertexes[7].y = pos.Y + vertexes[7].y; |
506 | // vertexes[7].z = pos.Z + vertexes[7].z; | 513 | // vertexes[7].z = pos.Z + vertexes[7].z; |
507 | 514 | ||
508 | FaceD[2] = vertexes[7]; | 515 | FaceD[2] = vertexes[7]; |
509 | FaceC[3] = vertexes[7]; | 516 | FaceC[3] = vertexes[7]; |
510 | FaceD[5] = vertexes[7]; | 517 | FaceD[5] = vertexes[7]; |
511 | #endregion | 518 | #endregion |
512 | 519 | ||
513 | //int wy = 0; | 520 | //int wy = 0; |
514 | 521 | ||
515 | //bool breakYN = false; // If we run into an error drawing, break out of the | 522 | //bool breakYN = false; // If we run into an error drawing, break out of the |
516 | // loop so we don't lag to death on error handling | 523 | // loop so we don't lag to death on error handling |
517 | DrawStruct ds = new DrawStruct(); | 524 | DrawStruct ds = new DrawStruct(); |
518 | ds.brush = new SolidBrush(mapdotspot); | 525 | ds.brush = new SolidBrush(mapdotspot); |
519 | //ds.rect = new Rectangle(mapdrawstartX, (255 - mapdrawstartY), mapdrawendX - mapdrawstartX, mapdrawendY - mapdrawstartY); | 526 | //ds.rect = new Rectangle(mapdrawstartX, (255 - mapdrawstartY), mapdrawendX - mapdrawstartX, mapdrawendY - mapdrawstartY); |
520 | 527 | ||
521 | ds.trns = new face[FaceA.Length]; | 528 | ds.trns = new face[FaceA.Length]; |
522 | 529 | ||
523 | for (int i = 0; i < FaceA.Length; i++) | 530 | for (int i = 0; i < FaceA.Length; i++) |
524 | { | 531 | { |
525 | Point[] working = new Point[5]; | 532 | Point[] working = new Point[5]; |
526 | working[0] = project(FaceA[i], axPos); | 533 | working[0] = project(FaceA[i], axPos); |
527 | working[1] = project(FaceB[i], axPos); | 534 | working[1] = project(FaceB[i], axPos); |
528 | working[2] = project(FaceD[i], axPos); | 535 | working[2] = project(FaceD[i], axPos); |
529 | working[3] = project(FaceC[i], axPos); | 536 | working[3] = project(FaceC[i], axPos); |
530 | working[4] = project(FaceA[i], axPos); | 537 | working[4] = project(FaceA[i], axPos); |
531 | 538 | ||
532 | face workingface = new face(); | 539 | face workingface = new face(); |
533 | workingface.pts = working; | 540 | workingface.pts = working; |
534 | 541 | ||
535 | ds.trns[i] = workingface; | 542 | ds.trns[i] = workingface; |
536 | } | 543 | } |
537 | 544 | ||
538 | z_sort.Add(part.LocalId, ds); | 545 | z_sort.Add(part.LocalId, ds); |
539 | z_localIDs.Add(part.LocalId); | 546 | z_localIDs.Add(part.LocalId); |
540 | z_sortheights.Add(pos.Z); | 547 | z_sortheights.Add(pos.Z); |
541 | 548 | ||
542 | //for (int wx = mapdrawstartX; wx < mapdrawendX; wx++) | 549 | //for (int wx = mapdrawstartX; wx < mapdrawendX; wx++) |
543 | //{ | ||
544 | //for (wy = mapdrawstartY; wy < mapdrawendY; wy++) | ||
545 | //{ | 550 | //{ |
546 | //m_log.InfoFormat("[MAPDEBUG]: {0},{1}({2})", wx, (255 - wy),wy); | 551 | //for (wy = mapdrawstartY; wy < mapdrawendY; wy++) |
547 | //try | ||
548 | //{ | ||
549 | // Remember, flip the y! | ||
550 | // mapbmp.SetPixel(wx, (255 - wy), mapdotspot); | ||
551 | //} | ||
552 | //catch (ArgumentException) | ||
553 | //{ | 552 | //{ |
554 | // breakYN = true; | 553 | //m_log.InfoFormat("[MAPDEBUG]: {0},{1}({2})", wx, (255 - wy),wy); |
554 | //try | ||
555 | //{ | ||
556 | // Remember, flip the y! | ||
557 | // mapbmp.SetPixel(wx, (255 - wy), mapdotspot); | ||
558 | //} | ||
559 | //catch (ArgumentException) | ||
560 | //{ | ||
561 | // breakYN = true; | ||
562 | //} | ||
563 | |||
564 | //if (breakYN) | ||
565 | // break; | ||
555 | //} | 566 | //} |
556 | 567 | ||
557 | //if (breakYN) | 568 | //if (breakYN) |
558 | // break; | 569 | // break; |
559 | //} | 570 | //} |
571 | } // Object is within 256m Z of terrain | ||
572 | } // object is at least a meter wide | ||
573 | } // loop over group children | ||
574 | } // entitybase is sceneobject group | ||
575 | } // foreach loop over entities | ||
560 | 576 | ||
561 | //if (breakYN) | 577 | float[] sortedZHeights = z_sortheights.ToArray(); |
562 | // break; | 578 | uint[] sortedlocalIds = z_localIDs.ToArray(); |
563 | //} | ||
564 | } // Object is within 256m Z of terrain | ||
565 | } // object is at least a meter wide | ||
566 | } // loop over group children | ||
567 | } // entitybase is sceneobject group | ||
568 | } // foreach loop over entities | ||
569 | |||
570 | float[] sortedZHeights = z_sortheights.ToArray(); | ||
571 | uint[] sortedlocalIds = z_localIDs.ToArray(); | ||
572 | |||
573 | // Sort prim by Z position | ||
574 | Array.Sort(sortedZHeights, sortedlocalIds); | ||
575 | 579 | ||
576 | Graphics g = Graphics.FromImage(mapbmp); | 580 | // Sort prim by Z position |
581 | Array.Sort(sortedZHeights, sortedlocalIds); | ||
577 | 582 | ||
578 | for (int s = 0; s < sortedZHeights.Length; s++) | 583 | using (Graphics g = Graphics.FromImage(mapbmp)) |
579 | { | ||
580 | if (z_sort.ContainsKey(sortedlocalIds[s])) | ||
581 | { | 584 | { |
582 | DrawStruct rectDrawStruct = z_sort[sortedlocalIds[s]]; | 585 | for (int s = 0; s < sortedZHeights.Length; s++) |
583 | for (int r = 0; r < rectDrawStruct.trns.Length; r++) | ||
584 | { | 586 | { |
585 | g.FillPolygon(rectDrawStruct.brush,rectDrawStruct.trns[r].pts); | 587 | if (z_sort.ContainsKey(sortedlocalIds[s])) |
588 | { | ||
589 | DrawStruct rectDrawStruct = z_sort[sortedlocalIds[s]]; | ||
590 | for (int r = 0; r < rectDrawStruct.trns.Length; r++) | ||
591 | { | ||
592 | g.FillPolygon(rectDrawStruct.brush,rectDrawStruct.trns[r].pts); | ||
593 | } | ||
594 | //g.FillRectangle(rectDrawStruct.brush , rectDrawStruct.rect); | ||
595 | } | ||
586 | } | 596 | } |
587 | //g.FillRectangle(rectDrawStruct.brush , rectDrawStruct.rect); | ||
588 | } | 597 | } |
589 | } | 598 | } // lock entities objs |
590 | 599 | ||
591 | g.Dispose(); | 600 | } |
592 | } // lock entities objs | 601 | finally |
602 | { | ||
603 | foreach (DrawStruct ds in z_sort.Values) | ||
604 | ds.brush.Dispose(); | ||
605 | } | ||
593 | 606 | ||
594 | m_log.Debug("[MAPTILE]: Generating Maptile Step 2: Done in " + (Environment.TickCount - tc) + " ms"); | 607 | m_log.Debug("[MAPTILE]: Generating Maptile Step 2: Done in " + (Environment.TickCount - tc) + " ms"); |
608 | |||
595 | return mapbmp; | 609 | return mapbmp; |
596 | } | 610 | } |
597 | 611 | ||
diff --git a/OpenSim/Region/CoreModules/World/LegacyMap/ShadedMapTileRenderer.cs b/OpenSim/Region/CoreModules/World/LegacyMap/ShadedMapTileRenderer.cs index 992bff3..cb06fd4 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.Debug("[MAPTILE]: Generating Maptile Step 1: Terrain"); | 57 | m_log.Debug("[SHADED MAP TILE RENDERER]: 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; |
@@ -199,7 +199,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
199 | { | 199 | { |
200 | if (!terraincorruptedwarningsaid) | 200 | if (!terraincorruptedwarningsaid) |
201 | { | 201 | { |
202 | m_log.WarnFormat("[MAPIMAGE]: Your terrain is corrupted in region {0}, it might take a few minutes to generate the map image depending on the corruption level", m_scene.RegionInfo.RegionName); | 202 | m_log.WarnFormat("[SHADED MAP TILE RENDERER]: Your terrain is corrupted in region {0}, it might take a few minutes to generate the map image depending on the corruption level", m_scene.RegionInfo.RegionName); |
203 | terraincorruptedwarningsaid = true; | 203 | terraincorruptedwarningsaid = true; |
204 | } | 204 | } |
205 | color = Color.Black; | 205 | color = Color.Black; |
@@ -229,7 +229,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
229 | { | 229 | { |
230 | if (!terraincorruptedwarningsaid) | 230 | if (!terraincorruptedwarningsaid) |
231 | { | 231 | { |
232 | m_log.WarnFormat("[MAPIMAGE]: Your terrain is corrupted in region {0}, it might take a few minutes to generate the map image depending on the corruption level", m_scene.RegionInfo.RegionName); | 232 | m_log.WarnFormat("[SHADED MAP TILE RENDERER]: Your terrain is corrupted in region {0}, it might take a few minutes to generate the map image depending on the corruption level", m_scene.RegionInfo.RegionName); |
233 | terraincorruptedwarningsaid = true; | 233 | terraincorruptedwarningsaid = true; |
234 | } | 234 | } |
235 | Color black = Color.Black; | 235 | Color black = Color.Black; |
@@ -238,7 +238,8 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
238 | } | 238 | } |
239 | } | 239 | } |
240 | } | 240 | } |
241 | m_log.Debug("[MAPTILE]: Generating Maptile Step 1: Done in " + (Environment.TickCount - tc) + " ms"); | 241 | |
242 | m_log.Debug("[SHADED MAP TILE RENDERER]: Generating Maptile Step 1: Done in " + (Environment.TickCount - tc) + " ms"); | ||
242 | } | 243 | } |
243 | } | 244 | } |
244 | } | 245 | } \ No newline at end of file |
diff --git a/OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs b/OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs index d13c2ef..e895178 100644 --- a/OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs +++ b/OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs | |||
@@ -173,7 +173,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
173 | private Bitmap fetchTexture(UUID id) | 173 | private Bitmap fetchTexture(UUID id) |
174 | { | 174 | { |
175 | AssetBase asset = m_scene.AssetService.Get(id.ToString()); | 175 | AssetBase asset = m_scene.AssetService.Get(id.ToString()); |
176 | m_log.DebugFormat("[TexturedMapTileRenderer]: Fetched texture {0}, found: {1}", id, asset != null); | 176 | m_log.DebugFormat("[TEXTURED MAP TILE RENDERER]: Fetched texture {0}, found: {1}", id, asset != null); |
177 | if (asset == null) return null; | 177 | if (asset == null) return null; |
178 | 178 | ||
179 | ManagedImage managedImage; | 179 | ManagedImage managedImage; |
@@ -188,17 +188,17 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
188 | } | 188 | } |
189 | catch (DllNotFoundException) | 189 | catch (DllNotFoundException) |
190 | { | 190 | { |
191 | m_log.ErrorFormat("[TexturedMapTileRenderer]: OpenJpeg is not installed correctly on this system. Asset Data is empty for {0}", id); | 191 | m_log.ErrorFormat("[TEXTURED MAP TILE RENDERER]: OpenJpeg is not installed correctly on this system. Asset Data is empty for {0}", id); |
192 | 192 | ||
193 | } | 193 | } |
194 | catch (IndexOutOfRangeException) | 194 | catch (IndexOutOfRangeException) |
195 | { | 195 | { |
196 | m_log.ErrorFormat("[TexturedMapTileRenderer]: OpenJpeg was unable to encode this. Asset Data is empty for {0}", id); | 196 | m_log.ErrorFormat("[TEXTURED MAP TILE RENDERER]: OpenJpeg was unable to encode this. Asset Data is empty for {0}", id); |
197 | 197 | ||
198 | } | 198 | } |
199 | catch (Exception) | 199 | catch (Exception) |
200 | { | 200 | { |
201 | m_log.ErrorFormat("[TexturedMapTileRenderer]: OpenJpeg was unable to encode this. Asset Data is empty for {0}", id); | 201 | m_log.ErrorFormat("[TEXTURED MAP TILE RENDERER]: OpenJpeg was unable to encode this. Asset Data is empty for {0}", id); |
202 | 202 | ||
203 | } | 203 | } |
204 | return null; | 204 | return null; |
@@ -233,10 +233,14 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
233 | if (textureID == UUID.Zero) return defaultColor; // not set | 233 | if (textureID == UUID.Zero) return defaultColor; // not set |
234 | if (m_mapping.ContainsKey(textureID)) return m_mapping[textureID]; // one of the predefined textures | 234 | if (m_mapping.ContainsKey(textureID)) return m_mapping[textureID]; // one of the predefined textures |
235 | 235 | ||
236 | Bitmap bmp = fetchTexture(textureID); | 236 | Color color; |
237 | Color color = bmp == null ? defaultColor : computeAverageColor(bmp); | 237 | |
238 | // store it for future reference | 238 | using (Bitmap bmp = fetchTexture(textureID)) |
239 | m_mapping[textureID] = color; | 239 | { |
240 | color = bmp == null ? defaultColor : computeAverageColor(bmp); | ||
241 | // store it for future reference | ||
242 | m_mapping[textureID] = color; | ||
243 | } | ||
240 | 244 | ||
241 | return color; | 245 | return color; |
242 | } | 246 | } |
@@ -278,7 +282,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
278 | public void TerrainToBitmap(Bitmap mapbmp) | 282 | public void TerrainToBitmap(Bitmap mapbmp) |
279 | { | 283 | { |
280 | int tc = Environment.TickCount; | 284 | int tc = Environment.TickCount; |
281 | m_log.Debug("[MAPTILE]: Generating Maptile Step 1: Terrain"); | 285 | m_log.Debug("[TEXTURED MAP TILE RENDERER]: Generating Maptile Step 1: Terrain"); |
282 | 286 | ||
283 | // These textures should be in the AssetCache anyway, as every client conneting to this | 287 | // 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), | 288 | // region needs them. Except on start, when the map is recreated (before anyone connected), |
@@ -412,7 +416,8 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap | |||
412 | } | 416 | } |
413 | } | 417 | } |
414 | } | 418 | } |
415 | m_log.Debug("[MAPTILE]: Generating Maptile Step 1: Done in " + (Environment.TickCount - tc) + " ms"); | 419 | |
420 | m_log.Debug("[TEXTURED MAP TILE RENDERER]: Generating Maptile Step 1: Done in " + (Environment.TickCount - tc) + " ms"); | ||
416 | } | 421 | } |
417 | } | 422 | } |
418 | } | 423 | } \ No newline at end of file |
diff --git a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs index 28daf2f..d4e4c25 100644 --- a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs +++ b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs | |||
@@ -205,13 +205,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell | |||
205 | item.InvType = (int)InventoryType.Object; | 205 | item.InvType = (int)InventoryType.Object; |
206 | item.Folder = categoryID; | 206 | item.Folder = categoryID; |
207 | 207 | ||
208 | uint nextPerms=(perms & 7) << 13; | 208 | PermissionsUtil.ApplyFoldedPermissions(perms, ref perms); |
209 | if ((nextPerms & (uint)PermissionMask.Copy) == 0) | ||
210 | perms &= ~(uint)PermissionMask.Copy; | ||
211 | if ((nextPerms & (uint)PermissionMask.Transfer) == 0) | ||
212 | perms &= ~(uint)PermissionMask.Transfer; | ||
213 | if ((nextPerms & (uint)PermissionMask.Modify) == 0) | ||
214 | perms &= ~(uint)PermissionMask.Modify; | ||
215 | 209 | ||
216 | item.BasePermissions = perms & part.NextOwnerMask; | 210 | item.BasePermissions = perms & part.NextOwnerMask; |
217 | item.CurrentPermissions = perms & part.NextOwnerMask; | 211 | item.CurrentPermissions = perms & part.NextOwnerMask; |
diff --git a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs index e434b2e..e77f0aa 100644 --- a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs +++ b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs | |||
@@ -546,7 +546,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands | |||
546 | { | 546 | { |
547 | ConsoleDisplayList cdl = new ConsoleDisplayList(); | 547 | ConsoleDisplayList cdl = new ConsoleDisplayList(); |
548 | cdl.AddRow("Name", so.Name); | 548 | cdl.AddRow("Name", so.Name); |
549 | cdl.AddRow("Descrition", so.Description); | 549 | cdl.AddRow("Description", so.Description); |
550 | cdl.AddRow("Local ID", so.LocalId); | 550 | cdl.AddRow("Local ID", so.LocalId); |
551 | cdl.AddRow("UUID", so.UUID); | 551 | cdl.AddRow("UUID", so.UUID); |
552 | cdl.AddRow("Location", string.Format("{0} @ {1}", so.AbsolutePosition, so.Scene.Name)); | 552 | cdl.AddRow("Location", string.Format("{0} @ {1}", so.AbsolutePosition, so.Scene.Name)); |
@@ -631,7 +631,22 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands | |||
631 | cdl.AddRow("SculptType", s.SculptType); | 631 | cdl.AddRow("SculptType", s.SculptType); |
632 | cdl.AddRow("State", s.State); | 632 | cdl.AddRow("State", s.State); |
633 | 633 | ||
634 | // TODO, unpack and display texture entries | 634 | // TODO, need to display more information about textures but in a compact format |
635 | // to stop output becoming huge. | ||
636 | for (int i = 0; i < sop.GetNumberOfSides(); i++) | ||
637 | { | ||
638 | Primitive.TextureEntryFace teFace = s.Textures.FaceTextures[i]; | ||
639 | |||
640 | UUID textureID; | ||
641 | |||
642 | if (teFace != null) | ||
643 | textureID = teFace.TextureID; | ||
644 | else | ||
645 | textureID = s.Textures.DefaultTexture.TextureID; | ||
646 | |||
647 | cdl.AddRow(string.Format("Face {0} texture ID", i), textureID); | ||
648 | } | ||
649 | |||
635 | //cdl.AddRow("Textures", string.Format("{0} entries", s.Textures. | 650 | //cdl.AddRow("Textures", string.Format("{0} entries", s.Textures. |
636 | } | 651 | } |
637 | 652 | ||
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index 4f5b9b7..616fe98 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs | |||
@@ -1453,6 +1453,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions | |||
1453 | 1453 | ||
1454 | bool permission = false; | 1454 | bool permission = false; |
1455 | 1455 | ||
1456 | // m_log.DebugFormat("[PERMISSIONS MODULE]: Checking rez object at {0} in {1}", objectPosition, m_scene.Name); | ||
1457 | |||
1456 | ILandObject land = m_scene.LandChannel.GetLandObject(objectPosition.X, objectPosition.Y); | 1458 | ILandObject land = m_scene.LandChannel.GetLandObject(objectPosition.X, objectPosition.Y); |
1457 | if (land == null) return false; | 1459 | if (land == null) return false; |
1458 | 1460 | ||
diff --git a/OpenSim/Region/CoreModules/World/Region/RestartModule.cs b/OpenSim/Region/CoreModules/World/Region/RestartModule.cs index 9c441ed..0c74b49 100644 --- a/OpenSim/Region/CoreModules/World/Region/RestartModule.cs +++ b/OpenSim/Region/CoreModules/World/Region/RestartModule.cs | |||
@@ -48,8 +48,8 @@ namespace OpenSim.Region.CoreModules.World.Region | |||
48 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RestartModule")] | 48 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RestartModule")] |
49 | public class RestartModule : INonSharedRegionModule, IRestartModule | 49 | public class RestartModule : INonSharedRegionModule, IRestartModule |
50 | { | 50 | { |
51 | // private static readonly ILog m_log = | 51 | private static readonly ILog m_log = |
52 | // LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 52 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
53 | 53 | ||
54 | protected Scene m_Scene; | 54 | protected Scene m_Scene; |
55 | protected Timer m_CountdownTimer = null; | 55 | protected Timer m_CountdownTimer = null; |
@@ -223,11 +223,25 @@ namespace OpenSim.Region.CoreModules.World.Region | |||
223 | 223 | ||
224 | public void SetTimer(int intervalSeconds) | 224 | public void SetTimer(int intervalSeconds) |
225 | { | 225 | { |
226 | m_CountdownTimer = new Timer(); | 226 | if (intervalSeconds > 0) |
227 | m_CountdownTimer.AutoReset = false; | 227 | { |
228 | m_CountdownTimer.Interval = intervalSeconds * 1000; | 228 | m_CountdownTimer = new Timer(); |
229 | m_CountdownTimer.Elapsed += OnTimer; | 229 | m_CountdownTimer.AutoReset = false; |
230 | m_CountdownTimer.Start(); | 230 | m_CountdownTimer.Interval = intervalSeconds * 1000; |
231 | m_CountdownTimer.Elapsed += OnTimer; | ||
232 | m_CountdownTimer.Start(); | ||
233 | } | ||
234 | else if (m_CountdownTimer != null) | ||
235 | { | ||
236 | m_CountdownTimer.Stop(); | ||
237 | m_CountdownTimer = null; | ||
238 | } | ||
239 | else | ||
240 | { | ||
241 | m_log.WarnFormat( | ||
242 | "[RESTART MODULE]: Tried to set restart timer to {0} in {1}, which is not a valid interval", | ||
243 | intervalSeconds, m_Scene.Name); | ||
244 | } | ||
231 | } | 245 | } |
232 | 246 | ||
233 | private void OnTimer(object source, ElapsedEventArgs e) | 247 | private void OnTimer(object source, ElapsedEventArgs e) |
@@ -332,4 +346,4 @@ namespace OpenSim.Region.CoreModules.World.Region | |||
332 | } | 346 | } |
333 | } | 347 | } |
334 | } | 348 | } |
335 | } \ No newline at end of file | 349 | } |
diff --git a/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs b/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs index b4348c9..66059fb 100644 --- a/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs +++ b/OpenSim/Region/CoreModules/World/Serialiser/Tests/SerialiserTests.cs | |||
@@ -144,7 +144,20 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests | |||
144 | <Flags>None</Flags> | 144 | <Flags>None</Flags> |
145 | <CollisionSound><Guid>00000000-0000-0000-0000-000000000000</Guid></CollisionSound> | 145 | <CollisionSound><Guid>00000000-0000-0000-0000-000000000000</Guid></CollisionSound> |
146 | <CollisionSoundVolume>0</CollisionSoundVolume> | 146 | <CollisionSoundVolume>0</CollisionSoundVolume> |
147 | <DynAttrs><llsd><map><key>MyStore</key><map><key>the answer</key><integer>42</integer></map></map></llsd></DynAttrs> | 147 | <DynAttrs> |
148 | <llsd> | ||
149 | <map> | ||
150 | <key>MyNamespace</key> | ||
151 | <map> | ||
152 | <key>MyStore</key> | ||
153 | <map> | ||
154 | <key>the answer</key> | ||
155 | <integer>42</integer> | ||
156 | </map> | ||
157 | </map> | ||
158 | </map> | ||
159 | </llsd> | ||
160 | </DynAttrs> | ||
148 | </SceneObjectPart> | 161 | </SceneObjectPart> |
149 | </RootPart> | 162 | </RootPart> |
150 | <OtherParts /> | 163 | <OtherParts /> |
@@ -333,7 +346,20 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests | |||
333 | <EveryoneMask>0</EveryoneMask> | 346 | <EveryoneMask>0</EveryoneMask> |
334 | <NextOwnerMask>2147483647</NextOwnerMask> | 347 | <NextOwnerMask>2147483647</NextOwnerMask> |
335 | <Flags>None</Flags> | 348 | <Flags>None</Flags> |
336 | <DynAttrs><llsd><map><key>MyStore</key><map><key>last words</key><string>Rosebud</string></map></map></llsd></DynAttrs> | 349 | <DynAttrs> |
350 | <llsd> | ||
351 | <map> | ||
352 | <key>MyNamespace</key> | ||
353 | <map> | ||
354 | <key>MyStore</key> | ||
355 | <map> | ||
356 | <key>last words</key> | ||
357 | <string>Rosebud</string> | ||
358 | </map> | ||
359 | </map> | ||
360 | </map> | ||
361 | </llsd> | ||
362 | </DynAttrs> | ||
337 | <SitTargetAvatar><UUID>00000000-0000-0000-0000-000000000000</UUID></SitTargetAvatar> | 363 | <SitTargetAvatar><UUID>00000000-0000-0000-0000-000000000000</UUID></SitTargetAvatar> |
338 | </SceneObjectPart> | 364 | </SceneObjectPart> |
339 | <OtherParts /> | 365 | <OtherParts /> |
@@ -362,7 +388,7 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests | |||
362 | Assert.That(rootPart.UUID, Is.EqualTo(new UUID("e6a5a05e-e8cc-4816-8701-04165e335790"))); | 388 | Assert.That(rootPart.UUID, Is.EqualTo(new UUID("e6a5a05e-e8cc-4816-8701-04165e335790"))); |
363 | Assert.That(rootPart.CreatorID, Is.EqualTo(new UUID("a6dacf01-4636-4bb9-8a97-30609438af9d"))); | 389 | Assert.That(rootPart.CreatorID, Is.EqualTo(new UUID("a6dacf01-4636-4bb9-8a97-30609438af9d"))); |
364 | Assert.That(rootPart.Name, Is.EqualTo("PrimMyRide")); | 390 | Assert.That(rootPart.Name, Is.EqualTo("PrimMyRide")); |
365 | OSDMap store = rootPart.DynAttrs["MyStore"]; | 391 | OSDMap store = rootPart.DynAttrs.GetStore("MyNamespace", "MyStore"); |
366 | Assert.AreEqual(42, store["the answer"].AsInteger()); | 392 | Assert.AreEqual(42, store["the answer"].AsInteger()); |
367 | 393 | ||
368 | // TODO: Check other properties | 394 | // TODO: Check other properties |
@@ -414,13 +440,14 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests | |||
414 | rp.CreatorID = rpCreatorId; | 440 | rp.CreatorID = rpCreatorId; |
415 | rp.Shape = shape; | 441 | rp.Shape = shape; |
416 | 442 | ||
443 | string daNamespace = "MyNamespace"; | ||
417 | string daStoreName = "MyStore"; | 444 | string daStoreName = "MyStore"; |
418 | string daKey = "foo"; | 445 | string daKey = "foo"; |
419 | string daValue = "bar"; | 446 | string daValue = "bar"; |
420 | OSDMap myStore = new OSDMap(); | 447 | OSDMap myStore = new OSDMap(); |
421 | myStore.Add(daKey, daValue); | 448 | myStore.Add(daKey, daValue); |
422 | rp.DynAttrs = new DAMap(); | 449 | rp.DynAttrs = new DAMap(); |
423 | rp.DynAttrs[daStoreName] = myStore; | 450 | rp.DynAttrs.SetStore(daNamespace, daStoreName, myStore); |
424 | 451 | ||
425 | SceneObjectGroup so = new SceneObjectGroup(rp); | 452 | SceneObjectGroup so = new SceneObjectGroup(rp); |
426 | 453 | ||
@@ -481,7 +508,7 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests | |||
481 | Assert.That(name, Is.EqualTo(rpName)); | 508 | Assert.That(name, Is.EqualTo(rpName)); |
482 | Assert.That(creatorId, Is.EqualTo(rpCreatorId)); | 509 | Assert.That(creatorId, Is.EqualTo(rpCreatorId)); |
483 | Assert.NotNull(daMap); | 510 | Assert.NotNull(daMap); |
484 | Assert.AreEqual(daValue, daMap[daStoreName][daKey].AsString()); | 511 | Assert.AreEqual(daValue, daMap.GetStore(daNamespace, daStoreName)[daKey].AsString()); |
485 | } | 512 | } |
486 | 513 | ||
487 | [Test] | 514 | [Test] |
@@ -496,7 +523,7 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests | |||
496 | Assert.That(rootPart.UUID, Is.EqualTo(new UUID("9be68fdd-f740-4a0f-9675-dfbbb536b946"))); | 523 | Assert.That(rootPart.UUID, Is.EqualTo(new UUID("9be68fdd-f740-4a0f-9675-dfbbb536b946"))); |
497 | Assert.That(rootPart.CreatorID, Is.EqualTo(new UUID("b46ef588-411e-4a8b-a284-d7dcfe8e74ef"))); | 524 | Assert.That(rootPart.CreatorID, Is.EqualTo(new UUID("b46ef588-411e-4a8b-a284-d7dcfe8e74ef"))); |
498 | Assert.That(rootPart.Name, Is.EqualTo("PrimFun")); | 525 | Assert.That(rootPart.Name, Is.EqualTo("PrimFun")); |
499 | OSDMap store = rootPart.DynAttrs["MyStore"]; | 526 | OSDMap store = rootPart.DynAttrs.GetStore("MyNamespace", "MyStore"); |
500 | Assert.AreEqual("Rosebud", store["last words"].AsString()); | 527 | Assert.AreEqual("Rosebud", store["last words"].AsString()); |
501 | 528 | ||
502 | // TODO: Check other properties | 529 | // TODO: Check other properties |
@@ -522,13 +549,14 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests | |||
522 | rp.CreatorID = rpCreatorId; | 549 | rp.CreatorID = rpCreatorId; |
523 | rp.Shape = shape; | 550 | rp.Shape = shape; |
524 | 551 | ||
552 | string daNamespace = "MyNamespace"; | ||
525 | string daStoreName = "MyStore"; | 553 | string daStoreName = "MyStore"; |
526 | string daKey = "foo"; | 554 | string daKey = "foo"; |
527 | string daValue = "bar"; | 555 | string daValue = "bar"; |
528 | OSDMap myStore = new OSDMap(); | 556 | OSDMap myStore = new OSDMap(); |
529 | myStore.Add(daKey, daValue); | 557 | myStore.Add(daKey, daValue); |
530 | rp.DynAttrs = new DAMap(); | 558 | rp.DynAttrs = new DAMap(); |
531 | rp.DynAttrs[daStoreName] = myStore; | 559 | rp.DynAttrs.SetStore(daNamespace, daStoreName, myStore); |
532 | 560 | ||
533 | SceneObjectGroup so = new SceneObjectGroup(rp); | 561 | SceneObjectGroup so = new SceneObjectGroup(rp); |
534 | 562 | ||
@@ -585,7 +613,7 @@ namespace OpenSim.Region.CoreModules.World.Serialiser.Tests | |||
585 | Assert.That(name, Is.EqualTo(rpName)); | 613 | Assert.That(name, Is.EqualTo(rpName)); |
586 | Assert.That(creatorId, Is.EqualTo(rpCreatorId)); | 614 | Assert.That(creatorId, Is.EqualTo(rpCreatorId)); |
587 | Assert.NotNull(daMap); | 615 | Assert.NotNull(daMap); |
588 | Assert.AreEqual(daValue, daMap[daStoreName][daKey].AsString()); | 616 | Assert.AreEqual(daValue, daMap.GetStore(daNamespace, daStoreName)[daKey].AsString()); |
589 | } | 617 | } |
590 | } | 618 | } |
591 | } \ No newline at end of file | 619 | } \ No newline at end of file |
diff --git a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs index 883045a..d093224 100644 --- a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs +++ b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs | |||
@@ -369,6 +369,15 @@ namespace OpenSim.Region.CoreModules.World.Sound | |||
369 | }); | 369 | }); |
370 | } | 370 | } |
371 | 371 | ||
372 | public void SetSoundQueueing(UUID objectID, bool shouldQueue) | ||
373 | { | ||
374 | SceneObjectPart part; | ||
375 | if (!m_scene.TryGetSceneObjectPart(objectID, out part)) | ||
376 | return; | ||
377 | |||
378 | part.SoundQueueing = shouldQueue; | ||
379 | } | ||
380 | |||
372 | #endregion | 381 | #endregion |
373 | } | 382 | } |
374 | } | 383 | } |
diff --git a/OpenSim/Region/CoreModules/World/Wind/WindModule.cs b/OpenSim/Region/CoreModules/World/Wind/WindModule.cs index 9de588c..35014f5 100644 --- a/OpenSim/Region/CoreModules/World/Wind/WindModule.cs +++ b/OpenSim/Region/CoreModules/World/Wind/WindModule.cs | |||
@@ -216,13 +216,13 @@ namespace OpenSim.Region.CoreModules | |||
216 | // FIXME: If console region is root then this will be printed by every module. Currently, there is no | 216 | // FIXME: If console region is root then this will be printed by every module. Currently, there is no |
217 | // way to prevent this, short of making the entire module shared (which is complete overkill). | 217 | // way to prevent this, short of making the entire module shared (which is complete overkill). |
218 | // One possibility is to return a bool to signal whether the module has completely handled the command | 218 | // One possibility is to return a bool to signal whether the module has completely handled the command |
219 | m_log.InfoFormat("[WIND]: Please change to a specific region in order to set Sun parameters."); | 219 | MainConsole.Instance.Output("Please change to a specific region in order to set Sun parameters."); |
220 | return; | 220 | return; |
221 | } | 221 | } |
222 | 222 | ||
223 | if (m_scene.ConsoleScene() != m_scene) | 223 | if (m_scene.ConsoleScene() != m_scene) |
224 | { | 224 | { |
225 | m_log.InfoFormat("[WIND]: Console Scene is not my scene."); | 225 | MainConsole.Instance.Output("Console Scene is not my scene."); |
226 | return; | 226 | return; |
227 | } | 227 | } |
228 | } | 228 | } |
@@ -233,7 +233,9 @@ namespace OpenSim.Region.CoreModules | |||
233 | private void HandleConsoleCommand(string module, string[] cmdparams) | 233 | private void HandleConsoleCommand(string module, string[] cmdparams) |
234 | { | 234 | { |
235 | ValidateConsole(); | 235 | ValidateConsole(); |
236 | m_log.Info("[WIND] The wind command can be used to change the currently active wind model plugin and update the parameters for wind plugins."); | 236 | |
237 | MainConsole.Instance.Output( | ||
238 | "The wind command can be used to change the currently active wind model plugin and update the parameters for wind plugins."); | ||
237 | } | 239 | } |
238 | 240 | ||
239 | /// <summary> | 241 | /// <summary> |
@@ -246,7 +248,9 @@ namespace OpenSim.Region.CoreModules | |||
246 | if ((cmdparams.Length != 4) | 248 | if ((cmdparams.Length != 4) |
247 | || !cmdparams[1].Equals("base")) | 249 | || !cmdparams[1].Equals("base")) |
248 | { | 250 | { |
249 | m_log.Info("[WIND] Invalid parameters to change parameters for Wind module base, usage: wind base <parameter> <value>"); | 251 | MainConsole.Instance.Output( |
252 | "Invalid parameters to change parameters for Wind module base, usage: wind base <parameter> <value>"); | ||
253 | |||
250 | return; | 254 | return; |
251 | } | 255 | } |
252 | 256 | ||
@@ -261,7 +265,9 @@ namespace OpenSim.Region.CoreModules | |||
261 | } | 265 | } |
262 | else | 266 | else |
263 | { | 267 | { |
264 | m_log.InfoFormat("[WIND] Invalid value {0} specified for {1}", cmdparams[3], cmdparams[2]); | 268 | MainConsole.Instance.OutputFormat( |
269 | "Invalid value {0} specified for {1}", cmdparams[3], cmdparams[2]); | ||
270 | |||
265 | return; | 271 | return; |
266 | } | 272 | } |
267 | 273 | ||
@@ -271,22 +277,23 @@ namespace OpenSim.Region.CoreModules | |||
271 | 277 | ||
272 | if (desiredPlugin.Equals(m_activeWindPlugin.Name)) | 278 | if (desiredPlugin.Equals(m_activeWindPlugin.Name)) |
273 | { | 279 | { |
274 | m_log.InfoFormat("[WIND] Wind model plugin {0} is already active", cmdparams[3]); | 280 | MainConsole.Instance.OutputFormat("Wind model plugin {0} is already active", cmdparams[3]); |
281 | |||
275 | return; | 282 | return; |
276 | } | 283 | } |
277 | 284 | ||
278 | if (m_availableWindPlugins.ContainsKey(desiredPlugin)) | 285 | if (m_availableWindPlugins.ContainsKey(desiredPlugin)) |
279 | { | 286 | { |
280 | m_activeWindPlugin = m_availableWindPlugins[cmdparams[3]]; | 287 | m_activeWindPlugin = m_availableWindPlugins[cmdparams[3]]; |
281 | m_log.InfoFormat("[WIND] {0} wind model plugin now active", m_activeWindPlugin.Name); | 288 | |
289 | MainConsole.Instance.OutputFormat("{0} wind model plugin now active", m_activeWindPlugin.Name); | ||
282 | } | 290 | } |
283 | else | 291 | else |
284 | { | 292 | { |
285 | m_log.InfoFormat("[WIND] Could not find wind model plugin {0}", desiredPlugin); | 293 | MainConsole.Instance.OutputFormat("Could not find wind model plugin {0}", desiredPlugin); |
286 | } | 294 | } |
287 | break; | 295 | break; |
288 | } | 296 | } |
289 | |||
290 | } | 297 | } |
291 | 298 | ||
292 | /// <summary> | 299 | /// <summary> |
@@ -300,7 +307,7 @@ namespace OpenSim.Region.CoreModules | |||
300 | if ((cmdparams.Length != 4) | 307 | if ((cmdparams.Length != 4) |
301 | && (cmdparams.Length != 3)) | 308 | && (cmdparams.Length != 3)) |
302 | { | 309 | { |
303 | m_log.Info("[WIND] Usage: wind <plugin> <param> [value]"); | 310 | MainConsole.Instance.Output("Usage: wind <plugin> <param> [value]"); |
304 | return; | 311 | return; |
305 | } | 312 | } |
306 | 313 | ||
@@ -311,16 +318,17 @@ namespace OpenSim.Region.CoreModules | |||
311 | { | 318 | { |
312 | if (!float.TryParse(cmdparams[3], out value)) | 319 | if (!float.TryParse(cmdparams[3], out value)) |
313 | { | 320 | { |
314 | m_log.InfoFormat("[WIND] Invalid value {0}", cmdparams[3]); | 321 | MainConsole.Instance.OutputFormat("Invalid value {0}", cmdparams[3]); |
315 | } | 322 | } |
316 | 323 | ||
317 | try | 324 | try |
318 | { | 325 | { |
319 | WindParamSet(plugin, param, value); | 326 | WindParamSet(plugin, param, value); |
327 | MainConsole.Instance.OutputFormat("{0} set to {1}", param, value); | ||
320 | } | 328 | } |
321 | catch (Exception e) | 329 | catch (Exception e) |
322 | { | 330 | { |
323 | m_log.InfoFormat("[WIND] {0}", e.Message); | 331 | MainConsole.Instance.OutputFormat("{0}", e.Message); |
324 | } | 332 | } |
325 | } | 333 | } |
326 | else | 334 | else |
@@ -328,11 +336,11 @@ namespace OpenSim.Region.CoreModules | |||
328 | try | 336 | try |
329 | { | 337 | { |
330 | value = WindParamGet(plugin, param); | 338 | value = WindParamGet(plugin, param); |
331 | m_log.InfoFormat("[WIND] {0} : {1}", param, value); | 339 | MainConsole.Instance.OutputFormat("{0} : {1}", param, value); |
332 | } | 340 | } |
333 | catch (Exception e) | 341 | catch (Exception e) |
334 | { | 342 | { |
335 | m_log.InfoFormat("[WIND] {0}", e.Message); | 343 | MainConsole.Instance.OutputFormat("{0}", e.Message); |
336 | } | 344 | } |
337 | } | 345 | } |
338 | 346 | ||
@@ -366,13 +374,11 @@ namespace OpenSim.Region.CoreModules | |||
366 | { | 374 | { |
367 | IWindModelPlugin windPlugin = m_availableWindPlugins[plugin]; | 375 | IWindModelPlugin windPlugin = m_availableWindPlugins[plugin]; |
368 | windPlugin.WindParamSet(param, value); | 376 | windPlugin.WindParamSet(param, value); |
369 | m_log.InfoFormat("[WIND] {0} set to {1}", param, value); | ||
370 | } | 377 | } |
371 | else | 378 | else |
372 | { | 379 | { |
373 | throw new Exception(String.Format("Could not find plugin {0}", plugin)); | 380 | throw new Exception(String.Format("Could not find plugin {0}", plugin)); |
374 | } | 381 | } |
375 | |||
376 | } | 382 | } |
377 | 383 | ||
378 | public float WindParamGet(string plugin, string param) | 384 | public float WindParamGet(string plugin, string param) |
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index bf18616..5412359 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs | |||
@@ -115,6 +115,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
115 | "export-map [<path>]", | 115 | "export-map [<path>]", |
116 | "Save an image of the world map", HandleExportWorldMapConsoleCommand); | 116 | "Save an image of the world map", HandleExportWorldMapConsoleCommand); |
117 | 117 | ||
118 | m_scene.AddCommand( | ||
119 | "Regions", this, "generate map", | ||
120 | "generate map", | ||
121 | "Generates and stores a new maptile.", HandleGenerateMapConsoleCommand); | ||
122 | |||
118 | AddHandlers(); | 123 | AddHandlers(); |
119 | } | 124 | } |
120 | } | 125 | } |
@@ -162,7 +167,16 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
162 | regionimage = regionimage.Replace("-", ""); | 167 | regionimage = regionimage.Replace("-", ""); |
163 | m_log.Info("[WORLD MAP]: JPEG Map location: " + m_scene.RegionInfo.ServerURI + "index.php?method=" + regionimage); | 168 | m_log.Info("[WORLD MAP]: JPEG Map location: " + m_scene.RegionInfo.ServerURI + "index.php?method=" + regionimage); |
164 | 169 | ||
165 | MainServer.Instance.AddHTTPHandler(regionimage, OnHTTPGetMapImage); | 170 | MainServer.Instance.AddHTTPHandler(regionimage, |
171 | new GenericHTTPDOSProtector(OnHTTPGetMapImage, OnHTTPThrottled, new BasicDosProtectorOptions() | ||
172 | { | ||
173 | AllowXForwardedFor = false, | ||
174 | ForgetTimeSpan = TimeSpan.FromMinutes(2), | ||
175 | MaxRequestsInTimeframe = 4, | ||
176 | ReportingName = "MAPDOSPROTECTOR", | ||
177 | RequestTimeSpan = TimeSpan.FromSeconds(10), | ||
178 | ThrottledAction = BasicDOSProtector.ThrottleAction.DoThrottledMethod | ||
179 | }).Process); | ||
166 | MainServer.Instance.AddLLSDHandler( | 180 | MainServer.Instance.AddLLSDHandler( |
167 | "/MAP/MapItems/" + m_scene.RegionInfo.RegionHandle.ToString(), HandleRemoteMapItemRequest); | 181 | "/MAP/MapItems/" + m_scene.RegionInfo.RegionHandle.ToString(), HandleRemoteMapItemRequest); |
168 | 182 | ||
@@ -1131,6 +1145,16 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
1131 | block.Y = (ushort)(r.RegionLocY / Constants.RegionSize); | 1145 | block.Y = (ushort)(r.RegionLocY / Constants.RegionSize); |
1132 | } | 1146 | } |
1133 | 1147 | ||
1148 | public Hashtable OnHTTPThrottled(Hashtable keysvals) | ||
1149 | { | ||
1150 | Hashtable reply = new Hashtable(); | ||
1151 | int statuscode = 500; | ||
1152 | reply["str_response_string"] = ""; | ||
1153 | reply["int_response_code"] = statuscode; | ||
1154 | reply["content_type"] = "text/plain"; | ||
1155 | return reply; | ||
1156 | } | ||
1157 | |||
1134 | public Hashtable OnHTTPGetMapImage(Hashtable keysvals) | 1158 | public Hashtable OnHTTPGetMapImage(Hashtable keysvals) |
1135 | { | 1159 | { |
1136 | m_log.Debug("[WORLD MAP]: Sending map image jpeg"); | 1160 | m_log.Debug("[WORLD MAP]: Sending map image jpeg"); |
@@ -1305,6 +1329,16 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
1305 | m_scene.RegionInfo.RegionName, exportPath); | 1329 | m_scene.RegionInfo.RegionName, exportPath); |
1306 | } | 1330 | } |
1307 | 1331 | ||
1332 | public void HandleGenerateMapConsoleCommand(string module, string[] cmdparams) | ||
1333 | { | ||
1334 | Scene consoleScene = m_scene.ConsoleScene(); | ||
1335 | |||
1336 | if (consoleScene != null && consoleScene != m_scene) | ||
1337 | return; | ||
1338 | |||
1339 | GenerateMaptile(); | ||
1340 | } | ||
1341 | |||
1308 | public OSD HandleRemoteMapItemRequest(string path, OSD request, string endpoint) | 1342 | public OSD HandleRemoteMapItemRequest(string path, OSD request, string endpoint) |
1309 | { | 1343 | { |
1310 | uint xstart = 0; | 1344 | uint xstart = 0; |
@@ -1542,88 +1576,69 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
1542 | 1576 | ||
1543 | private Byte[] GenerateOverlay() | 1577 | private Byte[] GenerateOverlay() |
1544 | { | 1578 | { |
1545 | Bitmap overlay = new Bitmap(256, 256); | 1579 | using (Bitmap overlay = new Bitmap(256, 256)) |
1546 | |||
1547 | bool[,] saleBitmap = new bool[64, 64]; | ||
1548 | for (int x = 0 ; x < 64 ; x++) | ||
1549 | { | 1580 | { |
1550 | for (int y = 0 ; y < 64 ; y++) | 1581 | bool[,] saleBitmap = new bool[64, 64]; |
1551 | saleBitmap[x, y] = false; | 1582 | for (int x = 0 ; x < 64 ; x++) |
1552 | } | 1583 | { |
1553 | 1584 | for (int y = 0 ; y < 64 ; y++) | |
1554 | bool landForSale = false; | 1585 | saleBitmap[x, y] = false; |
1586 | } | ||
1555 | 1587 | ||
1556 | List<ILandObject> parcels = m_scene.LandChannel.AllParcels(); | 1588 | bool landForSale = false; |
1557 | 1589 | ||
1558 | Color background = Color.FromArgb(0, 0, 0, 0); | 1590 | List<ILandObject> parcels = m_scene.LandChannel.AllParcels(); |
1559 | SolidBrush transparent = new SolidBrush(background); | ||
1560 | Graphics g = Graphics.FromImage(overlay); | ||
1561 | g.FillRectangle(transparent, 0, 0, 255, 255); | ||
1562 | 1591 | ||
1563 | SolidBrush yellow = new SolidBrush(Color.FromArgb(255, 249, 223, 9)); | 1592 | Color background = Color.FromArgb(0, 0, 0, 0); |
1564 | Pen grey = new Pen(Color.FromArgb(255, 92, 92, 92)); | ||
1565 | 1593 | ||
1566 | foreach (ILandObject land in parcels) | 1594 | using (Graphics g = Graphics.FromImage(overlay)) |
1567 | { | ||
1568 | // m_log.DebugFormat("[WORLD MAP]: Parcel {0} flags {1}", land.LandData.Name, land.LandData.Flags); | ||
1569 | if ((land.LandData.Flags & (uint)ParcelFlags.ForSale) != 0) | ||
1570 | { | 1595 | { |
1571 | landForSale = true; | 1596 | using (SolidBrush transparent = new SolidBrush(background)) |
1572 | 1597 | g.FillRectangle(transparent, 0, 0, 256, 256); | |
1573 | bool[,] landBitmap = land.GetLandBitmap(); | ||
1574 | 1598 | ||
1575 | for (int x = 0 ; x < 64 ; x++) | 1599 | |
1600 | foreach (ILandObject land in parcels) | ||
1576 | { | 1601 | { |
1577 | for (int y = 0 ; y < 64 ; y++) | 1602 | // m_log.DebugFormat("[WORLD MAP]: Parcel {0} flags {1}", land.LandData.Name, land.LandData.Flags); |
1603 | if ((land.LandData.Flags & (uint)ParcelFlags.ForSale) != 0) | ||
1578 | { | 1604 | { |
1579 | if (landBitmap[x, y]) | 1605 | landForSale = true; |
1606 | |||
1607 | saleBitmap = land.MergeLandBitmaps(saleBitmap, land.GetLandBitmap()); | ||
1608 | } | ||
1609 | } | ||
1610 | |||
1611 | if (!landForSale) | ||
1612 | { | ||
1613 | m_log.DebugFormat("[WORLD MAP]: Region {0} has no parcels for sale, not generating overlay", m_scene.RegionInfo.RegionName); | ||
1614 | return null; | ||
1615 | } | ||
1616 | |||
1617 | m_log.DebugFormat("[WORLD MAP]: Region {0} has parcels for sale, generating overlay", m_scene.RegionInfo.RegionName); | ||
1618 | |||
1619 | using (SolidBrush yellow = new SolidBrush(Color.FromArgb(255, 249, 223, 9))) | ||
1620 | { | ||
1621 | for (int x = 0 ; x < 64 ; x++) | ||
1622 | { | ||
1623 | for (int y = 0 ; y < 64 ; y++) | ||
1580 | { | 1624 | { |
1581 | g.FillRectangle(yellow, x * 4, 252 - (y * 4), 4, 4); | 1625 | if (saleBitmap[x, y]) |
1582 | 1626 | g.FillRectangle(yellow, x * 4, 252 - (y * 4), 4, 4); | |
1583 | if (x > 0) | ||
1584 | { | ||
1585 | if ((saleBitmap[x - 1, y] || landBitmap[x - 1, y]) == false) | ||
1586 | g.DrawLine(grey, x * 4, 252 - (y * 4), x * 4, 255 - (y * 4)); | ||
1587 | } | ||
1588 | if (y > 0) | ||
1589 | { | ||
1590 | if ((saleBitmap[x, y-1] || landBitmap[x, y-1]) == false) | ||
1591 | g.DrawLine(grey, x * 4, 255 - (y * 4), x * 4 + 3, 255 - (y * 4)); | ||
1592 | } | ||
1593 | if (x < 63) | ||
1594 | { | ||
1595 | if ((saleBitmap[x + 1, y] || landBitmap[x + 1, y]) == false) | ||
1596 | g.DrawLine(grey, x * 4 + 3, 252 - (y * 4), x * 4 + 3, 255 - (y * 4)); | ||
1597 | } | ||
1598 | if (y < 63) | ||
1599 | { | ||
1600 | if ((saleBitmap[x, y + 1] || landBitmap[x, y + 1]) == false) | ||
1601 | g.DrawLine(grey, x * 4, 252 - (y * 4), x * 4 + 3, 252 - (y * 4)); | ||
1602 | } | ||
1603 | } | 1627 | } |
1604 | } | 1628 | } |
1605 | } | 1629 | } |
1606 | |||
1607 | saleBitmap = land.MergeLandBitmaps(saleBitmap, landBitmap); | ||
1608 | } | 1630 | } |
1609 | } | ||
1610 | 1631 | ||
1611 | if (!landForSale) | 1632 | try |
1612 | { | 1633 | { |
1613 | m_log.DebugFormat("[WORLD MAP]: Region {0} has no parcels for sale, not generating overlay", m_scene.RegionInfo.RegionName); | 1634 | return OpenJPEG.EncodeFromImage(overlay, true); |
1614 | return null; | 1635 | } |
1636 | catch (Exception e) | ||
1637 | { | ||
1638 | m_log.DebugFormat("[WORLD MAP]: Error creating parcel overlay: " + e.ToString()); | ||
1639 | } | ||
1615 | } | 1640 | } |
1616 | 1641 | ||
1617 | m_log.DebugFormat("[WORLD MAP]: Region {0} has parcels for sale, generating overlay", m_scene.RegionInfo.RegionName); | ||
1618 | |||
1619 | try | ||
1620 | { | ||
1621 | return OpenJPEG.EncodeFromImage(overlay, true); | ||
1622 | } | ||
1623 | catch (Exception e) | ||
1624 | { | ||
1625 | m_log.DebugFormat("[WORLD MAP]: Error creating parcel overlay: " + e.ToString()); | ||
1626 | } | ||
1627 | return null; | 1642 | return null; |
1628 | } | 1643 | } |
1629 | } | 1644 | } |