diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/World')
9 files changed, 895 insertions, 43 deletions
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs index 587d260..a6dbaba 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs | |||
@@ -116,6 +116,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
116 | m_merge = merge; | 116 | m_merge = merge; |
117 | m_skipAssets = skipAssets; | 117 | m_skipAssets = skipAssets; |
118 | m_requestId = requestId; | 118 | m_requestId = requestId; |
119 | |||
120 | // Zero can never be a valid user id | ||
121 | m_validUserUuids[UUID.Zero] = false; | ||
119 | } | 122 | } |
120 | 123 | ||
121 | public ArchiveReadRequest(Scene scene, Stream loadStream, bool merge, bool skipAssets, Guid requestId) | 124 | public ArchiveReadRequest(Scene scene, Stream loadStream, bool merge, bool skipAssets, Guid requestId) |
@@ -125,6 +128,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
125 | m_merge = merge; | 128 | m_merge = merge; |
126 | m_skipAssets = skipAssets; | 129 | m_skipAssets = skipAssets; |
127 | m_requestId = requestId; | 130 | m_requestId = requestId; |
131 | |||
132 | // Zero can never be a valid user id | ||
133 | m_validUserUuids[UUID.Zero] = false; | ||
128 | } | 134 | } |
129 | 135 | ||
130 | /// <summary> | 136 | /// <summary> |
@@ -368,16 +374,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
368 | if (!m_validUserUuids.ContainsKey(uuid)) | 374 | if (!m_validUserUuids.ContainsKey(uuid)) |
369 | { | 375 | { |
370 | UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, uuid); | 376 | UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, uuid); |
371 | if (account != null) | 377 | m_validUserUuids.Add(uuid, account != null); |
372 | m_validUserUuids.Add(uuid, true); | ||
373 | else | ||
374 | m_validUserUuids.Add(uuid, false); | ||
375 | } | 378 | } |
376 | 379 | ||
377 | if (m_validUserUuids[uuid]) | 380 | return m_validUserUuids[uuid]; |
378 | return true; | ||
379 | else | ||
380 | return false; | ||
381 | } | 381 | } |
382 | 382 | ||
383 | /// <summary> | 383 | /// <summary> |
@@ -404,6 +404,12 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
404 | string extension = filename.Substring(i); | 404 | string extension = filename.Substring(i); |
405 | string uuid = filename.Remove(filename.Length - extension.Length); | 405 | string uuid = filename.Remove(filename.Length - extension.Length); |
406 | 406 | ||
407 | if (m_scene.AssetService.GetMetadata(uuid) != null) | ||
408 | { | ||
409 | // m_log.DebugFormat("[ARCHIVER]: found existing asset {0}",uuid); | ||
410 | return true; | ||
411 | } | ||
412 | |||
407 | if (ArchiveConstants.EXTENSION_TO_ASSET_TYPE.ContainsKey(extension)) | 413 | if (ArchiveConstants.EXTENSION_TO_ASSET_TYPE.ContainsKey(extension)) |
408 | { | 414 | { |
409 | sbyte assetType = ArchiveConstants.EXTENSION_TO_ASSET_TYPE[extension]; | 415 | sbyte assetType = ArchiveConstants.EXTENSION_TO_ASSET_TYPE[extension]; |
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs index b895afe..ffcf063 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs | |||
@@ -282,10 +282,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
282 | // always (incorrectly) includes the Copy bit set in this case. But that's a mistake: the viewer | 282 | // always (incorrectly) includes the Copy bit set in this case. But that's a mistake: the viewer |
283 | // does NOT show that the object has Everyone-Copy permissions, and doesn't allow it to be copied. | 283 | // does NOT show that the object has Everyone-Copy permissions, and doesn't allow it to be copied. |
284 | if (permissionClass != PermissionClass.Owner) | 284 | if (permissionClass != PermissionClass.Owner) |
285 | { | ||
286 | canTransfer |= (obj.EveryoneMask & (uint)PermissionMask.Copy) != 0; | 285 | canTransfer |= (obj.EveryoneMask & (uint)PermissionMask.Copy) != 0; |
287 | } | ||
288 | |||
289 | 286 | ||
290 | bool partPermitted = true; | 287 | bool partPermitted = true; |
291 | if (checkPermissions.Contains("C") && !canCopy) | 288 | if (checkPermissions.Contains("C") && !canCopy) |
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs index f44a3ba..f5a5a8d 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs | |||
@@ -98,6 +98,16 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
98 | 98 | ||
99 | OptionSet options = new OptionSet().Add("m|merge", delegate (string v) { mergeOar = v != null; }); | 99 | OptionSet options = new OptionSet().Add("m|merge", delegate (string v) { mergeOar = v != null; }); |
100 | options.Add("s|skip-assets", delegate (string v) { skipAssets = v != null; }); | 100 | options.Add("s|skip-assets", delegate (string v) { skipAssets = v != null; }); |
101 | |||
102 | // Send a message to the region ready module | ||
103 | /* bluewall* Disable this for the time being | ||
104 | IRegionReadyModule rready = m_scene.RequestModuleInterface<IRegionReadyModule>(); | ||
105 | |||
106 | if (rready != null) | ||
107 | { | ||
108 | rready.OarLoadingAlert("load"); | ||
109 | } | ||
110 | */ | ||
101 | 111 | ||
102 | List<string> mainParams = options.Parse(cmdparams); | 112 | List<string> mainParams = options.Parse(cmdparams); |
103 | 113 | ||
@@ -125,9 +135,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
125 | Dictionary<string, object> options = new Dictionary<string, object>(); | 135 | Dictionary<string, object> options = new Dictionary<string, object>(); |
126 | 136 | ||
127 | OptionSet ops = new OptionSet(); | 137 | OptionSet ops = new OptionSet(); |
128 | // ops.Add("v|version=", delegate(string v) { options["version"] = v; }); | 138 | |
129 | ops.Add("p|profile=", delegate(string v) { options["profile"] = v; }); | 139 | // legacy argument [obsolete] |
140 | ops.Add("p|profile=", delegate(string v) { Console.WriteLine("\n WARNING: -profile option is obsolete and it will not work. Use -home instead.\n"); }); | ||
141 | // preferred | ||
142 | ops.Add("h|home=", delegate(string v) { options["home"] = v; }); | ||
143 | |||
130 | ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; }); | 144 | ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; }); |
145 | ops.Add("publish", v => options["wipe-owners"] = v != null); | ||
131 | ops.Add("perm=", delegate(string v) { options["checkPermissions"] = v; }); | 146 | ops.Add("perm=", delegate(string v) { options["checkPermissions"] = v; }); |
132 | 147 | ||
133 | List<string> mainParams = ops.Parse(cmdparams); | 148 | List<string> mainParams = ops.Parse(cmdparams); |
diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs index e798e5e..63f1363 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs | |||
@@ -248,9 +248,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests | |||
248 | Dictionary<string, Object> options = new Dictionary<string, Object>(); | 248 | Dictionary<string, Object> options = new Dictionary<string, Object>(); |
249 | options.Add("noassets", true); | 249 | options.Add("noassets", true); |
250 | m_archiverModule.ArchiveRegion(archiveWriteStream, requestId, options); | 250 | m_archiverModule.ArchiveRegion(archiveWriteStream, requestId, options); |
251 | //AssetServerBase assetServer = (AssetServerBase)scene.CommsManager.AssetCache.AssetServer; | ||
252 | //while (assetServer.HasWaitingRequests()) | ||
253 | // assetServer.ProcessNextRequest(); | ||
254 | 251 | ||
255 | // Don't wait for completion - with --noassets save oar happens synchronously | 252 | // Don't wait for completion - with --noassets save oar happens synchronously |
256 | // Monitor.Wait(this, 60000); | 253 | // Monitor.Wait(this, 60000); |
@@ -344,7 +341,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests | |||
344 | { | 341 | { |
345 | using (BinaryReader br = new BinaryReader(resource)) | 342 | using (BinaryReader br = new BinaryReader(resource)) |
346 | { | 343 | { |
347 | // FIXME: Use the inspector insteadthere are so many forums and lists already, though admittedly none of them are suitable for cross virtual-enivornemnt discussion | 344 | // FIXME: Use the inspector instead |
348 | soundData = br.ReadBytes(99999999); | 345 | soundData = br.ReadBytes(99999999); |
349 | UUID soundUuid = UUID.Parse("00000000-0000-0000-0000-000000000001"); | 346 | UUID soundUuid = UUID.Parse("00000000-0000-0000-0000-000000000001"); |
350 | string soundAssetFileName | 347 | string soundAssetFileName |
@@ -410,6 +407,86 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests | |||
410 | } | 407 | } |
411 | 408 | ||
412 | /// <summary> | 409 | /// <summary> |
410 | /// Test loading an OpenSim Region Archive saved with the --publish option. | ||
411 | /// </summary> | ||
412 | [Test] | ||
413 | public void TestLoadPublishedOar() | ||
414 | { | ||
415 | TestHelpers.InMethod(); | ||
416 | // log4net.Config.XmlConfigurator.Configure(); | ||
417 | |||
418 | SceneObjectPart part1 = CreateSceneObjectPart1(); | ||
419 | SceneObjectGroup sog1 = new SceneObjectGroup(part1); | ||
420 | m_scene.AddNewSceneObject(sog1, false); | ||
421 | |||
422 | SceneObjectPart part2 = CreateSceneObjectPart2(); | ||
423 | |||
424 | AssetNotecard nc = new AssetNotecard(); | ||
425 | nc.BodyText = "Hello World!"; | ||
426 | nc.Encode(); | ||
427 | UUID ncAssetUuid = new UUID("00000000-0000-0000-1000-000000000000"); | ||
428 | UUID ncItemUuid = new UUID("00000000-0000-0000-1100-000000000000"); | ||
429 | AssetBase ncAsset | ||
430 | = AssetHelpers.CreateAsset(ncAssetUuid, AssetType.Notecard, nc.AssetData, UUID.Zero); | ||
431 | m_scene.AssetService.Store(ncAsset); | ||
432 | SceneObjectGroup sog2 = new SceneObjectGroup(part2); | ||
433 | TaskInventoryItem ncItem | ||
434 | = new TaskInventoryItem { Name = "ncItem", AssetID = ncAssetUuid, ItemID = ncItemUuid }; | ||
435 | part2.Inventory.AddInventoryItem(ncItem, true); | ||
436 | |||
437 | m_scene.AddNewSceneObject(sog2, false); | ||
438 | |||
439 | MemoryStream archiveWriteStream = new MemoryStream(); | ||
440 | m_scene.EventManager.OnOarFileSaved += SaveCompleted; | ||
441 | |||
442 | Guid requestId = new Guid("00000000-0000-0000-0000-808080808080"); | ||
443 | |||
444 | lock (this) | ||
445 | { | ||
446 | m_archiverModule.ArchiveRegion( | ||
447 | archiveWriteStream, requestId, new Dictionary<string, Object>() { { "wipe-owners", Boolean.TrueString } }); | ||
448 | |||
449 | Monitor.Wait(this, 60000); | ||
450 | } | ||
451 | |||
452 | Assert.That(m_lastRequestId, Is.EqualTo(requestId)); | ||
453 | |||
454 | byte[] archive = archiveWriteStream.ToArray(); | ||
455 | MemoryStream archiveReadStream = new MemoryStream(archive); | ||
456 | |||
457 | { | ||
458 | UUID estateOwner = TestHelpers.ParseTail(0x4747); | ||
459 | UUID objectOwner = TestHelpers.ParseTail(0x15); | ||
460 | |||
461 | // Reload to new scene | ||
462 | ArchiverModule archiverModule = new ArchiverModule(); | ||
463 | SerialiserModule serialiserModule = new SerialiserModule(); | ||
464 | TerrainModule terrainModule = new TerrainModule(); | ||
465 | |||
466 | TestScene scene2 = SceneHelpers.SetupScene(); | ||
467 | SceneHelpers.SetupSceneModules(scene2, archiverModule, serialiserModule, terrainModule); | ||
468 | |||
469 | // Make sure there's a valid owner for the owner we saved (this should have been wiped if the code is | ||
470 | // behaving correctly | ||
471 | UserAccountHelpers.CreateUserWithInventory(scene2, objectOwner); | ||
472 | |||
473 | scene2.RegionInfo.EstateSettings.EstateOwner = estateOwner; | ||
474 | |||
475 | lock (this) | ||
476 | { | ||
477 | scene2.EventManager.OnOarFileLoaded += LoadCompleted; | ||
478 | archiverModule.DearchiveRegion(archiveReadStream); | ||
479 | } | ||
480 | |||
481 | Assert.That(m_lastErrorMessage, Is.Null); | ||
482 | |||
483 | SceneObjectGroup loadedSog = scene2.GetSceneObjectGroup(part1.Name); | ||
484 | Assert.That(loadedSog.OwnerID, Is.EqualTo(estateOwner)); | ||
485 | Assert.That(loadedSog.LastOwnerID, Is.EqualTo(estateOwner)); | ||
486 | } | ||
487 | } | ||
488 | |||
489 | /// <summary> | ||
413 | /// Test loading the region settings of an OpenSim Region Archive. | 490 | /// Test loading the region settings of an OpenSim Region Archive. |
414 | /// </summary> | 491 | /// </summary> |
415 | [Test] | 492 | [Test] |
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index 58d9455..2e1487f 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs | |||
@@ -53,6 +53,7 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
53 | protected EstateManagementCommands m_commands; | 53 | protected EstateManagementCommands m_commands; |
54 | 54 | ||
55 | private EstateTerrainXferHandler TerrainUploader; | 55 | private EstateTerrainXferHandler TerrainUploader; |
56 | public TelehubManager m_Telehub; | ||
56 | 57 | ||
57 | public event ChangeDelegate OnRegionInfoChange; | 58 | public event ChangeDelegate OnRegionInfoChange; |
58 | public event ChangeDelegate OnEstateInfoChange; | 59 | public event ChangeDelegate OnEstateInfoChange; |
@@ -599,6 +600,50 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
599 | } | 600 | } |
600 | } | 601 | } |
601 | 602 | ||
603 | public void handleOnEstateManageTelehub (IClientAPI client, UUID invoice, UUID senderID, string cmd, uint param1) | ||
604 | { | ||
605 | uint ObjectLocalID; | ||
606 | SceneObjectPart part; | ||
607 | |||
608 | switch (cmd) | ||
609 | { | ||
610 | case "info ui": | ||
611 | break; | ||
612 | |||
613 | case "connect": | ||
614 | // Add the Telehub | ||
615 | part = Scene.GetSceneObjectPart((uint)param1); | ||
616 | if (part == null) | ||
617 | return; | ||
618 | SceneObjectGroup grp = part.ParentGroup; | ||
619 | |||
620 | m_Telehub.Connect(grp); | ||
621 | break; | ||
622 | |||
623 | case "delete": | ||
624 | // Disconnect Telehub | ||
625 | m_Telehub.Disconnect(); | ||
626 | break; | ||
627 | |||
628 | case "spawnpoint add": | ||
629 | // Add SpawnPoint to the Telehub | ||
630 | part = Scene.GetSceneObjectPart((uint)param1); | ||
631 | if (part == null) | ||
632 | return; | ||
633 | m_Telehub.AddSpawnPoint(part.AbsolutePosition); | ||
634 | break; | ||
635 | |||
636 | case "spawnpoint remove": | ||
637 | // Remove SpawnPoint from Telehub | ||
638 | m_Telehub.RemoveSpawnPoint((int)param1); | ||
639 | break; | ||
640 | |||
641 | default: | ||
642 | break; | ||
643 | } | ||
644 | SendTelehubInfo(client); | ||
645 | } | ||
646 | |||
602 | private void SendSimulatorBlueBoxMessage( | 647 | private void SendSimulatorBlueBoxMessage( |
603 | IClientAPI remote_client, UUID invoice, UUID senderID, UUID sessionID, string senderName, string message) | 648 | IClientAPI remote_client, UUID invoice, UUID senderID, UUID sessionID, string senderName, string message) |
604 | { | 649 | { |
@@ -1055,7 +1100,9 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
1055 | Scene.RegisterModuleInterface<IEstateModule>(this); | 1100 | Scene.RegisterModuleInterface<IEstateModule>(this); |
1056 | Scene.EventManager.OnNewClient += EventManager_OnNewClient; | 1101 | Scene.EventManager.OnNewClient += EventManager_OnNewClient; |
1057 | Scene.EventManager.OnRequestChangeWaterHeight += changeWaterHeight; | 1102 | Scene.EventManager.OnRequestChangeWaterHeight += changeWaterHeight; |
1058 | 1103 | ||
1104 | m_Telehub = new TelehubManager(scene); | ||
1105 | |||
1059 | m_commands = new EstateManagementCommands(this); | 1106 | m_commands = new EstateManagementCommands(this); |
1060 | m_commands.Initialise(); | 1107 | m_commands.Initialise(); |
1061 | } | 1108 | } |
@@ -1109,6 +1156,7 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
1109 | client.OnEstateRestartSimRequest += handleEstateRestartSimRequest; | 1156 | client.OnEstateRestartSimRequest += handleEstateRestartSimRequest; |
1110 | client.OnEstateChangeCovenantRequest += handleChangeEstateCovenantRequest; | 1157 | client.OnEstateChangeCovenantRequest += handleChangeEstateCovenantRequest; |
1111 | client.OnEstateChangeInfo += handleEstateChangeInfo; | 1158 | client.OnEstateChangeInfo += handleEstateChangeInfo; |
1159 | client.OnEstateManageTelehub += handleOnEstateManageTelehub; | ||
1112 | client.OnUpdateEstateAccessDeltaRequest += handleEstateAccessDeltaRequest; | 1160 | client.OnUpdateEstateAccessDeltaRequest += handleEstateAccessDeltaRequest; |
1113 | client.OnSimulatorBlueBoxMessageRequest += SendSimulatorBlueBoxMessage; | 1161 | client.OnSimulatorBlueBoxMessageRequest += SendSimulatorBlueBoxMessage; |
1114 | client.OnEstateBlueBoxMessageRequest += SendEstateBlueBoxMessage; | 1162 | client.OnEstateBlueBoxMessageRequest += SendEstateBlueBoxMessage; |
@@ -1243,5 +1291,39 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
1243 | if (onmessage != null) | 1291 | if (onmessage != null) |
1244 | onmessage(Scene.RegionInfo.RegionID, fromID, fromName, message); | 1292 | onmessage(Scene.RegionInfo.RegionID, fromID, fromName, message); |
1245 | } | 1293 | } |
1294 | |||
1295 | |||
1296 | private void SendTelehubInfo(IClientAPI client) | ||
1297 | { | ||
1298 | RegionSettings settings = | ||
1299 | this.Scene.RegionInfo.RegionSettings; | ||
1300 | |||
1301 | SceneObjectGroup telehub = null; | ||
1302 | if (settings.TelehubObject != UUID.Zero && | ||
1303 | (telehub = Scene.GetSceneObjectGroup(settings.TelehubObject)) != null) | ||
1304 | { | ||
1305 | List<Vector3> spawnPoints = new List<Vector3>(); | ||
1306 | |||
1307 | foreach (SpawnPoint sp in settings.SpawnPoints()) | ||
1308 | { | ||
1309 | spawnPoints.Add(sp.GetLocation(Vector3.Zero, Quaternion.Identity)); | ||
1310 | } | ||
1311 | |||
1312 | client.SendTelehubInfo(settings.TelehubObject, | ||
1313 | telehub.Name, | ||
1314 | telehub.AbsolutePosition, | ||
1315 | telehub.GroupRotation, | ||
1316 | spawnPoints); | ||
1317 | } | ||
1318 | else | ||
1319 | { | ||
1320 | client.SendTelehubInfo(UUID.Zero, | ||
1321 | String.Empty, | ||
1322 | Vector3.Zero, | ||
1323 | Quaternion.Identity, | ||
1324 | new List<Vector3>()); | ||
1325 | } | ||
1326 | } | ||
1246 | } | 1327 | } |
1247 | } | 1328 | } |
1329 | |||
diff --git a/OpenSim/Region/CoreModules/World/Estate/TelehubManager.cs b/OpenSim/Region/CoreModules/World/Estate/TelehubManager.cs new file mode 100644 index 0000000..8bc831f --- /dev/null +++ b/OpenSim/Region/CoreModules/World/Estate/TelehubManager.cs | |||
@@ -0,0 +1,95 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Reflection; | ||
30 | using OpenMetaverse; | ||
31 | using System.Collections.Generic; | ||
32 | using OpenSim.Framework; | ||
33 | using OpenSim.Region.Framework.Scenes; | ||
34 | using log4net; | ||
35 | |||
36 | namespace OpenSim.Region.CoreModules.World.Estate | ||
37 | { | ||
38 | public class TelehubManager | ||
39 | { | ||
40 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
41 | |||
42 | Scene m_Scene; | ||
43 | |||
44 | public TelehubManager(Scene scene) | ||
45 | { | ||
46 | m_Scene = scene; | ||
47 | } | ||
48 | |||
49 | // Connect the Telehub | ||
50 | public void Connect(SceneObjectGroup grp) | ||
51 | { | ||
52 | m_Scene.RegionInfo.RegionSettings.ClearSpawnPoints(); | ||
53 | |||
54 | m_Scene.RegionInfo.RegionSettings.TelehubObject = grp.UUID; | ||
55 | m_Scene.RegionInfo.RegionSettings.Save(); | ||
56 | } | ||
57 | |||
58 | // Disconnect the Telehub: | ||
59 | public void Disconnect() | ||
60 | { | ||
61 | if (m_Scene.RegionInfo.RegionSettings.TelehubObject == UUID.Zero) | ||
62 | return; | ||
63 | |||
64 | m_Scene.RegionInfo.RegionSettings.TelehubObject = UUID.Zero; | ||
65 | m_Scene.RegionInfo.RegionSettings.ClearSpawnPoints(); | ||
66 | m_Scene.RegionInfo.RegionSettings.Save(); | ||
67 | } | ||
68 | |||
69 | // Add a SpawnPoint to the Telehub | ||
70 | public void AddSpawnPoint(Vector3 point) | ||
71 | { | ||
72 | if (m_Scene.RegionInfo.RegionSettings.TelehubObject == UUID.Zero) | ||
73 | return; | ||
74 | |||
75 | SceneObjectGroup grp = m_Scene.GetSceneObjectGroup(m_Scene.RegionInfo.RegionSettings.TelehubObject); | ||
76 | if (grp == null) | ||
77 | return; | ||
78 | |||
79 | SpawnPoint sp = new SpawnPoint(); | ||
80 | sp.SetLocation(grp.AbsolutePosition, grp.GroupRotation, point); | ||
81 | m_Scene.RegionInfo.RegionSettings.AddSpawnPoint(sp); | ||
82 | m_Scene.RegionInfo.RegionSettings.Save(); | ||
83 | } | ||
84 | |||
85 | // Remove a SpawnPoint from the Telehub | ||
86 | public void RemoveSpawnPoint(int spawnpoint) | ||
87 | { | ||
88 | if (m_Scene.RegionInfo.RegionSettings.TelehubObject == UUID.Zero) | ||
89 | return; | ||
90 | |||
91 | m_Scene.RegionInfo.RegionSettings.RemoveSpawnPoint(spawnpoint); | ||
92 | m_Scene.RegionInfo.RegionSettings.Save(); | ||
93 | } | ||
94 | } | ||
95 | } | ||
diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index 0da0de3..79b13c3 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs | |||
@@ -1094,7 +1094,16 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1094 | LandData.MusicURL = url; | 1094 | LandData.MusicURL = url; |
1095 | SendLandUpdateToAvatarsOverMe(); | 1095 | SendLandUpdateToAvatarsOverMe(); |
1096 | } | 1096 | } |
1097 | 1097 | ||
1098 | /// <summary> | ||
1099 | /// Get the music url for this land parcel | ||
1100 | /// </summary> | ||
1101 | /// <returns>The music url.</returns> | ||
1102 | public string GetMusicUrl() | ||
1103 | { | ||
1104 | return LandData.MusicURL; | ||
1105 | } | ||
1106 | |||
1098 | #endregion | 1107 | #endregion |
1099 | } | 1108 | } |
1100 | } | 1109 | } |
diff --git a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs new file mode 100644 index 0000000..e3d04cd --- /dev/null +++ b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs | |||
@@ -0,0 +1,410 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Reflection; | ||
31 | using System.Text; | ||
32 | using log4net; | ||
33 | using Mono.Addins; | ||
34 | using Nini.Config; | ||
35 | using OpenMetaverse; | ||
36 | using OpenSim.Framework; | ||
37 | using OpenSim.Framework.Console; | ||
38 | using OpenSim.Framework.Statistics; | ||
39 | using OpenSim.Region.Framework.Interfaces; | ||
40 | using OpenSim.Region.Framework.Scenes; | ||
41 | |||
42 | namespace OpenSim.Region.CoreModules.World.Objects.Commands | ||
43 | { | ||
44 | /// <summary> | ||
45 | /// A module that holds commands for manipulating objects in the scene. | ||
46 | /// </summary> | ||
47 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ObjectCommandsModule")] | ||
48 | public class ObjectCommandsModule : INonSharedRegionModule | ||
49 | { | ||
50 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
51 | |||
52 | private Scene m_scene; | ||
53 | private ICommandConsole m_console; | ||
54 | |||
55 | public string Name { get { return "Object Commands Module"; } } | ||
56 | |||
57 | public Type ReplaceableInterface { get { return null; } } | ||
58 | |||
59 | public void Initialise(IConfigSource source) | ||
60 | { | ||
61 | // m_log.DebugFormat("[OBJECT COMMANDS MODULE]: INITIALIZED MODULE"); | ||
62 | } | ||
63 | |||
64 | public void PostInitialise() | ||
65 | { | ||
66 | // m_log.DebugFormat("[OBJECT COMMANDS MODULE]: POST INITIALIZED MODULE"); | ||
67 | } | ||
68 | |||
69 | public void Close() | ||
70 | { | ||
71 | // m_log.DebugFormat("[OBJECT COMMANDS MODULE]: CLOSED MODULE"); | ||
72 | } | ||
73 | |||
74 | public void AddRegion(Scene scene) | ||
75 | { | ||
76 | // m_log.DebugFormat("[OBJECT COMMANDS MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName); | ||
77 | |||
78 | m_scene = scene; | ||
79 | m_console = MainConsole.Instance; | ||
80 | |||
81 | m_console.Commands.AddCommand("region", false, "delete object owner", | ||
82 | "delete object owner <UUID>", | ||
83 | "Delete a scene object by owner", HandleDeleteObject); | ||
84 | m_console.Commands.AddCommand("region", false, "delete object creator", | ||
85 | "delete object creator <UUID>", | ||
86 | "Delete a scene object by creator", HandleDeleteObject); | ||
87 | m_console.Commands.AddCommand("region", false, "delete object uuid", | ||
88 | "delete object uuid <UUID>", | ||
89 | "Delete a scene object by uuid", HandleDeleteObject); | ||
90 | m_console.Commands.AddCommand("region", false, "delete object name", | ||
91 | "delete object name <name>", | ||
92 | "Delete a scene object by name", HandleDeleteObject); | ||
93 | m_console.Commands.AddCommand("region", false, "delete object outside", | ||
94 | "delete object outside", | ||
95 | "Delete all scene objects outside region boundaries", HandleDeleteObject); | ||
96 | |||
97 | m_console.Commands.AddCommand( | ||
98 | "region", | ||
99 | false, | ||
100 | "show object uuid", | ||
101 | "show object uuid <UUID>", | ||
102 | "Show details of a scene object with the given UUID", HandleShowObjectByUuid); | ||
103 | |||
104 | m_console.Commands.AddCommand( | ||
105 | "region", | ||
106 | false, | ||
107 | "show object name", | ||
108 | "show object name <name>", | ||
109 | "Show details of scene objects with the given name", HandleShowObjectByName); | ||
110 | |||
111 | m_console.Commands.AddCommand( | ||
112 | "region", | ||
113 | false, | ||
114 | "show part uuid", | ||
115 | "show part uuid <UUID>", | ||
116 | "Show details of a scene object parts with the given UUID", HandleShowPartByUuid); | ||
117 | |||
118 | m_console.Commands.AddCommand( | ||
119 | "region", | ||
120 | false, | ||
121 | "show part name", | ||
122 | "show part name <name>", | ||
123 | "Show details of scene object parts with the given name", HandleShowPartByName); | ||
124 | } | ||
125 | |||
126 | public void RemoveRegion(Scene scene) | ||
127 | { | ||
128 | // m_log.DebugFormat("[OBJECTS COMMANDS MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName); | ||
129 | } | ||
130 | |||
131 | public void RegionLoaded(Scene scene) | ||
132 | { | ||
133 | // m_log.DebugFormat("[OBJECTS COMMANDS MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); | ||
134 | } | ||
135 | |||
136 | private void HandleShowObjectByUuid(string module, string[] cmd) | ||
137 | { | ||
138 | if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) | ||
139 | return; | ||
140 | |||
141 | if (cmd.Length < 4) | ||
142 | { | ||
143 | m_console.OutputFormat("Usage: show object uuid <uuid>"); | ||
144 | return; | ||
145 | } | ||
146 | |||
147 | UUID objectUuid; | ||
148 | if (!UUID.TryParse(cmd[3], out objectUuid)) | ||
149 | { | ||
150 | m_console.OutputFormat("{0} is not a valid uuid", cmd[3]); | ||
151 | return; | ||
152 | } | ||
153 | |||
154 | SceneObjectGroup so = m_scene.GetSceneObjectGroup(objectUuid); | ||
155 | |||
156 | if (so == null) | ||
157 | { | ||
158 | // m_console.OutputFormat("No part found with uuid {0}", objectUuid); | ||
159 | return; | ||
160 | } | ||
161 | |||
162 | StringBuilder sb = new StringBuilder(); | ||
163 | AddSceneObjectReport(sb, so); | ||
164 | |||
165 | m_console.OutputFormat(sb.ToString()); | ||
166 | } | ||
167 | |||
168 | private void HandleShowObjectByName(string module, string[] cmd) | ||
169 | { | ||
170 | if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) | ||
171 | return; | ||
172 | |||
173 | if (cmd.Length < 4) | ||
174 | { | ||
175 | m_console.OutputFormat("Usage: show object name <name>"); | ||
176 | return; | ||
177 | } | ||
178 | |||
179 | string name = cmd[3]; | ||
180 | |||
181 | List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>(); | ||
182 | |||
183 | m_scene.ForEachSOG(so => { if (so.Name == name) { sceneObjects.Add(so); }}); | ||
184 | |||
185 | if (sceneObjects.Count == 0) | ||
186 | { | ||
187 | m_console.OutputFormat("No objects with name {0} found in {1}", name, m_scene.RegionInfo.RegionName); | ||
188 | return; | ||
189 | } | ||
190 | |||
191 | StringBuilder sb = new StringBuilder(); | ||
192 | |||
193 | foreach (SceneObjectGroup so in sceneObjects) | ||
194 | { | ||
195 | AddSceneObjectReport(sb, so); | ||
196 | sb.Append("\n"); | ||
197 | } | ||
198 | |||
199 | m_console.OutputFormat(sb.ToString()); | ||
200 | } | ||
201 | |||
202 | private void HandleShowPartByUuid(string module, string[] cmd) | ||
203 | { | ||
204 | if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) | ||
205 | return; | ||
206 | |||
207 | if (cmd.Length < 4) | ||
208 | { | ||
209 | m_console.OutputFormat("Usage: show part uuid <uuid>"); | ||
210 | return; | ||
211 | } | ||
212 | |||
213 | UUID objectUuid; | ||
214 | if (!UUID.TryParse(cmd[3], out objectUuid)) | ||
215 | { | ||
216 | m_console.OutputFormat("{0} is not a valid uuid", cmd[3]); | ||
217 | return; | ||
218 | } | ||
219 | |||
220 | SceneObjectPart sop = m_scene.GetSceneObjectPart(objectUuid); | ||
221 | |||
222 | if (sop == null) | ||
223 | { | ||
224 | // m_console.OutputFormat("No part found with uuid {0}", objectUuid); | ||
225 | return; | ||
226 | } | ||
227 | |||
228 | StringBuilder sb = new StringBuilder(); | ||
229 | AddScenePartReport(sb, sop); | ||
230 | |||
231 | m_console.OutputFormat(sb.ToString()); | ||
232 | } | ||
233 | |||
234 | private void HandleShowPartByName(string module, string[] cmd) | ||
235 | { | ||
236 | if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) | ||
237 | return; | ||
238 | |||
239 | if (cmd.Length < 4) | ||
240 | { | ||
241 | m_console.OutputFormat("Usage: show part name <name>"); | ||
242 | return; | ||
243 | } | ||
244 | |||
245 | string name = cmd[3]; | ||
246 | |||
247 | List<SceneObjectPart> parts = new List<SceneObjectPart>(); | ||
248 | |||
249 | m_scene.ForEachSOG(so => so.ForEachPart(sop => { if (sop.Name == name) { parts.Add(sop); } })); | ||
250 | |||
251 | if (parts.Count == 0) | ||
252 | { | ||
253 | m_console.OutputFormat("No parts with name {0} found in {1}", name, m_scene.RegionInfo.RegionName); | ||
254 | return; | ||
255 | } | ||
256 | |||
257 | StringBuilder sb = new StringBuilder(); | ||
258 | |||
259 | foreach (SceneObjectPart part in parts) | ||
260 | { | ||
261 | AddScenePartReport(sb, part); | ||
262 | sb.Append("\n"); | ||
263 | } | ||
264 | |||
265 | m_console.OutputFormat(sb.ToString()); | ||
266 | } | ||
267 | |||
268 | private StringBuilder AddSceneObjectReport(StringBuilder sb, SceneObjectGroup so) | ||
269 | { | ||
270 | sb.AppendFormat("Name: {0}\n", so.Name); | ||
271 | sb.AppendFormat("Description: {0}\n", so.Description); | ||
272 | sb.AppendFormat("Location: {0} @ {1}\n", so.AbsolutePosition, so.Scene.RegionInfo.RegionName); | ||
273 | sb.AppendFormat("Parts: {0}\n", so.PrimCount); | ||
274 | |||
275 | return sb; | ||
276 | } | ||
277 | |||
278 | private StringBuilder AddScenePartReport(StringBuilder sb, SceneObjectPart sop) | ||
279 | { | ||
280 | sb.AppendFormat("Name: {0}\n", sop.Name); | ||
281 | sb.AppendFormat("Description: {0}\n", sop.Description); | ||
282 | sb.AppendFormat("Location: {0} @ {1}\n", sop.AbsolutePosition, sop.ParentGroup.Scene.RegionInfo.RegionName); | ||
283 | sb.AppendFormat("Parent: {0}", | ||
284 | sop.IsRoot ? "Is Root\n" : string.Format("{0} {1}\n", sop.ParentGroup.Name, sop.ParentGroup.UUID)); | ||
285 | sb.AppendFormat("Parts: {0}\n", !sop.IsRoot ? "1" : sop.ParentGroup.PrimCount.ToString());; | ||
286 | |||
287 | return sb; | ||
288 | } | ||
289 | |||
290 | private void HandleDeleteObject(string module, string[] cmd) | ||
291 | { | ||
292 | if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) | ||
293 | return; | ||
294 | |||
295 | if (cmd.Length < 3) | ||
296 | return; | ||
297 | |||
298 | string mode = cmd[2]; | ||
299 | string o = ""; | ||
300 | |||
301 | if (mode != "outside") | ||
302 | { | ||
303 | if (cmd.Length < 4) | ||
304 | return; | ||
305 | |||
306 | o = cmd[3]; | ||
307 | } | ||
308 | |||
309 | List<SceneObjectGroup> deletes = new List<SceneObjectGroup>(); | ||
310 | |||
311 | UUID match; | ||
312 | |||
313 | switch (mode) | ||
314 | { | ||
315 | case "owner": | ||
316 | if (!UUID.TryParse(o, out match)) | ||
317 | return; | ||
318 | |||
319 | m_scene.ForEachSOG(delegate (SceneObjectGroup g) | ||
320 | { | ||
321 | if (g.OwnerID == match && !g.IsAttachment) | ||
322 | deletes.Add(g); | ||
323 | }); | ||
324 | |||
325 | // if (deletes.Count == 0) | ||
326 | // m_console.OutputFormat("No objects were found with owner {0}", match); | ||
327 | |||
328 | break; | ||
329 | |||
330 | case "creator": | ||
331 | if (!UUID.TryParse(o, out match)) | ||
332 | return; | ||
333 | |||
334 | m_scene.ForEachSOG(delegate (SceneObjectGroup g) | ||
335 | { | ||
336 | if (g.RootPart.CreatorID == match && !g.IsAttachment) | ||
337 | deletes.Add(g); | ||
338 | }); | ||
339 | |||
340 | // if (deletes.Count == 0) | ||
341 | // m_console.OutputFormat("No objects were found with creator {0}", match); | ||
342 | |||
343 | break; | ||
344 | |||
345 | case "uuid": | ||
346 | if (!UUID.TryParse(o, out match)) | ||
347 | return; | ||
348 | |||
349 | m_scene.ForEachSOG(delegate (SceneObjectGroup g) | ||
350 | { | ||
351 | if (g.UUID == match && !g.IsAttachment) | ||
352 | deletes.Add(g); | ||
353 | }); | ||
354 | |||
355 | // if (deletes.Count == 0) | ||
356 | // m_console.OutputFormat("No objects were found with uuid {0}", match); | ||
357 | |||
358 | break; | ||
359 | |||
360 | case "name": | ||
361 | m_scene.ForEachSOG(delegate (SceneObjectGroup g) | ||
362 | { | ||
363 | if (g.RootPart.Name == o && !g.IsAttachment) | ||
364 | deletes.Add(g); | ||
365 | }); | ||
366 | |||
367 | // if (deletes.Count == 0) | ||
368 | // m_console.OutputFormat("No objects were found with name {0}", o); | ||
369 | |||
370 | break; | ||
371 | |||
372 | case "outside": | ||
373 | m_scene.ForEachSOG(delegate (SceneObjectGroup g) | ||
374 | { | ||
375 | SceneObjectPart rootPart = g.RootPart; | ||
376 | bool delete = false; | ||
377 | |||
378 | if (rootPart.GroupPosition.Z < 0.0 || rootPart.GroupPosition.Z > 10000.0) | ||
379 | { | ||
380 | delete = true; | ||
381 | } | ||
382 | else | ||
383 | { | ||
384 | ILandObject parcel | ||
385 | = m_scene.LandChannel.GetLandObject(rootPart.GroupPosition.X, rootPart.GroupPosition.Y); | ||
386 | |||
387 | if (parcel == null || parcel.LandData.Name == "NO LAND") | ||
388 | delete = true; | ||
389 | } | ||
390 | |||
391 | if (delete && !g.IsAttachment && !deletes.Contains(g)) | ||
392 | deletes.Add(g); | ||
393 | }); | ||
394 | |||
395 | // if (deletes.Count == 0) | ||
396 | // m_console.OutputFormat("No objects were found outside region bounds"); | ||
397 | |||
398 | break; | ||
399 | } | ||
400 | |||
401 | m_console.OutputFormat("Deleting {0} objects in {1}", deletes.Count, m_scene.RegionInfo.RegionName); | ||
402 | |||
403 | foreach (SceneObjectGroup g in deletes) | ||
404 | { | ||
405 | m_console.OutputFormat("Deleting object {0} {1}", g.UUID, g.Name); | ||
406 | m_scene.DeleteSceneObject(g, false); | ||
407 | } | ||
408 | } | ||
409 | } | ||
410 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index 9b0e2ff..6c6aa37 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs | |||
@@ -213,7 +213,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
213 | UUID agentID, Caps caps) | 213 | UUID agentID, Caps caps) |
214 | { | 214 | { |
215 | //try | 215 | //try |
216 | //{ | 216 | // |
217 | //m_log.DebugFormat("[MAPLAYER]: path: {0}, param: {1}, agent:{2}", | 217 | //m_log.DebugFormat("[MAPLAYER]: path: {0}, param: {1}, agent:{2}", |
218 | // path, param, agentID.ToString()); | 218 | // path, param, agentID.ToString()); |
219 | 219 | ||
@@ -263,7 +263,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
263 | foreach (GridRegion r in regions) | 263 | foreach (GridRegion r in regions) |
264 | { | 264 | { |
265 | MapBlockData block = new MapBlockData(); | 265 | MapBlockData block = new MapBlockData(); |
266 | MapBlockFromGridRegion(block, r); | 266 | MapBlockFromGridRegion(block, r, 0); |
267 | mapBlocks.Add(block); | 267 | mapBlocks.Add(block); |
268 | } | 268 | } |
269 | avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); | 269 | avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0); |
@@ -373,7 +373,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
373 | public virtual void HandleMapItemRequest(IClientAPI remoteClient, uint flags, | 373 | public virtual void HandleMapItemRequest(IClientAPI remoteClient, uint flags, |
374 | uint EstateID, bool godlike, uint itemtype, ulong regionhandle) | 374 | uint EstateID, bool godlike, uint itemtype, ulong regionhandle) |
375 | { | 375 | { |
376 | // m_log.DebugFormat("[WORLD MAP]: Handle MapItem request {0} {1}", regionhandle, itemtype); | 376 | m_log.DebugFormat("[WORLD MAP]: Handle MapItem request {0} {1}", regionhandle, itemtype); |
377 | 377 | ||
378 | lock (m_rootAgents) | 378 | lock (m_rootAgents) |
379 | { | 379 | { |
@@ -429,7 +429,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
429 | // ensures that the blockingqueue doesn't get borked if the GetAgents() timing changes. | 429 | // ensures that the blockingqueue doesn't get borked if the GetAgents() timing changes. |
430 | RequestMapItems("",remoteClient.AgentId,flags,EstateID,godlike,itemtype,regionhandle); | 430 | RequestMapItems("",remoteClient.AgentId,flags,EstateID,godlike,itemtype,regionhandle); |
431 | } | 431 | } |
432 | } else if (itemtype == 7) // Service 7 (MAP_ITEM_LAND_FOR_SALE) | 432 | } |
433 | else if (itemtype == 7) // Service 7 (MAP_ITEM_LAND_FOR_SALE) | ||
433 | { | 434 | { |
434 | if (regionhandle == 0 || regionhandle == m_scene.RegionInfo.RegionHandle) | 435 | if (regionhandle == 0 || regionhandle == m_scene.RegionInfo.RegionHandle) |
435 | { | 436 | { |
@@ -463,7 +464,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
463 | mapitem.x = (uint)(xstart + x); | 464 | mapitem.x = (uint)(xstart + x); |
464 | mapitem.y = (uint)(ystart + y); | 465 | mapitem.y = (uint)(ystart + y); |
465 | // mapitem.z = (uint)m_scene.GetGroundHeight(x,y); | 466 | // mapitem.z = (uint)m_scene.GetGroundHeight(x,y); |
466 | mapitem.id = UUID.Zero; | 467 | mapitem.id = parcel.GlobalID; |
467 | mapitem.name = parcel.Name; | 468 | mapitem.name = parcel.Name; |
468 | mapitem.Extra = parcel.Area; | 469 | mapitem.Extra = parcel.Area; |
469 | mapitem.Extra2 = parcel.SalePrice; | 470 | mapitem.Extra2 = parcel.SalePrice; |
@@ -481,6 +482,34 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
481 | RequestMapItems("",remoteClient.AgentId,flags,EstateID,godlike,itemtype,regionhandle); | 482 | RequestMapItems("",remoteClient.AgentId,flags,EstateID,godlike,itemtype,regionhandle); |
482 | } | 483 | } |
483 | } | 484 | } |
485 | else if (itemtype == 1) // Service 1 (MAP_ITEM_TELEHUB) | ||
486 | { | ||
487 | if (regionhandle == 0 || regionhandle == m_scene.RegionInfo.RegionHandle) | ||
488 | { | ||
489 | List<mapItemReply> mapitems = new List<mapItemReply>(); | ||
490 | mapItemReply mapitem = new mapItemReply(); | ||
491 | |||
492 | SceneObjectGroup sog = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject); | ||
493 | if (sog != null) | ||
494 | { | ||
495 | mapitem = new mapItemReply(); | ||
496 | mapitem.x = (uint)(xstart + sog.AbsolutePosition.X); | ||
497 | mapitem.y = (uint)(ystart + sog.AbsolutePosition.Y); | ||
498 | mapitem.id = UUID.Zero; | ||
499 | mapitem.name = sog.Name; | ||
500 | mapitem.Extra = 0; // color (not used) | ||
501 | mapitem.Extra2 = 0; // 0 = telehub / 1 = infohub | ||
502 | mapitems.Add(mapitem); | ||
503 | |||
504 | remoteClient.SendMapItemReply(mapitems.ToArray(), itemtype, flags); | ||
505 | } | ||
506 | } | ||
507 | else | ||
508 | { | ||
509 | // Remote Map Item Request | ||
510 | RequestMapItems("",remoteClient.AgentId,flags,EstateID,godlike,itemtype,regionhandle); | ||
511 | } | ||
512 | } | ||
484 | } | 513 | } |
485 | 514 | ||
486 | private int nAsyncRequests = 0; | 515 | private int nAsyncRequests = 0; |
@@ -620,6 +649,28 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
620 | } | 649 | } |
621 | av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, mrs.flags); | 650 | av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, mrs.flags); |
622 | } | 651 | } |
652 | |||
653 | // Service 1 (MAP_ITEM_TELEHUB) | ||
654 | itemtype = 1; | ||
655 | |||
656 | if (response.ContainsKey(itemtype.ToString())) | ||
657 | { | ||
658 | List<mapItemReply> returnitems = new List<mapItemReply>(); | ||
659 | OSDArray itemarray = (OSDArray)response[itemtype.ToString()]; | ||
660 | for (int i = 0; i < itemarray.Count; i++) | ||
661 | { | ||
662 | OSDMap mapitem = (OSDMap)itemarray[i]; | ||
663 | mapItemReply mi = new mapItemReply(); | ||
664 | mi.x = (uint)mapitem["X"].AsInteger(); | ||
665 | mi.y = (uint)mapitem["Y"].AsInteger(); | ||
666 | mi.id = mapitem["ID"].AsUUID(); | ||
667 | mi.Extra = mapitem["Extra"].AsInteger(); | ||
668 | mi.Extra2 = mapitem["Extra2"].AsInteger(); | ||
669 | mi.name = mapitem["Name"].AsString(); | ||
670 | returnitems.Add(mi); | ||
671 | } | ||
672 | av.ControllingClient.SendMapItemReply(returnitems.ToArray(), itemtype, mrs.flags); | ||
673 | } | ||
623 | } | 674 | } |
624 | } | 675 | } |
625 | } | 676 | } |
@@ -904,8 +955,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
904 | { | 955 | { |
905 | List<MapBlockData> response = new List<MapBlockData>(); | 956 | List<MapBlockData> response = new List<MapBlockData>(); |
906 | 957 | ||
907 | // this should return one mapblock at most. | 958 | // this should return one mapblock at most. It is triggered by a click |
908 | // (diva note: why?? in that case we should GetRegionByPosition) | 959 | // on an unloaded square. |
909 | // But make sure: Look whether the one we requested is in there | 960 | // But make sure: Look whether the one we requested is in there |
910 | List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, | 961 | List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, |
911 | minX * (int)Constants.RegionSize, | 962 | minX * (int)Constants.RegionSize, |
@@ -922,7 +973,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
922 | { | 973 | { |
923 | // found it => add it to response | 974 | // found it => add it to response |
924 | MapBlockData block = new MapBlockData(); | 975 | MapBlockData block = new MapBlockData(); |
925 | MapBlockFromGridRegion(block, r); | 976 | MapBlockFromGridRegion(block, r, flag); |
926 | response.Add(block); | 977 | response.Add(block); |
927 | break; | 978 | break; |
928 | } | 979 | } |
@@ -938,10 +989,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
938 | block.Access = 254; // means 'simulator is offline' | 989 | block.Access = 254; // means 'simulator is offline' |
939 | response.Add(block); | 990 | response.Add(block); |
940 | } | 991 | } |
941 | if ((flag & 2) == 2) // V2 !!! | 992 | // The lower 16 bits are an unsigned int16 |
942 | remoteClient.SendMapBlock(response, 2); | 993 | remoteClient.SendMapBlock(response, flag & 0xffff); |
943 | else | ||
944 | remoteClient.SendMapBlock(response, 0); | ||
945 | } | 994 | } |
946 | else | 995 | else |
947 | { | 996 | { |
@@ -961,21 +1010,29 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
961 | foreach (GridRegion r in regions) | 1010 | foreach (GridRegion r in regions) |
962 | { | 1011 | { |
963 | MapBlockData block = new MapBlockData(); | 1012 | MapBlockData block = new MapBlockData(); |
964 | MapBlockFromGridRegion(block, r); | 1013 | MapBlockFromGridRegion(block, r, flag); |
965 | mapBlocks.Add(block); | 1014 | mapBlocks.Add(block); |
966 | } | 1015 | } |
967 | if ((flag & 2) == 2) // V2 !!! | 1016 | remoteClient.SendMapBlock(mapBlocks, flag & 0xffff); |
968 | remoteClient.SendMapBlock(mapBlocks, 2); | ||
969 | else | ||
970 | remoteClient.SendMapBlock(mapBlocks, 0); | ||
971 | 1017 | ||
972 | return mapBlocks; | 1018 | return mapBlocks; |
973 | } | 1019 | } |
974 | 1020 | ||
975 | protected void MapBlockFromGridRegion(MapBlockData block, GridRegion r) | 1021 | protected void MapBlockFromGridRegion(MapBlockData block, GridRegion r, uint flag) |
976 | { | 1022 | { |
977 | block.Access = r.Access; | 1023 | block.Access = r.Access; |
978 | block.MapImageId = r.TerrainImage; | 1024 | switch (flag & 0xffff) |
1025 | { | ||
1026 | case 0: | ||
1027 | block.MapImageId = r.TerrainImage; | ||
1028 | break; | ||
1029 | case 2: | ||
1030 | block.MapImageId = r.ParcelImage; | ||
1031 | break; | ||
1032 | default: | ||
1033 | block.MapImageId = UUID.Zero; | ||
1034 | break; | ||
1035 | } | ||
979 | block.Name = r.RegionName; | 1036 | block.Name = r.RegionName; |
980 | block.X = (ushort)(r.RegionLocX / Constants.RegionSize); | 1037 | block.X = (ushort)(r.RegionLocX / Constants.RegionSize); |
981 | block.Y = (ushort)(r.RegionLocY / Constants.RegionSize); | 1038 | block.Y = (ushort)(r.RegionLocY / Constants.RegionSize); |
@@ -1109,7 +1166,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
1109 | foreach (GridRegion r in regions) | 1166 | foreach (GridRegion r in regions) |
1110 | { | 1167 | { |
1111 | MapBlockData mapBlock = new MapBlockData(); | 1168 | MapBlockData mapBlock = new MapBlockData(); |
1112 | MapBlockFromGridRegion(mapBlock, r); | 1169 | MapBlockFromGridRegion(mapBlock, r, 0); |
1113 | AssetBase texAsset = m_scene.AssetService.Get(mapBlock.MapImageId.ToString()); | 1170 | AssetBase texAsset = m_scene.AssetService.Get(mapBlock.MapImageId.ToString()); |
1114 | 1171 | ||
1115 | if (texAsset != null) | 1172 | if (texAsset != null) |
@@ -1240,7 +1297,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
1240 | responsemapdata["X"] = OSD.FromInteger((int)(xstart + x)); | 1297 | responsemapdata["X"] = OSD.FromInteger((int)(xstart + x)); |
1241 | responsemapdata["Y"] = OSD.FromInteger((int)(ystart + y)); | 1298 | responsemapdata["Y"] = OSD.FromInteger((int)(ystart + y)); |
1242 | // responsemapdata["Z"] = OSD.FromInteger((int)m_scene.GetGroundHeight(x,y)); | 1299 | // responsemapdata["Z"] = OSD.FromInteger((int)m_scene.GetGroundHeight(x,y)); |
1243 | responsemapdata["ID"] = OSD.FromUUID(UUID.Zero); | 1300 | responsemapdata["ID"] = OSD.FromUUID(parcel.GlobalID); |
1244 | responsemapdata["Name"] = OSD.FromString(parcel.Name); | 1301 | responsemapdata["Name"] = OSD.FromString(parcel.Name); |
1245 | responsemapdata["Extra"] = OSD.FromInteger(parcel.Area); | 1302 | responsemapdata["Extra"] = OSD.FromInteger(parcel.Area); |
1246 | responsemapdata["Extra2"] = OSD.FromInteger(parcel.SalePrice); | 1303 | responsemapdata["Extra2"] = OSD.FromInteger(parcel.SalePrice); |
@@ -1250,6 +1307,26 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
1250 | responsemap["7"] = responsearr; | 1307 | responsemap["7"] = responsearr; |
1251 | } | 1308 | } |
1252 | 1309 | ||
1310 | if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero) | ||
1311 | { | ||
1312 | SceneObjectGroup sog = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject); | ||
1313 | if (sog != null) | ||
1314 | { | ||
1315 | OSDArray responsearr = new OSDArray(); | ||
1316 | OSDMap responsemapdata = new OSDMap(); | ||
1317 | responsemapdata["X"] = OSD.FromInteger((int)(xstart + sog.AbsolutePosition.X)); | ||
1318 | responsemapdata["Y"] = OSD.FromInteger((int)(ystart + sog.AbsolutePosition.Y)); | ||
1319 | // responsemapdata["Z"] = OSD.FromInteger((int)m_scene.GetGroundHeight(x,y)); | ||
1320 | responsemapdata["ID"] = OSD.FromUUID(sog.UUID); | ||
1321 | responsemapdata["Name"] = OSD.FromString(sog.Name); | ||
1322 | responsemapdata["Extra"] = OSD.FromInteger(0); // color (unused) | ||
1323 | responsemapdata["Extra2"] = OSD.FromInteger(0); // 0 = telehub / 1 = infohub | ||
1324 | responsearr.Add(responsemapdata); | ||
1325 | |||
1326 | responsemap["1"] = responsearr; | ||
1327 | } | ||
1328 | } | ||
1329 | |||
1253 | return responsemap; | 1330 | return responsemap; |
1254 | } | 1331 | } |
1255 | 1332 | ||
@@ -1268,9 +1345,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
1268 | if (data == null) | 1345 | if (data == null) |
1269 | return; | 1346 | return; |
1270 | 1347 | ||
1348 | byte[] overlay = GenerateOverlay(); | ||
1349 | |||
1271 | m_log.Debug("[WORLDMAP]: STORING MAPTILE IMAGE"); | 1350 | m_log.Debug("[WORLDMAP]: STORING MAPTILE IMAGE"); |
1272 | 1351 | ||
1273 | UUID terrainImageID = UUID.Random(); | 1352 | UUID terrainImageID = UUID.Random(); |
1353 | UUID parcelImageID = UUID.Zero; | ||
1274 | 1354 | ||
1275 | AssetBase asset = new AssetBase( | 1355 | AssetBase asset = new AssetBase( |
1276 | terrainImageID, | 1356 | terrainImageID, |
@@ -1286,14 +1366,35 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
1286 | m_log.DebugFormat("[WORLDMAP]: Storing map tile {0}", asset.ID); | 1366 | m_log.DebugFormat("[WORLDMAP]: Storing map tile {0}", asset.ID); |
1287 | m_scene.AssetService.Store(asset); | 1367 | m_scene.AssetService.Store(asset); |
1288 | 1368 | ||
1369 | if (overlay != null) | ||
1370 | { | ||
1371 | parcelImageID = UUID.Random(); | ||
1372 | |||
1373 | AssetBase parcels = new AssetBase( | ||
1374 | parcelImageID, | ||
1375 | "parcelImage_" + m_scene.RegionInfo.RegionID.ToString(), | ||
1376 | (sbyte)AssetType.Texture, | ||
1377 | m_scene.RegionInfo.RegionID.ToString()); | ||
1378 | parcels.Data = overlay; | ||
1379 | parcels.Description = m_scene.RegionInfo.RegionName; | ||
1380 | parcels.Temporary = false; | ||
1381 | parcels.Flags = AssetFlags.Maptile; | ||
1382 | |||
1383 | m_scene.AssetService.Store(parcels); | ||
1384 | } | ||
1385 | |||
1289 | // Switch to the new one | 1386 | // Switch to the new one |
1290 | UUID lastMapRegionUUID = m_scene.RegionInfo.RegionSettings.TerrainImageID; | 1387 | UUID lastTerrainImageID = m_scene.RegionInfo.RegionSettings.TerrainImageID; |
1388 | UUID lastParcelImageID = m_scene.RegionInfo.RegionSettings.ParcelImageID; | ||
1291 | m_scene.RegionInfo.RegionSettings.TerrainImageID = terrainImageID; | 1389 | m_scene.RegionInfo.RegionSettings.TerrainImageID = terrainImageID; |
1390 | m_scene.RegionInfo.RegionSettings.ParcelImageID = parcelImageID; | ||
1292 | m_scene.RegionInfo.RegionSettings.Save(); | 1391 | m_scene.RegionInfo.RegionSettings.Save(); |
1293 | 1392 | ||
1294 | // Delete the old one | 1393 | // Delete the old one |
1295 | m_log.DebugFormat("[WORLDMAP]: Deleting old map tile {0}", lastMapRegionUUID); | 1394 | // m_log.DebugFormat("[WORLDMAP]: Deleting old map tile {0}", lastTerrainImageID); |
1296 | m_scene.AssetService.Delete(lastMapRegionUUID.ToString()); | 1395 | m_scene.AssetService.Delete(lastTerrainImageID.ToString()); |
1396 | if (lastParcelImageID != UUID.Zero) | ||
1397 | m_scene.AssetService.Delete(lastParcelImageID.ToString()); | ||
1297 | } | 1398 | } |
1298 | 1399 | ||
1299 | private void MakeRootAgent(ScenePresence avatar) | 1400 | private void MakeRootAgent(ScenePresence avatar) |
@@ -1339,6 +1440,66 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
1339 | } | 1440 | } |
1340 | } | 1441 | } |
1341 | 1442 | ||
1443 | private Byte[] GenerateOverlay() | ||
1444 | { | ||
1445 | Bitmap overlay = new Bitmap(256, 256); | ||
1446 | |||
1447 | bool[,] saleBitmap = new bool[64, 64]; | ||
1448 | for (int x = 0 ; x < 64 ; x++) | ||
1449 | { | ||
1450 | for (int y = 0 ; y < 64 ; y++) | ||
1451 | saleBitmap[x, y] = false; | ||
1452 | } | ||
1453 | |||
1454 | bool landForSale = false; | ||
1455 | |||
1456 | List<ILandObject> parcels = m_scene.LandChannel.AllParcels(); | ||
1457 | |||
1458 | Color background = Color.FromArgb(0, 0, 0, 0); | ||
1459 | SolidBrush transparent = new SolidBrush(background); | ||
1460 | Graphics g = Graphics.FromImage(overlay); | ||
1461 | g.FillRectangle(transparent, 0, 0, 256, 256); | ||
1462 | |||
1463 | SolidBrush yellow = new SolidBrush(Color.FromArgb(255, 249, 223, 9)); | ||
1464 | |||
1465 | foreach (ILandObject land in parcels) | ||
1466 | { | ||
1467 | // m_log.DebugFormat("[WORLD MAP]: Parcel {0} flags {1}", land.LandData.Name, land.LandData.Flags); | ||
1468 | if ((land.LandData.Flags & (uint)ParcelFlags.ForSale) != 0) | ||
1469 | { | ||
1470 | landForSale = true; | ||
1471 | |||
1472 | saleBitmap = land.MergeLandBitmaps(saleBitmap, land.GetLandBitmap()); | ||
1473 | } | ||
1474 | } | ||
1475 | |||
1476 | if (!landForSale) | ||
1477 | { | ||
1478 | m_log.DebugFormat("[WORLD MAP]: Region {0} has no parcels for sale, not geenrating overlay", m_scene.RegionInfo.RegionName); | ||
1479 | return null; | ||
1480 | } | ||
1481 | |||
1482 | m_log.DebugFormat("[WORLD MAP]: Region {0} has parcels for sale, genrating overlay", m_scene.RegionInfo.RegionName); | ||
1483 | |||
1484 | for (int x = 0 ; x < 64 ; x++) | ||
1485 | { | ||
1486 | for (int y = 0 ; y < 64 ; y++) | ||
1487 | { | ||
1488 | if (saleBitmap[x, y]) | ||
1489 | g.FillRectangle(yellow, x * 4, 252 - (y * 4), 4, 4); | ||
1490 | } | ||
1491 | } | ||
1492 | |||
1493 | try | ||
1494 | { | ||
1495 | return OpenJPEG.EncodeFromImage(overlay, true); | ||
1496 | } | ||
1497 | catch (Exception e) | ||
1498 | { | ||
1499 | m_log.DebugFormat("[WORLD MAP]: Error creating parcel overlay: " + e.ToString()); | ||
1500 | } | ||
1501 | return null; | ||
1502 | } | ||
1342 | } | 1503 | } |
1343 | 1504 | ||
1344 | public struct MapRequestState | 1505 | public struct MapRequestState |