aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
authorDan Lake2012-02-01 16:25:35 -0800
committerDan Lake2012-02-01 16:25:35 -0800
commitc10193c72b1f029a958f04d2f5d7ee384e693aaa (patch)
tree052ec7e973c15b158310511197affad14eb9c64f /OpenSim/Region
parentTrigger event when prims are scheduled for an update. This gives modules earl... (diff)
parentSmall optimization to last commit (diff)
downloadopensim-SC-c10193c72b1f029a958f04d2f5d7ee384e693aaa.zip
opensim-SC-c10193c72b1f029a958f04d2f5d7ee384e693aaa.tar.gz
opensim-SC-c10193c72b1f029a958f04d2f5d7ee384e693aaa.tar.bz2
opensim-SC-c10193c72b1f029a958f04d2f5d7ee384e693aaa.tar.xz
Merge branch 'master' of ssh://opensimulator.org/var/git/opensim
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/Application/ConfigurationLoader.cs19
-rw-r--r--OpenSim/Region/Application/OpenSim.cs29
-rw-r--r--OpenSim/Region/Application/OpenSimBase.cs12
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs75
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs151
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs4
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs63
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs81
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLImageManager.cs135
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs1
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs160
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/Tests/Resources/4-tile2.jp2bin0 -> 24410 bytes
-rw-r--r--OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs39
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs28
-rw-r--r--OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs90
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs5
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs3
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs10
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs9
-rw-r--r--OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs224
-rw-r--r--OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs34
-rw-r--r--OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs9
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/LocalGridUserServiceConnector.cs4
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/RemoteGridUserServiceConnector.cs5
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs22
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs3
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs19
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs85
-rw-r--r--OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs84
-rw-r--r--OpenSim/Region/CoreModules/World/Estate/TelehubManager.cs95
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandObject.cs11
-rw-r--r--OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs410
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs209
-rw-r--r--OpenSim/Region/DataSnapshot/DataRequestHandler.cs2
-rw-r--r--OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs2
-rw-r--r--OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs25
-rw-r--r--OpenSim/Region/Framework/Interfaces/IJ2KDecoder.cs19
-rw-r--r--OpenSim/Region/Framework/Interfaces/INPCModule.cs49
-rw-r--r--OpenSim/Region/Framework/Interfaces/IProfileModule.cs37
-rw-r--r--OpenSim/Region/Framework/Interfaces/IRegionReadyModule.cs38
-rw-r--r--OpenSim/Region/Framework/Interfaces/IScriptModule.cs13
-rw-r--r--OpenSim/Region/Framework/Interfaces/ISearchModule.cs36
-rw-r--r--OpenSim/Region/Framework/Interfaces/IUserManagement.cs5
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs36
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs281
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs163
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs45
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs15
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs18
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs103
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs155
-rw-r--r--OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs30
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneObjectScriptTests.cs76
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs6
-rw-r--r--OpenSim/Region/OptionalModules/Agent/TextureSender/J2KDecoderCommandModule.cs155
-rw-r--r--OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs151
-rw-r--r--OpenSim/Region/OptionalModules/Asset/AssetInfoModule.cs185
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs95
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs2
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IInventoryItem.cs5
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs64
-rw-r--r--OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs4
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs21
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs87
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs30
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs33
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs4
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODECharacter.cs40
-rw-r--r--OpenSim/Region/Physics/OdePlugin/OdeScene.cs32
-rw-r--r--OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs7
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs180
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs352
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs28
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs55
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs13
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs10
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs37
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs28
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs156
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs170
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs139
-rw-r--r--OpenSim/Region/UserStatistics/WebStatsModule.cs6
87 files changed, 4406 insertions, 979 deletions
diff --git a/OpenSim/Region/Application/ConfigurationLoader.cs b/OpenSim/Region/Application/ConfigurationLoader.cs
index 4a7c8b0..8d95c41 100644
--- a/OpenSim/Region/Application/ConfigurationLoader.cs
+++ b/OpenSim/Region/Application/ConfigurationLoader.cs
@@ -107,15 +107,13 @@ namespace OpenSim
107 } 107 }
108 else 108 else
109 { 109 {
110 m_log.ErrorFormat("Master ini file {0} not found", masterFilePath); 110 m_log.ErrorFormat("Master ini file {0} not found", Path.GetFullPath(masterFilePath));
111 Environment.Exit(1); 111 Environment.Exit(1);
112 } 112 }
113 } 113 }
114 } 114 }
115 115
116 116 string iniFileName = startupConfig.GetString("inifile", "OpenSim.ini");
117 string iniFileName =
118 startupConfig.GetString("inifile", "OpenSim.ini");
119 117
120 if (IsUri(iniFileName)) 118 if (IsUri(iniFileName))
121 { 119 {
@@ -131,8 +129,7 @@ namespace OpenSim
131 if (!File.Exists(Application.iniFilePath)) 129 if (!File.Exists(Application.iniFilePath))
132 { 130 {
133 iniFileName = "OpenSim.xml"; 131 iniFileName = "OpenSim.xml";
134 Application.iniFilePath = Path.GetFullPath( 132 Application.iniFilePath = Path.GetFullPath(Path.Combine(Util.configDir(), iniFileName));
135 Path.Combine(Util.configDir(), iniFileName));
136 } 133 }
137 134
138 if (File.Exists(Application.iniFilePath)) 135 if (File.Exists(Application.iniFilePath))
@@ -142,15 +139,12 @@ namespace OpenSim
142 } 139 }
143 } 140 }
144 141
145 string iniDirName = 142 string iniDirName = startupConfig.GetString("inidirectory", "config");
146 startupConfig.GetString("inidirectory", "config"); 143 string iniDirPath = Path.Combine(Util.configDir(), iniDirName);
147 string iniDirPath =
148 Path.Combine(Util.configDir(), iniDirName);
149 144
150 if (Directory.Exists(iniDirPath)) 145 if (Directory.Exists(iniDirPath))
151 { 146 {
152 m_log.InfoFormat("Searching folder {0} for config ini files", 147 m_log.InfoFormat("Searching folder {0} for config ini files", iniDirPath);
153 iniDirPath);
154 148
155 string[] fileEntries = Directory.GetFiles(iniDirName); 149 string[] fileEntries = Directory.GetFiles(iniDirName);
156 foreach (string filePath in fileEntries) 150 foreach (string filePath in fileEntries)
@@ -172,7 +166,6 @@ namespace OpenSim
172 if (sources.Count == 0) 166 if (sources.Count == 0)
173 { 167 {
174 m_log.FatalFormat("[CONFIG]: Could not load any configuration"); 168 m_log.FatalFormat("[CONFIG]: Could not load any configuration");
175 m_log.FatalFormat("[CONFIG]: Did you copy the OpenSimDefaults.ini.example file to OpenSimDefaults.ini?");
176 Environment.Exit(1); 169 Environment.Exit(1);
177 } 170 }
178 171
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs
index 3a1a8c7..145875b 100644
--- a/OpenSim/Region/Application/OpenSim.cs
+++ b/OpenSim/Region/Application/OpenSim.cs
@@ -250,8 +250,10 @@ namespace OpenSim
250 + "If level <= 0 then no extra http logging is done.\n", 250 + "If level <= 0 then no extra http logging is done.\n",
251 Debug); 251 Debug);
252 252
253 m_console.Commands.AddCommand("region", false, "debug teleport", "debug teleport", "Toggle teleport route debugging", Debug);
254
253 m_console.Commands.AddCommand("region", false, "debug scene", 255 m_console.Commands.AddCommand("region", false, "debug scene",
254 "debug scene <cripting> <collisions> <physics>", 256 "debug scene <scripting> <collisions> <physics>",
255 "Turn on scene debugging", Debug); 257 "Turn on scene debugging", Debug);
256 258
257 m_console.Commands.AddCommand("region", false, "change region", 259 m_console.Commands.AddCommand("region", false, "change region",
@@ -289,12 +291,16 @@ namespace OpenSim
289 291
290 m_console.Commands.AddCommand("region", false, "save oar", 292 m_console.Commands.AddCommand("region", false, "save oar",
291 //"save oar [-v|--version=<N>] [-p|--profile=<url>] [<OAR path>]", 293 //"save oar [-v|--version=<N>] [-p|--profile=<url>] [<OAR path>]",
292 "save oar [-p|--profile=<url>] [--noassets] [--perm=<permissions>] [<OAR path>]", 294 "save oar [-h|--home=<url>] [--noassets] [--publish] [--perm=<permissions>] [<OAR path>]",
293 "Save a region's data to an OAR archive.", 295 "Save a region's data to an OAR archive.",
294// "-v|--version=<N> generates scene objects as per older versions of the serialization (e.g. -v=0)" + Environment.NewLine 296// "-v|--version=<N> generates scene objects as per older versions of the serialization (e.g. -v=0)" + Environment.NewLine
295 "-p|--profile=<url> adds the url of the profile service to the saved user information." + Environment.NewLine 297 "-h|--home=<url> adds the url of the profile service to the saved user information." + Environment.NewLine
296 + "--noassets stops assets being saved to the OAR." + Environment.NewLine 298 + "--noassets stops assets being saved to the OAR." + Environment.NewLine
297 + "--perm stops objects with insufficient permissions from being saved to the OAR." + Environment.NewLine 299 + "--publish saves an OAR stripped of owner and last owner information." + Environment.NewLine
300 + " on reload, the estate owner will be the owner of all objects" + Environment.NewLine
301 + " this is useful if you're making oars generally available that might be reloaded to the same grid from which you published" + Environment.NewLine
302 + " this option is EXPERIMENTAL" + Environment.NewLine
303 + "--perm=<permissions> stops objects with insufficient permissions from being saved to the OAR." + Environment.NewLine
298 + " <permissions> can contain one or more of these characters: \"C\" = Copy, \"T\" = Transfer" + Environment.NewLine 304 + " <permissions> can contain one or more of these characters: \"C\" = Copy, \"T\" = Transfer" + Environment.NewLine
299 + "The OAR path must be a filesystem path." 305 + "The OAR path must be a filesystem path."
300 + " If this is not given then the oar is saved to region.oar in the current directory.", 306 + " If this is not given then the oar is saved to region.oar in the current directory.",
@@ -948,6 +954,21 @@ namespace OpenSim
948 954
949 break; 955 break;
950 956
957 case "teleport":
958 foreach(Scene s in m_sceneManager.Scenes)
959 {
960 if (s.DEBUG)
961 {
962 s.DEBUG = false;
963 MainConsole.Instance.Output("Teleport debugging is disabled!");
964 }
965 else{
966 s.DEBUG = true;
967 MainConsole.Instance.Output("Teleport debugging is enabled!");
968 }
969 }
970 break;
971
951 default: 972 default:
952 MainConsole.Instance.Output("Unknown debug command"); 973 MainConsole.Instance.Output("Unknown debug command");
953 break; 974 break;
diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs
index 9f9b4f0..f482d8f 100644
--- a/OpenSim/Region/Application/OpenSimBase.cs
+++ b/OpenSim/Region/Application/OpenSimBase.cs
@@ -202,16 +202,16 @@ namespace OpenSim
202 // Load the simulation data service 202 // Load the simulation data service
203 IConfig simDataConfig = m_config.Source.Configs["SimulationDataStore"]; 203 IConfig simDataConfig = m_config.Source.Configs["SimulationDataStore"];
204 if (simDataConfig == null) 204 if (simDataConfig == null)
205 throw new Exception("Configuration file is missing the [SimulationDataStore] section"); 205 throw new Exception("Configuration file is missing the [SimulationDataStore] section. Have you copied OpenSim.ini.example to OpenSim.ini to reference config-include/ files?");
206 string module = simDataConfig.GetString("LocalServiceModule", String.Empty); 206 string module = simDataConfig.GetString("LocalServiceModule", String.Empty);
207 if (String.IsNullOrEmpty(module)) 207 if (String.IsNullOrEmpty(module))
208 throw new Exception("Configuration file is missing the LocalServiceModule parameter in the [SimulationDataStore] section"); 208 throw new Exception("Configuration file is missing the LocalServiceModule parameter in the [SimulationDataStore] section.");
209 m_simulationDataService = ServerUtils.LoadPlugin<ISimulationDataService>(module, new object[] { m_config.Source }); 209 m_simulationDataService = ServerUtils.LoadPlugin<ISimulationDataService>(module, new object[] { m_config.Source });
210 210
211 // Load the estate data service 211 // Load the estate data service
212 IConfig estateDataConfig = m_config.Source.Configs["EstateDataStore"]; 212 IConfig estateDataConfig = m_config.Source.Configs["EstateDataStore"];
213 if (estateDataConfig == null) 213 if (estateDataConfig == null)
214 throw new Exception("Configuration file is missing the [EstateDataStore] section"); 214 throw new Exception("Configuration file is missing the [EstateDataStore] section. Have you copied OpenSim.ini.example to OpenSim.ini to reference config-include/ files?");
215 module = estateDataConfig.GetString("LocalServiceModule", String.Empty); 215 module = estateDataConfig.GetString("LocalServiceModule", String.Empty);
216 if (String.IsNullOrEmpty(module)) 216 if (String.IsNullOrEmpty(module))
217 throw new Exception("Configuration file is missing the LocalServiceModule parameter in the [EstateDataStore] section"); 217 throw new Exception("Configuration file is missing the LocalServiceModule parameter in the [EstateDataStore] section");
@@ -383,6 +383,9 @@ namespace OpenSim
383 // TODO : Try setting resource for region xstats here on scene 383 // TODO : Try setting resource for region xstats here on scene
384 MainServer.Instance.AddStreamHandler(new Region.Framework.Scenes.RegionStatsHandler(regionInfo)); 384 MainServer.Instance.AddStreamHandler(new Region.Framework.Scenes.RegionStatsHandler(regionInfo));
385 385
386 scene.loadAllLandObjectsFromStorage(regionInfo.originRegionID);
387 scene.EventManager.TriggerParcelPrimCountUpdate();
388
386 try 389 try
387 { 390 {
388 scene.RegisterRegionWithGrid(); 391 scene.RegisterRegionWithGrid();
@@ -398,9 +401,6 @@ namespace OpenSim
398 Environment.Exit(1); 401 Environment.Exit(1);
399 } 402 }
400 403
401 scene.loadAllLandObjectsFromStorage(regionInfo.originRegionID);
402 scene.EventManager.TriggerParcelPrimCountUpdate();
403
404 // We need to do this after we've initialized the 404 // We need to do this after we've initialized the
405 // scripting engines. 405 // scripting engines.
406 scene.CreateScriptInstances(); 406 scene.CreateScriptInstances();
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
index 2347cf2..cf0c28b 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
@@ -94,6 +94,7 @@ namespace OpenSim.Region.ClientStack.Linden
94 private static readonly string m_notecardUpdatePath = "0004/"; 94 private static readonly string m_notecardUpdatePath = "0004/";
95 private static readonly string m_notecardTaskUpdatePath = "0005/"; 95 private static readonly string m_notecardTaskUpdatePath = "0005/";
96 // private static readonly string m_fetchInventoryPath = "0006/"; 96 // private static readonly string m_fetchInventoryPath = "0006/";
97 private static readonly string m_copyFromNotecardPath = "0007/";
97 // private static readonly string m_remoteParcelRequestPath = "0009/";// This is in the LandManagementModule. 98 // private static readonly string m_remoteParcelRequestPath = "0009/";// This is in the LandManagementModule.
98 99
99 100
@@ -180,6 +181,7 @@ namespace OpenSim.Region.ClientStack.Linden
180 m_HostCapsObj.RegisterHandler("UpdateNotecardAgentInventory", req); 181 m_HostCapsObj.RegisterHandler("UpdateNotecardAgentInventory", req);
181 m_HostCapsObj.RegisterHandler("UpdateScriptAgentInventory", req); 182 m_HostCapsObj.RegisterHandler("UpdateScriptAgentInventory", req);
182 m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req); 183 m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req);
184 m_HostCapsObj.RegisterHandler("CopyInventoryFromNotecard", new RestStreamHandler("POST", capsBase + m_copyFromNotecardPath, CopyInventoryFromNotecard));
183 185
184 // As of RC 1.22.9 of the Linden client this is 186 // As of RC 1.22.9 of the Linden client this is
185 // supported 187 // supported
@@ -366,7 +368,7 @@ namespace OpenSim.Region.ClientStack.Linden
366 368
367 if (mm != null) 369 if (mm != null)
368 { 370 {
369 if (!mm.UploadCovered(client, mm.UploadCharge)) 371 if (!mm.UploadCovered(client.AgentId, mm.UploadCharge))
370 { 372 {
371 if (client != null) 373 if (client != null)
372 client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false); 374 client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false);
@@ -723,6 +725,75 @@ namespace OpenSim.Region.ClientStack.Linden
723 725
724 return LLSDHelpers.SerialiseLLSDReply(uploadResponse); 726 return LLSDHelpers.SerialiseLLSDReply(uploadResponse);
725 } 727 }
728
729 /// <summary>
730 /// Called by the CopyInventoryFromNotecard caps handler.
731 /// </summary>
732 /// <param name="request"></param>
733 /// <param name="path"></param>
734 /// <param name="param"></param>
735 public string CopyInventoryFromNotecard(string request, string path, string param,
736 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
737 {
738 Hashtable response = new Hashtable();
739 response["int_response_code"] = 404;
740 response["content_type"] = "text/plain";
741 response["keepalive"] = false;
742 response["str_response_string"] = "";
743
744 try
745 {
746 OSDMap content = (OSDMap)OSDParser.DeserializeLLSDXml(request);
747 UUID objectID = content["object-id"].AsUUID();
748 UUID notecardID = content["notecard-id"].AsUUID();
749 UUID folderID = content["folder-id"].AsUUID();
750 UUID itemID = content["item-id"].AsUUID();
751
752 // m_log.InfoFormat("[CAPS]: CopyInventoryFromNotecard, FolderID:{0}, ItemID:{1}, NotecardID:{2}, ObjectID:{3}", folderID, itemID, notecardID, objectID);
753
754 if (objectID != UUID.Zero)
755 {
756 SceneObjectPart part = m_Scene.GetSceneObjectPart(objectID);
757 if (part != null)
758 {
759 TaskInventoryItem taskItem = part.Inventory.GetInventoryItem(notecardID);
760 if (!m_Scene.Permissions.CanCopyObjectInventory(notecardID, objectID, m_HostCapsObj.AgentID))
761 {
762 return LLSDHelpers.SerialiseLLSDReply(response);
763 }
764 }
765 }
766
767 InventoryItemBase item = null;
768 InventoryItemBase copyItem = null;
769 IClientAPI client = null;
770
771 m_Scene.TryGetClient(m_HostCapsObj.AgentID, out client);
772 item = m_Scene.InventoryService.GetItem(new InventoryItemBase(itemID));
773 if (item != null)
774 {
775 copyItem = m_Scene.GiveInventoryItem(m_HostCapsObj.AgentID, item.Owner, itemID, folderID);
776 if (copyItem != null && client != null)
777 {
778 m_log.InfoFormat("[CAPS]: CopyInventoryFromNotecard, ItemID:{0}, FolderID:{1}", copyItem.ID, copyItem.Folder);
779 client.SendBulkUpdateInventory(copyItem);
780 }
781 }
782 else
783 {
784 m_log.ErrorFormat("[CAPS]: CopyInventoryFromNotecard - Failed to retrieve item {0} from notecard {1}", itemID, notecardID);
785 if (client != null)
786 client.SendAlertMessage("Failed to retrieve item");
787 }
788 }
789 catch (Exception e)
790 {
791 m_log.ErrorFormat("[CAPS]: CopyInventoryFromNotecard : {0}", e.ToString());
792 }
793
794 response["int_response_code"] = 200;
795 return LLSDHelpers.SerialiseLLSDReply(response);
796 }
726 } 797 }
727 798
728 public class AssetUploader 799 public class AssetUploader
@@ -1018,4 +1089,4 @@ namespace OpenSim.Region.ClientStack.Linden
1018 fs.Close(); 1089 fs.Close();
1019 } 1090 }
1020 } 1091 }
1021} \ No newline at end of file 1092}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs b/OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs
new file mode 100644
index 0000000..14501c7
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs
@@ -0,0 +1,151 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Reflection;
31using log4net;
32using Nini.Config;
33using Mono.Addins;
34using OpenMetaverse;
35using OpenSim.Framework;
36using OpenSim.Framework.Servers.HttpServer;
37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes;
39using OpenSim.Services.Interfaces;
40using Caps = OpenSim.Framework.Capabilities.Caps;
41using OpenSim.Capabilities.Handlers;
42
43namespace OpenSim.Region.ClientStack.Linden
44{
45 /// <summary>
46 /// This module implements both WebFetchInventoryDescendents and FetchInventoryDescendents2 capabilities.
47 /// </summary>
48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
49 public class FetchInventory2Module : INonSharedRegionModule
50 {
51// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52
53 public bool Enabled { get; private set; }
54
55 private Scene m_scene;
56
57 private IInventoryService m_inventoryService;
58
59 private string m_fetchInventory2Url;
60
61 private FetchInventory2Handler m_fetchHandler;
62
63 #region ISharedRegionModule Members
64
65 public void Initialise(IConfigSource source)
66 {
67 IConfig config = source.Configs["ClientStack.LindenCaps"];
68 if (config == null)
69 return;
70
71 m_fetchInventory2Url = config.GetString("Cap_FetchInventory2", string.Empty);
72
73 if (m_fetchInventory2Url != string.Empty)
74 Enabled = true;
75 }
76
77 public void AddRegion(Scene s)
78 {
79 if (!Enabled)
80 return;
81
82 m_scene = s;
83 }
84
85 public void RemoveRegion(Scene s)
86 {
87 if (!Enabled)
88 return;
89
90 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
91 m_scene = null;
92 }
93
94 public void RegionLoaded(Scene s)
95 {
96 if (!Enabled)
97 return;
98
99 m_inventoryService = m_scene.InventoryService;
100
101 // We'll reuse the same handler for all requests.
102 if (m_fetchInventory2Url == "localhost")
103 m_fetchHandler = new FetchInventory2Handler(m_inventoryService);
104
105 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
106 }
107
108 public void PostInitialise() {}
109
110 public void Close() {}
111
112 public string Name { get { return "FetchInventory2Module"; } }
113
114 public Type ReplaceableInterface
115 {
116 get { return null; }
117 }
118
119 #endregion
120
121 private void RegisterCaps(UUID agentID, Caps caps)
122 {
123 RegisterFetchCap(agentID, caps, "FetchInventory2", m_fetchInventory2Url);
124 }
125
126 private void RegisterFetchCap(UUID agentID, Caps caps, string capName, string url)
127 {
128 string capUrl;
129
130 if (url == "localhost")
131 {
132 capUrl = "/CAPS/" + UUID.Random();
133
134 IRequestHandler reqHandler
135 = new RestStreamHandler("POST", capUrl, m_fetchHandler.FetchInventoryRequest);
136
137 caps.RegisterHandler(capName, reqHandler);
138 }
139 else
140 {
141 capUrl = url;
142
143 caps.RegisterHandler(capName, capUrl);
144 }
145
146// m_log.DebugFormat(
147// "[FETCH INVENTORY2 MODULE]: Registered capability {0} at {1} in region {2} for {3}",
148// capName, capUrl, m_scene.RegionInfo.RegionName, agentID);
149 }
150 }
151}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs
index b2f04f9..aed03b3 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs
@@ -147,7 +147,7 @@ namespace OpenSim.Region.ClientStack.Linden
147 { 147 {
148 if (m_scene.TryGetClient(agentID, out client)) 148 if (m_scene.TryGetClient(agentID, out client))
149 { 149 {
150 if (!mm.UploadCovered(client, mm.UploadCharge)) 150 if (!mm.UploadCovered(client.AgentId, mm.UploadCharge))
151 { 151 {
152 if (client != null) 152 if (client != null)
153 client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false); 153 client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false);
@@ -268,4 +268,4 @@ namespace OpenSim.Region.ClientStack.Linden
268 268
269 } 269 }
270 } 270 }
271} \ No newline at end of file 271}
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs b/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
index cb9692a..afbe56b 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
@@ -45,6 +45,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
45 private const int IMAGE_PACKET_SIZE = 1000; 45 private const int IMAGE_PACKET_SIZE = 1000;
46 private const int FIRST_PACKET_SIZE = 600; 46 private const int FIRST_PACKET_SIZE = 600;
47 47
48 /// <summary>
49 /// If we've requested an asset but not received it in this ticks timeframe, then allow a duplicate
50 /// request from the client to trigger a fresh asset request.
51 /// </summary>
52 /// <remarks>
53 /// There are 10,000 ticks in a millisecond
54 /// </remarks>
55 private const int ASSET_REQUEST_TIMEOUT = 100000000;
56
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 57 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49 58
50 public uint LastSequence; 59 public uint LastSequence;
@@ -57,8 +66,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
57 public UUID AgentID; 66 public UUID AgentID;
58 public IInventoryAccessModule InventoryAccessModule; 67 public IInventoryAccessModule InventoryAccessModule;
59 private OpenJPEG.J2KLayerInfo[] m_layers; 68 private OpenJPEG.J2KLayerInfo[] m_layers;
69
70 /// <summary>
71 /// Has this request decoded the asset data?
72 /// </summary>
60 public bool IsDecoded { get; private set; } 73 public bool IsDecoded { get; private set; }
74
75 /// <summary>
76 /// Has this request received the required asset data?
77 /// </summary>
61 public bool HasAsset { get; private set; } 78 public bool HasAsset { get; private set; }
79
80 /// <summary>
81 /// Time in milliseconds at which the asset was requested.
82 /// </summary>
83 public long AssetRequestTime { get; private set; }
84
62 public C5.IPriorityQueueHandle<J2KImage> PriorityQueueHandle; 85 public C5.IPriorityQueueHandle<J2KImage> PriorityQueueHandle;
63 86
64 private uint m_currentPacket; 87 private uint m_currentPacket;
@@ -82,7 +105,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
82 /// <param name="packetsToSend">Maximum number of packets to send during this call</param> 105 /// <param name="packetsToSend">Maximum number of packets to send during this call</param>
83 /// <param name="packetsSent">Number of packets sent during this call</param> 106 /// <param name="packetsSent">Number of packets sent during this call</param>
84 /// <returns>True if the transfer completes at the current discard level, otherwise false</returns> 107 /// <returns>True if the transfer completes at the current discard level, otherwise false</returns>
85 public bool SendPackets(LLClientView client, int packetsToSend, out int packetsSent) 108 public bool SendPackets(IClientAPI client, int packetsToSend, out int packetsSent)
86 { 109 {
87 packetsSent = 0; 110 packetsSent = 0;
88 111
@@ -102,7 +125,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
102 { 125 {
103 m_currentPacket = 2; 126 m_currentPacket = 2;
104 } 127 }
105 128
106 while (sendMore && packetsSent < packetsToSend && m_currentPacket <= m_stopPacket) 129 while (sendMore && packetsSent < packetsToSend && m_currentPacket <= m_stopPacket)
107 { 130 {
108 sendMore = SendPacket(client); 131 sendMore = SendPacket(client);
@@ -114,17 +137,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP
114 return (m_currentPacket > m_stopPacket); 137 return (m_currentPacket > m_stopPacket);
115 } 138 }
116 139
140 /// <summary>
141 /// This is where we decide what we need to update
142 /// and assign the real discardLevel and packetNumber
143 /// assuming of course that the connected client might be bonkers
144 /// </summary>
117 public void RunUpdate() 145 public void RunUpdate()
118 { 146 {
119 //This is where we decide what we need to update
120 //and assign the real discardLevel and packetNumber
121 //assuming of course that the connected client might be bonkers
122
123 if (!HasAsset) 147 if (!HasAsset)
124 { 148 {
125 if (!m_assetRequested) 149 if (!m_assetRequested || DateTime.UtcNow.Ticks > AssetRequestTime + ASSET_REQUEST_TIMEOUT)
126 { 150 {
151// m_log.DebugFormat(
152// "[J2KIMAGE]: Requesting asset {0} from request in packet {1}, already requested? {2}, due to timeout? {3}",
153// TextureID, LastSequence, m_assetRequested, DateTime.UtcNow.Ticks > AssetRequestTime + ASSET_REQUEST_TIMEOUT);
154
127 m_assetRequested = true; 155 m_assetRequested = true;
156 AssetRequestTime = DateTime.UtcNow.Ticks;
157
128 AssetService.Get(TextureID.ToString(), this, AssetReceived); 158 AssetService.Get(TextureID.ToString(), this, AssetReceived);
129 } 159 }
130 } 160 }
@@ -137,6 +167,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
137 { 167 {
138 //Request decode 168 //Request decode
139 m_decodeRequested = true; 169 m_decodeRequested = true;
170
171// m_log.DebugFormat("[J2KIMAGE]: Requesting decode of asset {0}", TextureID);
172
140 // Do we have a jpeg decoder? 173 // Do we have a jpeg decoder?
141 if (J2KDecoder != null) 174 if (J2KDecoder != null)
142 { 175 {
@@ -149,7 +182,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
149 // Send it off to the jpeg decoder 182 // Send it off to the jpeg decoder
150 J2KDecoder.BeginDecode(TextureID, m_asset, J2KDecodedCallback); 183 J2KDecoder.BeginDecode(TextureID, m_asset, J2KDecodedCallback);
151 } 184 }
152
153 } 185 }
154 else 186 else
155 { 187 {
@@ -208,7 +240,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
208 } 240 }
209 } 241 }
210 242
211 private bool SendFirstPacket(LLClientView client) 243 private bool SendFirstPacket(IClientAPI client)
212 { 244 {
213 if (client == null) 245 if (client == null)
214 return false; 246 return false;
@@ -243,7 +275,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
243 return false; 275 return false;
244 } 276 }
245 277
246 private bool SendPacket(LLClientView client) 278 private bool SendPacket(IClientAPI client)
247 { 279 {
248 if (client == null) 280 if (client == null)
249 return false; 281 return false;
@@ -328,14 +360,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
328 { 360 {
329 if (m_currentPacket == 0) 361 if (m_currentPacket == 0)
330 return 0; 362 return 0;
363
331 if (m_currentPacket == 1) 364 if (m_currentPacket == 1)
332 return FIRST_PACKET_SIZE; 365 return FIRST_PACKET_SIZE;
333 366
334 int result = FIRST_PACKET_SIZE + ((int)m_currentPacket - 2) * IMAGE_PACKET_SIZE; 367 int result = FIRST_PACKET_SIZE + ((int)m_currentPacket - 2) * IMAGE_PACKET_SIZE;
368
335 if (result < 0) 369 if (result < 0)
336 {
337 result = FIRST_PACKET_SIZE; 370 result = FIRST_PACKET_SIZE;
338 } 371
339 return result; 372 return result;
340 } 373 }
341 374
@@ -372,9 +405,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
372 405
373 private void AssetReceived(string id, Object sender, AssetBase asset) 406 private void AssetReceived(string id, Object sender, AssetBase asset)
374 { 407 {
408// m_log.DebugFormat(
409// "[J2KIMAGE]: Received asset {0} ({1} bytes)", id, asset != null ? asset.Data.Length.ToString() : "n/a");
410
375 UUID assetID = UUID.Zero; 411 UUID assetID = UUID.Zero;
376 if (asset != null) 412 if (asset != null)
413 {
377 assetID = asset.FullID; 414 assetID = asset.FullID;
415 }
378 else if ((InventoryAccessModule != null) && (sender != InventoryAccessModule)) 416 else if ((InventoryAccessModule != null) && (sender != InventoryAccessModule))
379 { 417 {
380 // Unfortunately we need this here, there's no other way. 418 // Unfortunately we need this here, there's no other way.
@@ -395,7 +433,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
395 } 433 }
396 434
397 AssetDataCallback(assetID, asset); 435 AssetDataCallback(assetID, asset);
398
399 } 436 }
400 } 437 }
401} 438}
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index fe28ba3..a7bf06d 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -219,6 +219,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
219 public event BakeTerrain OnBakeTerrain; 219 public event BakeTerrain OnBakeTerrain;
220 public event RequestTerrain OnUploadTerrain; 220 public event RequestTerrain OnUploadTerrain;
221 public event EstateChangeInfo OnEstateChangeInfo; 221 public event EstateChangeInfo OnEstateChangeInfo;
222 public event EstateManageTelehub OnEstateManageTelehub;
222 public event EstateRestartSimRequest OnEstateRestartSimRequest; 223 public event EstateRestartSimRequest OnEstateRestartSimRequest;
223 public event EstateChangeCovenantRequest OnEstateChangeCovenantRequest; 224 public event EstateChangeCovenantRequest OnEstateChangeCovenantRequest;
224 public event UpdateEstateAccessDeltaRequest OnUpdateEstateAccessDeltaRequest; 225 public event UpdateEstateAccessDeltaRequest OnUpdateEstateAccessDeltaRequest;
@@ -304,6 +305,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
304 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 305 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
305 protected static Dictionary<PacketType, PacketMethod> PacketHandlers = new Dictionary<PacketType, PacketMethod>(); //Global/static handlers for all clients 306 protected static Dictionary<PacketType, PacketMethod> PacketHandlers = new Dictionary<PacketType, PacketMethod>(); //Global/static handlers for all clients
306 307
308 /// <summary>
309 /// Handles UDP texture download.
310 /// </summary>
311 public LLImageManager ImageManager { get; private set; }
312
307 private readonly LLUDPServer m_udpServer; 313 private readonly LLUDPServer m_udpServer;
308 private readonly LLUDPClient m_udpClient; 314 private readonly LLUDPClient m_udpClient;
309 private readonly UUID m_sessionId; 315 private readonly UUID m_sessionId;
@@ -348,7 +354,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
348 protected Dictionary<PacketType, PacketProcessor> m_packetHandlers = new Dictionary<PacketType, PacketProcessor>(); 354 protected Dictionary<PacketType, PacketProcessor> m_packetHandlers = new Dictionary<PacketType, PacketProcessor>();
349 protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers 355 protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers
350 protected Scene m_scene; 356 protected Scene m_scene;
351 private LLImageManager m_imageManager;
352 protected string m_firstName; 357 protected string m_firstName;
353 protected string m_lastName; 358 protected string m_lastName;
354 protected Thread m_clientThread; 359 protected Thread m_clientThread;
@@ -459,7 +464,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
459 464
460 m_assetService = m_scene.RequestModuleInterface<IAssetService>(); 465 m_assetService = m_scene.RequestModuleInterface<IAssetService>();
461 m_GroupsModule = scene.RequestModuleInterface<IGroupsModule>(); 466 m_GroupsModule = scene.RequestModuleInterface<IGroupsModule>();
462 m_imageManager = new LLImageManager(this, m_assetService, Scene.RequestModuleInterface<IJ2KDecoder>()); 467 ImageManager = new LLImageManager(this, m_assetService, Scene.RequestModuleInterface<IJ2KDecoder>());
463 m_channelVersion = Util.StringToBytes256(scene.GetSimulatorVersion()); 468 m_channelVersion = Util.StringToBytes256(scene.GetSimulatorVersion());
464 m_agentId = agentId; 469 m_agentId = agentId;
465 m_sessionId = sessionId; 470 m_sessionId = sessionId;
@@ -499,7 +504,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
499 IsActive = false; 504 IsActive = false;
500 505
501 // Shutdown the image manager 506 // Shutdown the image manager
502 m_imageManager.Close(); 507 ImageManager.Close();
503 508
504 // Fire the callback for this connection closing 509 // Fire the callback for this connection closing
505 if (OnConnectionClosed != null) 510 if (OnConnectionClosed != null)
@@ -577,7 +582,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
577 /// Add a handler for the given packet type. 582 /// Add a handler for the given packet type.
578 /// </summary> 583 /// </summary>
579 /// <remarks> 584 /// <remarks>
580 /// The packet is handled on its own thread. If packets must be handled in the order in which thye 585 /// The packet is handled on its own thread. If packets must be handled in the order in which they
581 /// are received then please use the synchronous version of this method. 586 /// are received then please use the synchronous version of this method.
582 /// </remarks> 587 /// </remarks>
583 /// <param name="packetType"></param> 588 /// <param name="packetType"></param>
@@ -758,9 +763,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
758 OutPacket(handshake, ThrottleOutPacketType.Task); 763 OutPacket(handshake, ThrottleOutPacketType.Task);
759 } 764 }
760 765
761 /// <summary>
762 ///
763 /// </summary>
764 public void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look) 766 public void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look)
765 { 767 {
766 AgentMovementCompletePacket mov = (AgentMovementCompletePacket)PacketPool.Instance.GetPacket(PacketType.AgentMovementComplete); 768 AgentMovementCompletePacket mov = (AgentMovementCompletePacket)PacketPool.Instance.GetPacket(PacketType.AgentMovementComplete);
@@ -3476,6 +3478,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3476 3478
3477 public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry) 3479 public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry)
3478 { 3480 {
3481// m_log.DebugFormat(
3482// "[LLCLIENTVIEW]: Sending avatar appearance for {0} with {1} bytes to {2} {3}",
3483// agentID, textureEntry.Length, Name, AgentId);
3484
3479 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance); 3485 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance);
3480 // TODO: don't create new blocks if recycling an old packet 3486 // TODO: don't create new blocks if recycling an old packet
3481 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218]; 3487 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218];
@@ -3497,7 +3503,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3497 3503
3498 public void SendAnimations(UUID[] animations, int[] seqs, UUID sourceAgentId, UUID[] objectIDs) 3504 public void SendAnimations(UUID[] animations, int[] seqs, UUID sourceAgentId, UUID[] objectIDs)
3499 { 3505 {
3500 //m_log.DebugFormat("[CLIENT]: Sending animations to {0}", Name); 3506// m_log.DebugFormat("[LLCLIENTVIEW]: Sending animations for {0} to {1}", sourceAgentId, Name);
3501 3507
3502 AvatarAnimationPacket ani = (AvatarAnimationPacket)PacketPool.Instance.GetPacket(PacketType.AvatarAnimation); 3508 AvatarAnimationPacket ani = (AvatarAnimationPacket)PacketPool.Instance.GetPacket(PacketType.AvatarAnimation);
3503 // TODO: don't create new blocks if recycling an old packet 3509 // TODO: don't create new blocks if recycling an old packet
@@ -3532,6 +3538,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3532 /// </summary> 3538 /// </summary>
3533 public void SendAvatarDataImmediate(ISceneEntity avatar) 3539 public void SendAvatarDataImmediate(ISceneEntity avatar)
3534 { 3540 {
3541// m_log.DebugFormat(
3542// "[LLCLIENTVIEW]: Sending immediate object update for avatar {0} {1} to {2} {3}",
3543// avatar.Name, avatar.UUID, Name, AgentId);
3544
3535 ScenePresence presence = avatar as ScenePresence; 3545 ScenePresence presence = avatar as ScenePresence;
3536 if (presence == null) 3546 if (presence == null)
3537 return; 3547 return;
@@ -3541,7 +3551,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3541 3551
3542 objupdate.RegionData.RegionHandle = presence.RegionHandle; 3552 objupdate.RegionData.RegionHandle = presence.RegionHandle;
3543 objupdate.RegionData.TimeDilation = ushort.MaxValue; 3553 objupdate.RegionData.TimeDilation = ushort.MaxValue;
3544 3554
3545 objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; 3555 objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
3546 objupdate.ObjectData[0] = CreateAvatarUpdateBlock(presence); 3556 objupdate.ObjectData[0] = CreateAvatarUpdateBlock(presence);
3547 3557
@@ -3939,7 +3949,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3939 } 3949 }
3940 3950
3941 if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0) 3951 if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0)
3942 m_imageManager.ProcessImageQueue(m_udpServer.TextureSendLimit); 3952 ImageManager.ProcessImageQueue(m_udpServer.TextureSendLimit);
3943 } 3953 }
3944 3954
3945 public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID) 3955 public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID)
@@ -4473,6 +4483,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4473 OutPacket(packet, ThrottleOutPacketType.Task); 4483 OutPacket(packet, ThrottleOutPacketType.Task);
4474 } 4484 }
4475 4485
4486 public void SendTelehubInfo(UUID ObjectID, string ObjectName, Vector3 ObjectPos, Quaternion ObjectRot, List<Vector3> SpawnPoint)
4487 {
4488 TelehubInfoPacket packet = (TelehubInfoPacket)PacketPool.Instance.GetPacket(PacketType.TelehubInfo);
4489 packet.TelehubBlock.ObjectID = ObjectID;
4490 packet.TelehubBlock.ObjectName = Utils.StringToBytes(ObjectName);
4491 packet.TelehubBlock.TelehubPos = ObjectPos;
4492 packet.TelehubBlock.TelehubRot = ObjectRot;
4493
4494 packet.SpawnPointBlock = new TelehubInfoPacket.SpawnPointBlockBlock[SpawnPoint.Count];
4495 for (int n = 0; n < SpawnPoint.Count; n++)
4496 {
4497 packet.SpawnPointBlock[n] = new TelehubInfoPacket.SpawnPointBlockBlock{SpawnPointPos = SpawnPoint[n]};
4498 }
4499
4500 OutPacket(packet, ThrottleOutPacketType.Task);
4501 }
4502
4476 #endregion 4503 #endregion
4477 4504
4478 #region Land Data Sending Methods 4505 #region Land Data Sending Methods
@@ -7470,7 +7497,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7470 if ((ImageType)block.Type == ImageType.Baked) 7497 if ((ImageType)block.Type == ImageType.Baked)
7471 args.Priority *= 2.0f; 7498 args.Priority *= 2.0f;
7472 7499
7473 m_imageManager.EnqueueReq(args); 7500 ImageManager.EnqueueReq(args);
7474 } 7501 }
7475 7502
7476 return true; 7503 return true;
@@ -8911,7 +8938,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
8911 private bool HandleEstateOwnerMessage(IClientAPI sender, Packet Pack) 8938 private bool HandleEstateOwnerMessage(IClientAPI sender, Packet Pack)
8912 { 8939 {
8913 EstateOwnerMessagePacket messagePacket = (EstateOwnerMessagePacket)Pack; 8940 EstateOwnerMessagePacket messagePacket = (EstateOwnerMessagePacket)Pack;
8914 //m_log.Debug(messagePacket.ToString()); 8941 // m_log.InfoFormat("[LLCLIENTVIEW]: Packet: {0}", Utils.BytesToString(messagePacket.MethodData.Method));
8915 GodLandStatRequest handlerLandStatRequest; 8942 GodLandStatRequest handlerLandStatRequest;
8916 8943
8917 #region Packet Session and User Check 8944 #region Packet Session and User Check
@@ -9210,6 +9237,34 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9210 } 9237 }
9211 return true; 9238 return true;
9212 9239
9240 case "telehub":
9241 if (((Scene)m_scene).Permissions.CanIssueEstateCommand(AgentId, false))
9242 {
9243 UUID invoice = messagePacket.MethodData.Invoice;
9244 UUID SenderID = messagePacket.AgentData.AgentID;
9245 UInt32 param1 = 0u;
9246
9247 string command = (string)Utils.BytesToString(messagePacket.ParamList[0].Parameter);
9248
9249 if (command != "info ui")
9250 {
9251 try
9252 {
9253 param1 = Convert.ToUInt32(Utils.BytesToString(messagePacket.ParamList[1].Parameter));
9254 }
9255 catch
9256 {
9257 }
9258 }
9259
9260 EstateManageTelehub handlerEstateManageTelehub = OnEstateManageTelehub;
9261 if (handlerEstateManageTelehub != null)
9262 {
9263 handlerEstateManageTelehub(this, invoice, SenderID, command, param1);
9264 }
9265 }
9266 return true;
9267
9213 default: 9268 default:
9214 m_log.Error("EstateOwnerMessage: Unknown method requested\n" + messagePacket); 9269 m_log.Error("EstateOwnerMessage: Unknown method requested\n" + messagePacket);
9215 return true; 9270 return true;
@@ -9221,8 +9276,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9221 //lsrp.RequestData.ReportType; // 1 = colliders, 0 = scripts 9276 //lsrp.RequestData.ReportType; // 1 = colliders, 0 = scripts
9222 //lsrp.RequestData.RequestFlags; 9277 //lsrp.RequestData.RequestFlags;
9223 //lsrp.RequestData.Filter; 9278 //lsrp.RequestData.Filter;
9224
9225// return true;
9226 } 9279 }
9227 9280
9228 private bool HandleRequestRegionInfo(IClientAPI sender, Packet Pack) 9281 private bool HandleRequestRegionInfo(IClientAPI sender, Packet Pack)
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLImageManager.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLImageManager.cs
index e3a881f..073c357 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLImageManager.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLImageManager.cs
@@ -55,18 +55,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP
55 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 55 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
56 private bool m_shuttingdown; 56 private bool m_shuttingdown;
57 private AssetBase m_missingImage; 57 private AssetBase m_missingImage;
58 private LLClientView m_client; //Client we're assigned to 58 private IAssetService m_assetCache;
59 private IAssetService m_assetCache; //Asset Cache 59 private IJ2KDecoder m_j2kDecodeModule;
60 private IJ2KDecoder m_j2kDecodeModule; //Our J2K module 60
61 /// <summary>
62 /// Priority queue for determining which image to send first.
63 /// </summary>
61 private C5.IntervalHeap<J2KImage> m_priorityQueue = new C5.IntervalHeap<J2KImage>(10, new J2KImageComparer()); 64 private C5.IntervalHeap<J2KImage> m_priorityQueue = new C5.IntervalHeap<J2KImage>(10, new J2KImageComparer());
65
66 /// <summary>
67 /// Used to control thread access to the priority queue.
68 /// </summary>
62 private object m_syncRoot = new object(); 69 private object m_syncRoot = new object();
63 70
64 public LLClientView Client { get { return m_client; } } 71 /// <summary>
72 /// Client served by this image manager
73 /// </summary>
74 public IClientAPI Client { get; private set; }
75
65 public AssetBase MissingImage { get { return m_missingImage; } } 76 public AssetBase MissingImage { get { return m_missingImage; } }
66 77
67 public LLImageManager(LLClientView client, IAssetService pAssetCache, IJ2KDecoder pJ2kDecodeModule) 78 public LLImageManager(IClientAPI client, IAssetService pAssetCache, IJ2KDecoder pJ2kDecodeModule)
68 { 79 {
69 m_client = client; 80 Client = client;
70 m_assetCache = pAssetCache; 81 m_assetCache = pAssetCache;
71 82
72 if (pAssetCache != null) 83 if (pAssetCache != null)
@@ -84,7 +95,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
84 /// <param name="newRequest"></param> 95 /// <param name="newRequest"></param>
85 public void EnqueueReq(TextureRequestArgs newRequest) 96 public void EnqueueReq(TextureRequestArgs newRequest)
86 { 97 {
87 //Make sure we're not shutting down..
88 if (!m_shuttingdown) 98 if (!m_shuttingdown)
89 { 99 {
90 J2KImage imgrequest; 100 J2KImage imgrequest;
@@ -99,19 +109,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
99 { 109 {
100 //m_log.Debug("[TEX]: (CAN) ID=" + newRequest.RequestedAssetID); 110 //m_log.Debug("[TEX]: (CAN) ID=" + newRequest.RequestedAssetID);
101 111
102 try 112 try
103 { 113 {
104 lock (m_syncRoot) 114 lock (m_syncRoot)
105 m_priorityQueue.Delete(imgrequest.PriorityQueueHandle); 115 m_priorityQueue.Delete(imgrequest.PriorityQueueHandle);
106 } 116 }
107 catch (Exception) { } 117 catch (Exception) { }
108 } 118 }
109 else 119 else
110 { 120 {
111 //m_log.DebugFormat("[TEX]: (UPD) ID={0}: D={1}, S={2}, P={3}", 121// m_log.DebugFormat(
112 // newRequest.RequestedAssetID, newRequest.DiscardLevel, newRequest.PacketNumber, newRequest.Priority); 122// "[LL IMAGE MANAGER]: Received duplicate of existing request for {0}, start packet {1} from {2}",
123// newRequest.RequestedAssetID, newRequest.PacketNumber, m_client.Name);
124
125// m_log.DebugFormat("[TEX]: (UPD) ID={0}: D={1}, S={2}, P={3}",
126// newRequest.RequestedAssetID, newRequest.DiscardLevel, newRequest.PacketNumber, newRequest.Priority);
113 127
114 //Check the packet sequence to make sure this isn't older than 128 //Check the packet sequence to make sure this isn't older than
115 //one we've already received 129 //one we've already received
116 if (newRequest.requestSequence > imgrequest.LastSequence) 130 if (newRequest.requestSequence > imgrequest.LastSequence)
117 { 131 {
@@ -126,11 +140,34 @@ namespace OpenSim.Region.ClientStack.LindenUDP
126 140
127 //Update the requested priority 141 //Update the requested priority
128 imgrequest.Priority = newRequest.Priority; 142 imgrequest.Priority = newRequest.Priority;
143
129 UpdateImageInQueue(imgrequest); 144 UpdateImageInQueue(imgrequest);
130 145
131 //Run an update
132 imgrequest.RunUpdate(); 146 imgrequest.RunUpdate();
147
148// J2KImage imgrequest2 = new J2KImage(this);
149// imgrequest2.J2KDecoder = m_j2kDecodeModule;
150// imgrequest2.AssetService = m_assetCache;
151// imgrequest2.AgentID = m_client.AgentId;
152// imgrequest2.InventoryAccessModule = m_client.Scene.RequestModuleInterface<IInventoryAccessModule>();
153// imgrequest2.DiscardLevel = newRequest.DiscardLevel;
154// imgrequest2.StartPacket = Math.Max(1, newRequest.PacketNumber);
155// imgrequest2.Priority = newRequest.Priority;
156// imgrequest2.TextureID = newRequest.RequestedAssetID;
157// imgrequest2.Priority = newRequest.Priority;
158//
159// //Add this download to the priority queue
160// AddImageToQueue(imgrequest2);
161//
162// imgrequest2.RunUpdate();
163
133 } 164 }
165// else
166// {
167// m_log.DebugFormat(
168// "[LL IMAGE MANAGER]: Ignoring duplicate of existing request for {0} (sequence {1}) from {2} as its request sequence {3} is not greater",
169// newRequest.RequestedAssetID, imgrequest.LastSequence, m_client.Name, newRequest.requestSequence);
170// }
134 } 171 }
135 } 172 }
136 else 173 else
@@ -142,14 +179,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
142 } 179 }
143 else 180 else
144 { 181 {
182// m_log.DebugFormat(
183// "[LL IMAGE MANAGER]: Received request for {0}, start packet {1} from {2}",
184// newRequest.RequestedAssetID, newRequest.PacketNumber, m_client.Name);
185
145 //m_log.DebugFormat("[TEX]: (NEW) ID={0}: D={1}, S={2}, P={3}", 186 //m_log.DebugFormat("[TEX]: (NEW) ID={0}: D={1}, S={2}, P={3}",
146 // newRequest.RequestedAssetID, newRequest.DiscardLevel, newRequest.PacketNumber, newRequest.Priority); 187 // newRequest.RequestedAssetID, newRequest.DiscardLevel, newRequest.PacketNumber, newRequest.Priority);
147 188
148 imgrequest = new J2KImage(this); 189 imgrequest = new J2KImage(this);
149 imgrequest.J2KDecoder = m_j2kDecodeModule; 190 imgrequest.J2KDecoder = m_j2kDecodeModule;
150 imgrequest.AssetService = m_assetCache; 191 imgrequest.AssetService = m_assetCache;
151 imgrequest.AgentID = m_client.AgentId; 192 imgrequest.AgentID = Client.AgentId;
152 imgrequest.InventoryAccessModule = m_client.Scene.RequestModuleInterface<IInventoryAccessModule>(); 193 imgrequest.InventoryAccessModule = Client.Scene.RequestModuleInterface<IInventoryAccessModule>();
153 imgrequest.DiscardLevel = newRequest.DiscardLevel; 194 imgrequest.DiscardLevel = newRequest.DiscardLevel;
154 imgrequest.StartPacket = Math.Max(1, newRequest.PacketNumber); 195 imgrequest.StartPacket = Math.Max(1, newRequest.PacketNumber);
155 imgrequest.Priority = newRequest.Priority; 196 imgrequest.Priority = newRequest.Priority;
@@ -159,7 +200,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
159 //Add this download to the priority queue 200 //Add this download to the priority queue
160 AddImageToQueue(imgrequest); 201 AddImageToQueue(imgrequest);
161 202
162 //Run an update
163 imgrequest.RunUpdate(); 203 imgrequest.RunUpdate();
164 } 204 }
165 } 205 }
@@ -176,12 +216,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
176 216
177 // If null was returned, the texture priority queue is currently empty 217 // If null was returned, the texture priority queue is currently empty
178 if (image == null) 218 if (image == null)
179 return false; 219 break;
180 220
181 if (image.IsDecoded) 221 if (image.IsDecoded)
182 { 222 {
183 int sent; 223 int sent;
184 bool imageDone = image.SendPackets(m_client, packetsToSend - packetsSent, out sent); 224 bool imageDone = image.SendPackets(Client, packetsToSend - packetsSent, out sent);
185 packetsSent += sent; 225 packetsSent += sent;
186 226
187 // If the send is complete, destroy any knowledge of this transfer 227 // If the send is complete, destroy any knowledge of this transfer
@@ -194,10 +234,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
194 // written. Undecoded textures should not be going into the priority 234 // written. Undecoded textures should not be going into the priority
195 // queue, because a high priority undecoded texture will clog up the 235 // queue, because a high priority undecoded texture will clog up the
196 // pipeline for a client 236 // pipeline for a client
197 return true; 237// m_log.DebugFormat(
238// "[LL IMAGE MANAGER]: Exiting image queue processing early on encountering undecoded image {0}",
239// image.TextureID);
240
241 break;
198 } 242 }
199 } 243 }
200 244
245// if (packetsSent != 0)
246// m_log.DebugFormat("[LL IMAGE MANAGER]: Processed {0} packets from image queue", packetsSent);
247
201 return m_priorityQueue.Count > 0; 248 return m_priorityQueue.Count > 0;
202 } 249 }
203 250
@@ -209,6 +256,36 @@ namespace OpenSim.Region.ClientStack.LindenUDP
209 m_shuttingdown = true; 256 m_shuttingdown = true;
210 } 257 }
211 258
259 /// <summary>
260 /// Clear the image queue.
261 /// </summary>
262 /// <returns>The number of requests cleared.</returns>
263 public int ClearImageQueue()
264 {
265 int requestsDeleted;
266
267 lock (m_priorityQueue)
268 {
269 requestsDeleted = m_priorityQueue.Count;
270
271 // Surprisingly, there doesn't seem to be a clear method at this time.
272 while (!m_priorityQueue.IsEmpty)
273 m_priorityQueue.DeleteMax();
274 }
275
276 return requestsDeleted;
277 }
278
279 /// <summary>
280 /// Returns an array containing all the images in the queue.
281 /// </summary>
282 /// <returns></returns>
283 public J2KImage[] GetImages()
284 {
285 lock (m_priorityQueue)
286 return m_priorityQueue.ToArray();
287 }
288
212 #region Priority Queue Helpers 289 #region Priority Queue Helpers
213 290
214 private J2KImage GetHighestPriorityImage() 291 private J2KImage GetHighestPriorityImage()
@@ -219,7 +296,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
219 { 296 {
220 if (m_priorityQueue.Count > 0) 297 if (m_priorityQueue.Count > 0)
221 { 298 {
222 try { image = m_priorityQueue.FindMax(); } 299 try
300 {
301 image = m_priorityQueue.FindMax();
302 }
223 catch (Exception) { } 303 catch (Exception) { }
224 } 304 }
225 } 305 }
@@ -232,7 +312,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
232 312
233 lock (m_syncRoot) 313 lock (m_syncRoot)
234 { 314 {
235 try { m_priorityQueue.Add(ref image.PriorityQueueHandle, image); } 315 try
316 {
317 m_priorityQueue.Add(ref image.PriorityQueueHandle, image);
318 }
236 catch (Exception) { } 319 catch (Exception) { }
237 } 320 }
238 } 321 }
@@ -241,7 +324,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
241 { 324 {
242 lock (m_syncRoot) 325 lock (m_syncRoot)
243 { 326 {
244 try { m_priorityQueue.Delete(image.PriorityQueueHandle); } 327 try
328 {
329 m_priorityQueue.Delete(image.PriorityQueueHandle);
330 }
245 catch (Exception) { } 331 catch (Exception) { }
246 } 332 }
247 } 333 }
@@ -250,7 +336,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
250 { 336 {
251 lock (m_syncRoot) 337 lock (m_syncRoot)
252 { 338 {
253 try { m_priorityQueue.Replace(image.PriorityQueueHandle, image); } 339 try
340 {
341 m_priorityQueue.Replace(image.PriorityQueueHandle, image);
342 }
254 catch (Exception) 343 catch (Exception)
255 { 344 {
256 image.PriorityQueueHandle = null; 345 image.PriorityQueueHandle = null;
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 5610c09..7b1aa2c 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -492,6 +492,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
492 if ((Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > 1000 * 60) 492 if ((Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > 1000 * 60)
493 { 493 {
494 m_log.Warn("[LLUDPSERVER]: Ack timeout, disconnecting " + udpClient.AgentID); 494 m_log.Warn("[LLUDPSERVER]: Ack timeout, disconnecting " + udpClient.AgentID);
495 StatsManager.SimExtraStats.AddAbnormalClientThreadTermination();
495 496
496 RemoveClient(udpClient); 497 RemoveClient(udpClient);
497 return; 498 return;
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs
new file mode 100644
index 0000000..1b68d68
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs
@@ -0,0 +1,160 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.IO;
30using System.Net;
31using System.Reflection;
32using log4net.Config;
33using Nini.Config;
34using NUnit.Framework;
35using OpenMetaverse;
36using OpenMetaverse.Packets;
37using OpenSim.Framework;
38using OpenSim.Region.CoreModules.Agent.TextureSender;
39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Tests.Common;
41using OpenSim.Tests.Common.Mock;
42
43namespace OpenSim.Region.ClientStack.LindenUDP.Tests
44{
45 [TestFixture]
46 public class LLImageManagerTests
47 {
48 private AssetBase m_testImageAsset;
49 private Scene scene;
50 private LLImageManager llim;
51 private TestClient tc;
52
53 [TestFixtureSetUp]
54 public void FixtureInit()
55 {
56 using (
57 Stream resource
58 = GetType().Assembly.GetManifestResourceStream(
59 "OpenSim.Region.ClientStack.LindenUDP.Tests.Resources.4-tile2.jp2"))
60 {
61 using (BinaryReader br = new BinaryReader(resource))
62 {
63 m_testImageAsset
64 = new AssetBase(
65 TestHelpers.ParseTail(0x1),
66 "Test Image",
67 (sbyte)AssetType.Texture,
68 TestHelpers.ParseTail(0x2).ToString());
69
70 m_testImageAsset.Data = br.ReadBytes(99999999);
71 }
72 }
73 }
74
75 [SetUp]
76 public void SetUp()
77 {
78 UUID userId = TestHelpers.ParseTail(0x3);
79
80 J2KDecoderModule j2kdm = new J2KDecoderModule();
81
82 scene = SceneHelpers.SetupScene();
83 SceneHelpers.SetupSceneModules(scene, j2kdm);
84
85 tc = new TestClient(SceneHelpers.GenerateAgentData(userId), scene);
86 llim = new LLImageManager(tc, scene.AssetService, j2kdm);
87 }
88
89 [Test]
90 public void TestSendImage()
91 {
92 TestHelpers.InMethod();
93// XmlConfigurator.Configure();
94
95 scene.AssetService.Store(m_testImageAsset);
96
97 TextureRequestArgs args = new TextureRequestArgs();
98 args.RequestedAssetID = m_testImageAsset.FullID;
99 args.DiscardLevel = 0;
100 args.PacketNumber = 1;
101 args.Priority = 5;
102 args.requestSequence = 1;
103
104 llim.EnqueueReq(args);
105 llim.ProcessImageQueue(20);
106
107 Assert.That(tc.SentImageDataPackets.Count, Is.EqualTo(1));
108 }
109
110 [Test]
111 public void TestDiscardImage()
112 {
113 TestHelpers.InMethod();
114// XmlConfigurator.Configure();
115
116 scene.AssetService.Store(m_testImageAsset);
117
118 TextureRequestArgs args = new TextureRequestArgs();
119 args.RequestedAssetID = m_testImageAsset.FullID;
120 args.DiscardLevel = 0;
121 args.PacketNumber = 1;
122 args.Priority = 5;
123 args.requestSequence = 1;
124 llim.EnqueueReq(args);
125
126 // Now create a discard request
127 TextureRequestArgs discardArgs = new TextureRequestArgs();
128 discardArgs.RequestedAssetID = m_testImageAsset.FullID;
129 discardArgs.DiscardLevel = -1;
130 discardArgs.PacketNumber = 1;
131 discardArgs.Priority = 0;
132 discardArgs.requestSequence = 2;
133 llim.EnqueueReq(discardArgs);
134
135 llim.ProcessImageQueue(20);
136
137 Assert.That(tc.SentImageDataPackets.Count, Is.EqualTo(0));
138 }
139
140 [Test]
141 public void TestMissingImage()
142 {
143 TestHelpers.InMethod();
144// XmlConfigurator.Configure();
145
146 TextureRequestArgs args = new TextureRequestArgs();
147 args.RequestedAssetID = m_testImageAsset.FullID;
148 args.DiscardLevel = 0;
149 args.PacketNumber = 1;
150 args.Priority = 5;
151 args.requestSequence = 1;
152
153 llim.EnqueueReq(args);
154 llim.ProcessImageQueue(20);
155
156 Assert.That(tc.SentImageDataPackets.Count, Is.EqualTo(0));
157 Assert.That(tc.SentImageNotInDatabasePackets.Count, Is.EqualTo(1));
158 }
159 }
160} \ No newline at end of file
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/Resources/4-tile2.jp2 b/OpenSim/Region/ClientStack/Linden/UDP/Tests/Resources/4-tile2.jp2
new file mode 100644
index 0000000..8c63104
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/Resources/4-tile2.jp2
Binary files differ
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
index a28d5d7..95e3aec 100644
--- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
+++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs
@@ -246,7 +246,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
246 246
247 if (mm != null) 247 if (mm != null)
248 { 248 {
249 if (!mm.UploadCovered(remoteClient, mm.UploadCharge)) 249 if (!mm.UploadCovered(remoteClient.AgentId, mm.UploadCharge))
250 { 250 {
251 remoteClient.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false); 251 remoteClient.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false);
252 return; 252 return;
diff --git a/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs b/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs
index 7dd9087..a1a2501 100644
--- a/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs
+++ b/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs
@@ -103,6 +103,10 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
103 // If it's cached, return the cached results 103 // If it's cached, return the cached results
104 if (m_decodedCache.TryGetValue(assetID, out result)) 104 if (m_decodedCache.TryGetValue(assetID, out result))
105 { 105 {
106// m_log.DebugFormat(
107// "[J2KDecoderModule]: Returning existing cached {0} layers j2k decode for {1}",
108// result.Length, assetID);
109
106 callback(assetID, result); 110 callback(assetID, result);
107 } 111 }
108 else 112 else
@@ -129,18 +133,20 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
129 133
130 // Do Decode! 134 // Do Decode!
131 if (decode) 135 if (decode)
132 DoJ2KDecode(assetID, j2kData); 136 Decode(assetID, j2kData);
133 } 137 }
134 } 138 }
135 139
136 /// <summary> 140 public bool Decode(UUID assetID, byte[] j2kData)
137 /// Provides a synchronous decode so that caller can be assured that this executes before the next line
138 /// </summary>
139 /// <param name="assetID"></param>
140 /// <param name="j2kData"></param>
141 public void Decode(UUID assetID, byte[] j2kData)
142 { 141 {
143 DoJ2KDecode(assetID, j2kData); 142 OpenJPEG.J2KLayerInfo[] layers;
143 int components;
144 return Decode(assetID, j2kData, out layers, out components);
145 }
146
147 public bool Decode(UUID assetID, byte[] j2kData, out OpenJPEG.J2KLayerInfo[] layers, out int components)
148 {
149 return DoJ2KDecode(assetID, j2kData, out layers, out components);
144 } 150 }
145 151
146 #endregion IJ2KDecoder 152 #endregion IJ2KDecoder
@@ -150,14 +156,21 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
150 /// </summary> 156 /// </summary>
151 /// <param name="assetID">UUID of Asset</param> 157 /// <param name="assetID">UUID of Asset</param>
152 /// <param name="j2kData">JPEG2000 data</param> 158 /// <param name="j2kData">JPEG2000 data</param>
153 private void DoJ2KDecode(UUID assetID, byte[] j2kData) 159 /// <param name="layers">layer data</param>
160 /// <param name="components">number of components</param>
161 /// <returns>true if decode was successful. false otherwise.</returns>
162 private bool DoJ2KDecode(UUID assetID, byte[] j2kData, out OpenJPEG.J2KLayerInfo[] layers, out int components)
154 { 163 {
155// m_log.DebugFormat( 164// m_log.DebugFormat(
156// "[J2KDecoderModule]: Doing J2K decoding of {0} bytes for asset {1}", j2kData.Length, assetID); 165// "[J2KDecoderModule]: Doing J2K decoding of {0} bytes for asset {1}", j2kData.Length, assetID);
157 166
167 bool decodedSuccessfully = true;
168
158 //int DecodeTime = 0; 169 //int DecodeTime = 0;
159 //DecodeTime = Environment.TickCount; 170 //DecodeTime = Environment.TickCount;
160 OpenJPEG.J2KLayerInfo[] layers; 171
172 // We don't get this from CSJ2K. Is it relevant?
173 components = 0;
161 174
162 if (!TryLoadCacheForAsset(assetID, out layers)) 175 if (!TryLoadCacheForAsset(assetID, out layers))
163 { 176 {
@@ -192,14 +205,15 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
192 catch (Exception ex) 205 catch (Exception ex)
193 { 206 {
194 m_log.Warn("[J2KDecoderModule]: CSJ2K threw an exception decoding texture " + assetID + ": " + ex.Message); 207 m_log.Warn("[J2KDecoderModule]: CSJ2K threw an exception decoding texture " + assetID + ": " + ex.Message);
208 decodedSuccessfully = false;
195 } 209 }
196 } 210 }
197 else 211 else
198 { 212 {
199 int components;
200 if (!OpenJPEG.DecodeLayerBoundaries(j2kData, out layers, out components)) 213 if (!OpenJPEG.DecodeLayerBoundaries(j2kData, out layers, out components))
201 { 214 {
202 m_log.Warn("[J2KDecoderModule]: OpenJPEG failed to decode texture " + assetID); 215 m_log.Warn("[J2KDecoderModule]: OpenJPEG failed to decode texture " + assetID);
216 decodedSuccessfully = false;
203 } 217 }
204 } 218 }
205 219
@@ -208,6 +222,7 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
208 m_log.Warn("[J2KDecoderModule]: Failed to decode layer data for texture " + assetID + ", guessing sane defaults"); 222 m_log.Warn("[J2KDecoderModule]: Failed to decode layer data for texture " + assetID + ", guessing sane defaults");
209 // Layer decoding completely failed. Guess at sane defaults for the layer boundaries 223 // Layer decoding completely failed. Guess at sane defaults for the layer boundaries
210 layers = CreateDefaultLayers(j2kData.Length); 224 layers = CreateDefaultLayers(j2kData.Length);
225 decodedSuccessfully = false;
211 } 226 }
212 227
213 // Cache Decoded layers 228 // Cache Decoded layers
@@ -227,6 +242,8 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
227 m_notifyList.Remove(assetID); 242 m_notifyList.Remove(assetID);
228 } 243 }
229 } 244 }
245
246 return decodedSuccessfully;
230 } 247 }
231 248
232 private OpenJPEG.J2KLayerInfo[] CreateDefaultLayers(int j2kLength) 249 private OpenJPEG.J2KLayerInfo[] CreateDefaultLayers(int j2kLength)
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index 280fdc7..7086e6c 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -148,7 +148,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
148 } 148 }
149 } 149 }
150 150
151 public void SaveChangedAttachments(IScenePresence sp) 151 public void SaveChangedAttachments(IScenePresence sp, bool saveAllScripted)
152 { 152 {
153// m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name); 153// m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name);
154 154
@@ -157,13 +157,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
157 157
158 foreach (SceneObjectGroup grp in sp.GetAttachments()) 158 foreach (SceneObjectGroup grp in sp.GetAttachments())
159 { 159 {
160// if (grp.HasGroupChanged) // Resizer scripts? 160 grp.IsAttachment = false;
161// { 161 grp.AbsolutePosition = grp.RootPart.AttachedPos;
162 grp.IsAttachment = false; 162 UpdateKnownItem(sp, grp, saveAllScripted);
163 grp.AbsolutePosition = grp.RootPart.AttachedPos; 163 grp.IsAttachment = true;
164 UpdateKnownItem(sp, grp);
165 grp.IsAttachment = true;
166// }
167 } 164 }
168 } 165 }
169 166
@@ -460,9 +457,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
460 /// </remarks> 457 /// </remarks>
461 /// <param name="sp"></param> 458 /// <param name="sp"></param>
462 /// <param name="grp"></param> 459 /// <param name="grp"></param>
463 private void UpdateKnownItem(IScenePresence sp, SceneObjectGroup grp) 460 private void UpdateKnownItem(IScenePresence sp, SceneObjectGroup grp, bool saveAllScripted)
464 { 461 {
465 if (grp.HasGroupChanged || grp.ContainsScripts()) 462 // Saving attachments for NPCs messes them up for the real owner!
463 INPCModule module = m_scene.RequestModuleInterface<INPCModule>();
464 if (module != null)
465 {
466 if (module.IsNPC(sp.UUID, m_scene))
467 return;
468 }
469
470 if (grp.HasGroupChanged || (saveAllScripted && grp.ContainsScripts()))
466 { 471 {
467 m_log.DebugFormat( 472 m_log.DebugFormat(
468 "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}", 473 "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}",
@@ -495,6 +500,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
495 if (sp.ControllingClient != null) 500 if (sp.ControllingClient != null)
496 sp.ControllingClient.SendInventoryItemCreateUpdate(item, 0); 501 sp.ControllingClient.SendInventoryItemCreateUpdate(item, 0);
497 } 502 }
503 grp.HasGroupChanged = false; // Prevent it being saved over and over
498 } 504 }
499 else 505 else
500 { 506 {
@@ -688,7 +694,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
688 group.IsAttachment = false; 694 group.IsAttachment = false;
689 group.AbsolutePosition = group.RootPart.AttachedPos; 695 group.AbsolutePosition = group.RootPart.AttachedPos;
690 696
691 UpdateKnownItem(sp, group); 697 UpdateKnownItem(sp, group, true);
692 m_scene.DeleteSceneObject(group, false); 698 m_scene.DeleteSceneObject(group, false);
693 699
694 return; 700 return;
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
index e8aee3e..8d503bd 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
@@ -149,14 +149,15 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
149 // Process the baked texture array 149 // Process the baked texture array
150 if (textureEntry != null) 150 if (textureEntry != null)
151 { 151 {
152 m_log.InfoFormat("[AVFACTORY]: received texture update for {0}", sp.UUID); 152 m_log.InfoFormat("[AVFACTORY]: Received texture update for {0} {1}", sp.Name, sp.UUID);
153 153
154// WriteBakedTexturesReport(sp, m_log.DebugFormat); 154// WriteBakedTexturesReport(sp, m_log.DebugFormat);
155 155
156 changed = sp.Appearance.SetTextureEntries(textureEntry) || changed; 156 changed = sp.Appearance.SetTextureEntries(textureEntry) || changed;
157 157
158// WriteBakedTexturesReport(sp, m_log.DebugFormat); 158// WriteBakedTexturesReport(sp, m_log.DebugFormat);
159 ValidateBakedTextureCache(sp, false); 159 if (!ValidateBakedTextureCache(sp))
160 RequestRebake(sp, true);
160 161
161 // This appears to be set only in the final stage of the appearance 162 // This appears to be set only in the final stage of the appearance
162 // update transaction. In theory, we should be able to do an immediate 163 // update transaction. In theory, we should be able to do an immediate
@@ -251,15 +252,6 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
251 } 252 }
252 253
253 /// <summary> 254 /// <summary>
254 /// Check for the existence of the baked texture assets.
255 /// </summary>
256 /// <param name="sp"></param>
257 public bool ValidateBakedTextureCache(IScenePresence sp)
258 {
259 return ValidateBakedTextureCache(sp, true);
260 }
261
262 /// <summary>
263 /// Queue up a request to send appearance. 255 /// Queue up a request to send appearance.
264 /// </summary> 256 /// </summary>
265 /// <remarks> 257 /// <remarks>
@@ -292,17 +284,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
292 } 284 }
293 } 285 }
294 286
295 #endregion 287 public bool ValidateBakedTextureCache(IScenePresence sp)
296
297 #region AvatarFactoryModule private methods
298
299 /// <summary>
300 /// Check for the existence of the baked texture assets. Request a rebake
301 /// unless checkonly is true.
302 /// </summary>
303 /// <param name="client"></param>
304 /// <param name="checkonly"></param>
305 private bool ValidateBakedTextureCache(IScenePresence sp, bool checkonly)
306 { 288 {
307 bool defonly = true; // are we only using default textures 289 bool defonly = true; // are we only using default textures
308 290
@@ -330,24 +312,66 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
330 defonly = false; // found a non-default texture reference 312 defonly = false; // found a non-default texture reference
331 313
332 if (m_scene.AssetService.Get(face.TextureID.ToString()) == null) 314 if (m_scene.AssetService.Get(face.TextureID.ToString()) == null)
333 { 315 return false;
334 if (checkonly) 316 }
335 return false; 317
318 m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0} {1}", sp.Name, sp.UUID);
319
320 // If we only found default textures, then the appearance is not cached
321 return (defonly ? false : true);
322 }
323
324 public int RequestRebake(IScenePresence sp, bool missingTexturesOnly)
325 {
326 int texturesRebaked = 0;
327
328 for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
329 {
330 int idx = AvatarAppearance.BAKE_INDICES[i];
331 Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx];
332
333 // if there is no texture entry, skip it
334 if (face == null)
335 continue;
336
337// m_log.DebugFormat(
338// "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}",
339// face.TextureID, idx, client.Name, client.AgentId);
340
341 // if the texture is one of the "defaults" then skip it
342 // this should probably be more intelligent (skirt texture doesnt matter
343 // if the avatar isnt wearing a skirt) but if any of the main baked
344 // textures is default then the rest should be as well
345 if (face.TextureID == UUID.Zero || face.TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE)
346 continue;
336 347
348 if (missingTexturesOnly)
349 {
350 if (m_scene.AssetService.Get(face.TextureID.ToString()) != null)
351 continue;
352 else
353 m_log.DebugFormat(
354 "[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.",
355 face.TextureID, idx, sp.Name);
356 }
357 else
358 {
337 m_log.DebugFormat( 359 m_log.DebugFormat(
338 "[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.", 360 "[AVFACTORY]: Requesting rebake of {0} ({1}) for {2}.",
339 face.TextureID, idx, sp.Name); 361 face.TextureID, idx, sp.Name);
340
341 sp.ControllingClient.SendRebakeAvatarTextures(face.TextureID);
342 } 362 }
343 }
344 363
345 m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0}", sp.UUID); 364 texturesRebaked++;
365 sp.ControllingClient.SendRebakeAvatarTextures(face.TextureID);
366 }
346 367
347 // If we only found default textures, then the appearance is not cached 368 return texturesRebaked;
348 return (defonly ? false : true);
349 } 369 }
350 370
371 #endregion
372
373 #region AvatarFactoryModule private methods
374
351 private Dictionary<BakeType, Primitive.TextureEntryFace> GetBakedTextureFaces(ScenePresence sp) 375 private Dictionary<BakeType, Primitive.TextureEntryFace> GetBakedTextureFaces(ScenePresence sp)
352 { 376 {
353 if (sp.IsChildAgent) 377 if (sp.IsChildAgent)
@@ -602,4 +626,4 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
602 outputAction("{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "corrupt"); 626 outputAction("{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "corrupt");
603 } 627 }
604 } 628 }
605} 629} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
index a77646c..9c53fc4 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
@@ -496,13 +496,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
496 string agentFriendService = string.Empty; 496 string agentFriendService = string.Empty;
497 string friendFriendService = string.Empty; 497 string friendFriendService = string.Empty;
498 498
499 if (agentIsLocal) 499 if (agentClient != null)
500 { 500 {
501 agentClientCircuit = ((Scene)(agentClient.Scene)).AuthenticateHandler.GetAgentCircuitData(agentClient.CircuitCode); 501 agentClientCircuit = ((Scene)(agentClient.Scene)).AuthenticateHandler.GetAgentCircuitData(agentClient.CircuitCode);
502 agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit); 502 agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
503 agentFriendService = agentClientCircuit.ServiceURLs["FriendsServerURI"].ToString(); 503 agentFriendService = agentClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
504 } 504 }
505 if (friendIsLocal) 505 if (friendClient != null)
506 { 506 {
507 friendClientCircuit = ((Scene)(friendClient.Scene)).AuthenticateHandler.GetAgentCircuitData(friendClient.CircuitCode); 507 friendClientCircuit = ((Scene)(friendClient.Scene)).AuthenticateHandler.GetAgentCircuitData(friendClient.CircuitCode);
508 friendUUI = Util.ProduceUserUniversalIdentifier(friendClientCircuit); 508 friendUUI = Util.ProduceUserUniversalIdentifier(friendClientCircuit);
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
index 6b24718..ee10d04 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
@@ -493,7 +493,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
493 } 493 }
494 else 494 else
495 { 495 {
496 sceneObjects.Add(SceneObjectSerializer.FromOriginalXmlFormat(xmlData)); 496 SceneObjectGroup deserializedObject = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
497
498 if (deserializedObject != null)
499 sceneObjects.Add(deserializedObject);
497 } 500 }
498 501
499 foreach (SceneObjectGroup sog in sceneObjects) 502 foreach (SceneObjectGroup sog in sceneObjects)
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
index e0b02aa..150d913 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
@@ -122,12 +122,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
122 122
123 scene.AddCommand( 123 scene.AddCommand(
124 this, "save iar", 124 this, "save iar",
125 "save iar [--p|-profile=<url>] [--noassets] <first> <last> <inventory path> <password> [<IAR path>] [--v|-verbose]", 125 "save iar [-h|--home=<url>] [--noassets] <first> <last> <inventory path> <password> [<IAR path>] [--v|-verbose]",
126 "Save user inventory archive (IAR).", 126 "Save user inventory archive (IAR).",
127 "<first> is the user's first name." + Environment.NewLine 127 "<first> is the user's first name." + Environment.NewLine
128 + "<last> is the user's last name." + Environment.NewLine 128 + "<last> is the user's last name." + Environment.NewLine
129 + "<inventory path> is the path inside the user's inventory for the folder/item to be saved." + Environment.NewLine 129 + "<inventory path> is the path inside the user's inventory for the folder/item to be saved." + Environment.NewLine
130 + "-p|--profile=<url> adds the url of the profile service to the saved user information." + Environment.NewLine 130 + "-h|--home=<url> adds the url of the profile service to the saved user information." + Environment.NewLine
131 + "-c|--creators preserves information about foreign creators." + Environment.NewLine 131 + "-c|--creators preserves information about foreign creators." + Environment.NewLine
132 + "-v|--verbose extra debug messages." + Environment.NewLine 132 + "-v|--verbose extra debug messages." + Environment.NewLine
133 + "--noassets stops assets being saved to the IAR." 133 + "--noassets stops assets being saved to the IAR."
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index cbef6ce..928bcd0 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -208,8 +208,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
208 208
209 foreach (SceneObjectGroup grp in sp.GetAttachments()) 209 foreach (SceneObjectGroup grp in sp.GetAttachments())
210 { 210 {
211 if (grp.IsDeleted) 211 sp.Scene.EventManager.TriggerOnScriptChangedEvent(grp.LocalId, (uint)Changed.TELEPORT);
212 sp.Scene.EventManager.TriggerOnScriptChangedEvent(grp.LocalId, (uint)Changed.TELEPORT);
213 } 212 }
214 } 213 }
215 else // Another region possibly in another simulator 214 else // Another region possibly in another simulator
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
index 8d41728..38a7805 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
@@ -348,7 +348,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
348 348
349 region.ExternalHostName = uri.Host; 349 region.ExternalHostName = uri.Host;
350 region.HttpPort = (uint)uri.Port; 350 region.HttpPort = (uint)uri.Port;
351 region.ServerURI = uri.ToString(); 351 region.ServerURI = aCircuit.ServiceURLs["HomeURI"].ToString();
352 region.RegionName = string.Empty; 352 region.RegionName = string.Empty;
353 region.InternalEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse("0.0.0.0"), (int)0); 353 region.InternalEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse("0.0.0.0"), (int)0);
354 return region; 354 return region;
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
index d20c9eb..eaadc1b 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
@@ -55,16 +55,16 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
55// private Dictionary<string, InventoryClient> m_inventoryServers = new Dictionary<string, InventoryClient>(); 55// private Dictionary<string, InventoryClient> m_inventoryServers = new Dictionary<string, InventoryClient>();
56 56
57 private Scene m_scene; 57 private Scene m_scene;
58 private string m_ProfileServerURI; 58 private string m_HomeURI;
59 59
60 #endregion 60 #endregion
61 61
62 #region Constructor 62 #region Constructor
63 63
64 public HGAssetMapper(Scene scene, string profileURL) 64 public HGAssetMapper(Scene scene, string homeURL)
65 { 65 {
66 m_scene = scene; 66 m_scene = scene;
67 m_ProfileServerURI = profileURL; 67 m_HomeURI = homeURL;
68 } 68 }
69 69
70 #endregion 70 #endregion
@@ -150,7 +150,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
150 UUID.TryParse(meta.CreatorID, out uuid); 150 UUID.TryParse(meta.CreatorID, out uuid);
151 UserAccount creator = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, uuid); 151 UserAccount creator = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, uuid);
152 if (creator != null) 152 if (creator != null)
153 meta.CreatorID = m_ProfileServerURI + "/" + meta.CreatorID + ";" + creator.FirstName + " " + creator.LastName; 153 meta.CreatorID = m_HomeURI + ";" + creator.FirstName + " " + creator.LastName;
154 } 154 }
155 } 155 }
156 156
@@ -193,7 +193,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
193 if (!hasCreatorData && creator != null) 193 if (!hasCreatorData && creator != null)
194 { 194 {
195 XmlElement creatorData = doc.CreateElement("CreatorData"); 195 XmlElement creatorData = doc.CreateElement("CreatorData");
196 creatorData.InnerText = m_ProfileServerURI + "/" + creator.PrincipalID + ";" + creator.FirstName + " " + creator.LastName; 196 creatorData.InnerText = m_HomeURI + ";" + creator.FirstName + " " + creator.LastName;
197 sop.AppendChild(creatorData); 197 sop.AppendChild(creatorData);
198 } 198 }
199 } 199 }
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
index bf24ebc..0c4ff7f 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
@@ -54,7 +54,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
54 get { return m_assMapper; } 54 get { return m_assMapper; }
55 } 55 }
56 56
57 private string m_ProfileServerURI; 57 private string m_HomeURI;
58 private bool m_OutboundPermission; 58 private bool m_OutboundPermission;
59 private string m_ThisGatekeeper; 59 private string m_ThisGatekeeper;
60 60
@@ -84,7 +84,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
84 IConfig thisModuleConfig = source.Configs["HGInventoryAccessModule"]; 84 IConfig thisModuleConfig = source.Configs["HGInventoryAccessModule"];
85 if (thisModuleConfig != null) 85 if (thisModuleConfig != null)
86 { 86 {
87 m_ProfileServerURI = thisModuleConfig.GetString("ProfileServerURI", string.Empty); 87 // legacy configuration [obsolete]
88 m_HomeURI = thisModuleConfig.GetString("ProfileServerURI", string.Empty);
89 // preferred
90 m_HomeURI = thisModuleConfig.GetString("HomeURI", m_HomeURI);
88 m_OutboundPermission = thisModuleConfig.GetBoolean("OutboundPermission", true); 91 m_OutboundPermission = thisModuleConfig.GetBoolean("OutboundPermission", true);
89 m_ThisGatekeeper = thisModuleConfig.GetString("Gatekeeper", string.Empty); 92 m_ThisGatekeeper = thisModuleConfig.GetString("Gatekeeper", string.Empty);
90 } 93 }
@@ -100,7 +103,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
100 return; 103 return;
101 104
102 base.AddRegion(scene); 105 base.AddRegion(scene);
103 m_assMapper = new HGAssetMapper(scene, m_ProfileServerURI); 106 m_assMapper = new HGAssetMapper(scene, m_HomeURI);
104 scene.EventManager.OnNewInventoryItemUploadComplete += UploadInventoryItem; 107 scene.EventManager.OnNewInventoryItemUploadComplete += UploadInventoryItem;
105 108
106 } 109 }
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
index 37292d6..b4f6b5a 100644
--- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
@@ -50,9 +50,6 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
50 public string LastName { get; set; } 50 public string LastName { get; set; }
51 public string HomeURL { get; set; } 51 public string HomeURL { get; set; }
52 public Dictionary<string, object> ServerURLs { get; set; } 52 public Dictionary<string, object> ServerURLs { get; set; }
53 public string Title { get; set; }
54 public int Flags { get; set; }
55 public int Created { get; set; }
56 } 53 }
57 54
58 public class UserManagementModule : ISharedRegionModule, IUserManagement 55 public class UserManagementModule : ISharedRegionModule, IUserManagement
@@ -284,94 +281,6 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
284 return string.Empty; 281 return string.Empty;
285 } 282 }
286 283
287 public int GetUserFlags(UUID userID)
288 {
289 UserData userdata;
290 lock (m_UserCache)
291 m_UserCache.TryGetValue(userID, out userdata);
292
293 if (userdata.Flags == -1)
294 GetUserInfo(userID);
295
296 if (userdata.Flags != -1)
297 return userdata.Flags;
298
299 return 0;
300 }
301
302 public int GetUserCreated(UUID userID)
303 {
304 UserData userdata;
305 lock (m_UserCache)
306 m_UserCache.TryGetValue(userID, out userdata);
307
308 if (userdata.Flags == -1)
309 GetUserInfo(userID);
310
311 if (userdata.Created != -1)
312 return userdata.Created;
313
314 return 0;
315 }
316
317 public string GetUserTitle(UUID userID)
318 {
319 UserData userdata;
320 lock (m_UserCache)
321 m_UserCache.TryGetValue(userID, out userdata);
322
323 if (userdata.Flags == -1)
324 GetUserInfo(userID);
325
326 if (userdata.Created != -1)
327 return userdata.Title;
328
329 return string.Empty;
330 }
331
332 // This will cache the user data
333 // Change this to return bool
334 private bool GetUserInfo(UUID userID)
335 {
336 UserData userdata;
337 lock (m_UserCache)
338 m_UserCache.TryGetValue(userID, out userdata);
339
340 if (userdata != null)
341 {
342// m_log.DebugFormat("[USER MANAGEMENT MODULE]: Requested url type {0} for {1}", serverType, userID);
343
344 if (userdata.Flags >= 0)
345 {
346 // This is already populated
347 return true;
348 }
349
350 if (userdata.HomeURL != null && userdata.HomeURL != string.Empty)
351 {
352 m_log.DebugFormat(
353 "[USER MANAGEMENT MODULE]: Requesting user flags from '{0}' for {1}",
354 userdata.HomeURL, userID);
355
356 UserAgentServiceConnector uConn = new UserAgentServiceConnector(userdata.HomeURL);
357 Dictionary<string, object> info = uConn.GetUserInfo(userID);
358
359 // Pull our data now
360 if (info["result"].ToString() == "success")
361 {
362 userdata.Flags = (int)info["user_flags"];
363 userdata.Created = (int)info["user_created"];
364 userdata.Title = (string)info["user_title"];
365
366 return true;
367 }
368 }
369 }
370
371 return false;
372 }
373
374
375 public string GetUserUUI(UUID userID) 284 public string GetUserUUI(UUID userID)
376 { 285 {
377 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, userID); 286 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, userID);
@@ -413,68 +322,85 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
413 user.Id = uuid; 322 user.Id = uuid;
414 user.FirstName = first; 323 user.FirstName = first;
415 user.LastName = last; 324 user.LastName = last;
416 // user.ProfileURL = we should initialize this to the default
417 325
418 AddUserInternal(user); 326 AddUserInternal(user);
419 } 327 }
420 328
421 public void AddUser(UUID uuid, string first, string last, string profileURL) 329 public void AddUser(UUID uuid, string first, string last, string homeURL)
422 { 330 {
423 AddUser(uuid, profileURL + ";" + first + " " + last); 331 AddUser(uuid, homeURL + ";" + first + " " + last);
424 } 332 }
425 333
426 public void AddUser(UUID id, string creatorData) 334 public void AddUser (UUID id, string creatorData)
427 { 335 {
336 UserData oldUser;
337 //lock the whole block - prevent concurrent update
428 lock (m_UserCache) 338 lock (m_UserCache)
429 { 339 {
430 if (m_UserCache.ContainsKey(id)) 340 m_UserCache.TryGetValue (id, out oldUser);
431 return; 341 if (oldUser != null)
432 } 342 {
433 343 if (creatorData == null || creatorData == String.Empty)
434// m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, craetorData {1}", id, creatorData); 344 {
435 345 //ignore updates without creator data
436 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, id); 346 return;
347 }
348 //try update unknown users
349 //and creator's home URL's
350 if ((oldUser.FirstName == "Unknown" && !creatorData.Contains ("Unknown")) || (oldUser.HomeURL != null && !creatorData.StartsWith (oldUser.HomeURL)))
351 {
352 m_UserCache.Remove (id);
353// m_log.DebugFormat("[USER MANAGEMENT MODULE]: Re-adding user with id {0}, creatorData [{1}] and old HomeURL {2}", id, creatorData,oldUser.HomeURL);
354 }
355 else
356 {
357 //we have already a valid user within the cache
358 return;
359 }
360 }
361// m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, creatorData {1}", id, creatorData);
437 362
438 if (account != null) 363 UserAccount account = m_Scenes [0].UserAccountService.GetUserAccount (m_Scenes [0].RegionInfo.ScopeID, id);
439 {
440 AddUser(id, account.FirstName, account.LastName);
441 }
442 else
443 {
444 UserData user = new UserData();
445 user.Id = id;
446 user.Flags = -1;
447 user.Created = -1;
448 364
449 if (creatorData != null && creatorData != string.Empty) 365 if (account != null)
450 { 366 {
451 //creatorData = <endpoint>;<name> 367 AddUser (id, account.FirstName, account.LastName);
368 }
369 else
370 {
371 UserData user = new UserData ();
372 user.Id = id;
452 373
453 string[] parts = creatorData.Split(';'); 374 if (creatorData != null && creatorData != string.Empty)
454 if (parts.Length >= 1)
455 { 375 {
456 user.HomeURL = parts[0]; 376 //creatorData = <endpoint>;<name>
457 try 377
458 { 378 string[] parts = creatorData.Split (';');
459 Uri uri = new Uri(parts[0]); 379 if (parts.Length >= 1)
460 user.LastName = "@" + uri.Authority;
461 }
462 catch (UriFormatException)
463 { 380 {
464 m_log.DebugFormat("[SCENE]: Unable to parse Uri {0}", parts[0]); 381 user.HomeURL = parts [0];
465 user.LastName = "@unknown"; 382 try
383 {
384 Uri uri = new Uri (parts [0]);
385 user.LastName = "@" + uri.Authority;
386 }
387 catch (UriFormatException)
388 {
389 m_log.DebugFormat ("[SCENE]: Unable to parse Uri {0}", parts [0]);
390 user.LastName = "@unknown";
391 }
466 } 392 }
393 if (parts.Length >= 2)
394 user.FirstName = parts [1].Replace (' ', '.');
395 }
396 else
397 {
398 user.FirstName = "Unknown";
399 user.LastName = "User";
467 } 400 }
468 if (parts.Length >= 2)
469 user.FirstName = parts[1].Replace(' ', '.');
470 }
471 else
472 {
473 user.FirstName = "Unknown";
474 user.LastName = "User";
475 }
476 401
477 AddUserInternal(user); 402 AddUserInternal (user);
403 }
478 } 404 }
479 } 405 }
480 406
@@ -488,36 +414,6 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
488// user.Id, user.FirstName, user.LastName, user.HomeURL); 414// user.Id, user.FirstName, user.LastName, user.HomeURL);
489 } 415 }
490 416
491 //public void AddUser(UUID uuid, string userData)
492 //{
493 // if (m_UserCache.ContainsKey(uuid))
494 // return;
495
496 // UserData user = new UserData();
497 // user.Id = uuid;
498
499 // // userData = <profile url>;<name>
500 // string[] parts = userData.Split(';');
501 // if (parts.Length >= 1)
502 // user.ProfileURL = parts[0].Trim();
503 // if (parts.Length >= 2)
504 // {
505 // string[] name = parts[1].Trim().Split(' ');
506 // if (name.Length >= 1)
507 // user.FirstName = name[0];
508 // if (name.Length >= 2)
509 // user.LastName = name[1];
510 // else
511 // user.LastName = "?";
512 // }
513
514 // lock (m_UserCache)
515 // m_UserCache.Add(uuid, user);
516
517 // m_log.DebugFormat("[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}", user.Id, user.FirstName, user.LastName, user.ProfileURL);
518
519 //}
520
521 public bool IsLocalGridUser(UUID uuid) 417 public bool IsLocalGridUser(UUID uuid)
522 { 418 {
523 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, uuid); 419 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, uuid);
diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
index 8fb5d75..d328eb3 100644
--- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
+++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs
@@ -29,6 +29,7 @@ using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.IO; 30using System.IO;
31using System.Net; 31using System.Net;
32using System.Net.Mail;
32using System.Net.Security; 33using System.Net.Security;
33using System.Text; 34using System.Text;
34using System.Threading; 35using System.Threading;
@@ -111,21 +112,36 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
111 X509Chain chain, 112 X509Chain chain,
112 SslPolicyErrors sslPolicyErrors) 113 SslPolicyErrors sslPolicyErrors)
113 { 114 {
114 HttpWebRequest Request = (HttpWebRequest)sender; 115 // If this is a web request we need to check the headers first
115 116 // We may want to ignore SSL
116 if (Request.Headers.Get("NoVerifyCert") != null) 117 if (sender is HttpWebRequest)
117 { 118 {
119 HttpWebRequest Request = (HttpWebRequest)sender;
120 ServicePoint sp = Request.ServicePoint;
121
122 // We don't case about encryption, get out of here
123 if (Request.Headers.Get("NoVerifyCert") != null)
124 {
125 return true;
126 }
127
128 // If there was an upstream cert verification error, bail
129 if ((((int)sslPolicyErrors) & ~4) != 0)
130 return false;
131
132 // Check for policy and execute it if defined
133 if (ServicePointManager.CertificatePolicy != null)
134 {
135 return ServicePointManager.CertificatePolicy.CheckValidationResult (sp, certificate, Request, 0);
136 }
137
118 return true; 138 return true;
119 } 139 }
120 140
141 // If it's not HTTP, trust .NET to check it
121 if ((((int)sslPolicyErrors) & ~4) != 0) 142 if ((((int)sslPolicyErrors) & ~4) != 0)
122 return false; 143 return false;
123 144
124 if (ServicePointManager.CertificatePolicy != null)
125 {
126 ServicePoint sp = Request.ServicePoint;
127 return ServicePointManager.CertificatePolicy.CheckValidationResult (sp, certificate, Request, 0);
128 }
129 return true; 145 return true;
130 } 146 }
131 #region IHttpRequestModule Members 147 #region IHttpRequestModule Members
diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
index 67d99e0..93e75b3 100644
--- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
@@ -131,6 +131,12 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
131 131
132 public void RegionLoaded(Scene scene) 132 public void RegionLoaded(Scene scene)
133 { 133 {
134 IScriptModule[] scriptModules = scene.RequestModuleInterfaces<IScriptModule>();
135 foreach (IScriptModule scriptModule in scriptModules)
136 {
137 scriptModule.OnScriptRemoved += ScriptRemoved;
138 scriptModule.OnObjectRemoved += ObjectRemoved;
139 }
134 } 140 }
135 141
136 public void RemoveRegion(Scene scene) 142 public void RemoveRegion(Scene scene)
@@ -160,7 +166,6 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
160 urlData.url = url; 166 urlData.url = url;
161 urlData.urlcode = urlcode; 167 urlData.urlcode = urlcode;
162 urlData.requests = new Dictionary<UUID, RequestData>(); 168 urlData.requests = new Dictionary<UUID, RequestData>();
163
164 169
165 m_UrlMap[url] = urlData; 170 m_UrlMap[url] = urlData;
166 171
@@ -276,6 +281,8 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
276 281
277 public void ScriptRemoved(UUID itemID) 282 public void ScriptRemoved(UUID itemID)
278 { 283 {
284// m_log.DebugFormat("[URL MODULE]: Removing script {0}", itemID);
285
279 lock (m_UrlMap) 286 lock (m_UrlMap)
280 { 287 {
281 List<string> removeURLs = new List<string>(); 288 List<string> removeURLs = new List<string>();
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/LocalGridUserServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/LocalGridUserServiceConnector.cs
index 985acec..90fe69e 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/LocalGridUserServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/LocalGridUserServiceConnector.cs
@@ -171,6 +171,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser
171 { 171 {
172 return m_GridUserService.GetGridUserInfo(userID); 172 return m_GridUserService.GetGridUserInfo(userID);
173 } 173 }
174 public GridUserInfo[] GetGridUserInfo(string[] userID)
175 {
176 return m_GridUserService.GetGridUserInfo(userID);
177 }
174 178
175 #endregion 179 #endregion
176 180
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/RemoteGridUserServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/RemoteGridUserServiceConnector.cs
index 95b3591..badb552 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/RemoteGridUserServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/RemoteGridUserServiceConnector.cs
@@ -147,6 +147,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser
147 return m_RemoteConnector.GetGridUserInfo(userID); 147 return m_RemoteConnector.GetGridUserInfo(userID);
148 } 148 }
149 149
150 public GridUserInfo[] GetGridUserInfo(string[] userID)
151 {
152 return m_RemoteConnector.GetGridUserInfo(userID);
153 }
154
150 #endregion 155 #endregion
151 156
152 } 157 }
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
28using System;
29using System.Reflection;
30using OpenMetaverse;
31using System.Collections.Generic;
32using OpenSim.Framework;
33using OpenSim.Region.Framework.Scenes;
34using log4net;
35
36namespace 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
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using System.Text;
32using log4net;
33using Mono.Addins;
34using Nini.Config;
35using OpenMetaverse;
36using OpenSim.Framework;
37using OpenSim.Framework.Console;
38using OpenSim.Framework.Statistics;
39using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes;
41
42namespace 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
diff --git a/OpenSim/Region/DataSnapshot/DataRequestHandler.cs b/OpenSim/Region/DataSnapshot/DataRequestHandler.cs
index b760454..93648d6 100644
--- a/OpenSim/Region/DataSnapshot/DataRequestHandler.cs
+++ b/OpenSim/Region/DataSnapshot/DataRequestHandler.cs
@@ -67,7 +67,7 @@ namespace OpenSim.Region.DataSnapshot
67 67
68 public void OnRegisterCaps(UUID agentID, Caps caps) 68 public void OnRegisterCaps(UUID agentID, Caps caps)
69 { 69 {
70 m_log.Info("[DATASNAPSHOT]: Registering service discovery capability for " + agentID); 70// m_log.InfoFormat("[DATASNAPSHOT]: Registering service discovery capability for {0}", agentID);
71 string capsBase = "/CAPS/" + caps.CapsObjectPath; 71 string capsBase = "/CAPS/" + caps.CapsObjectPath;
72 caps.RegisterHandler("PublicSnapshotDataInfo", 72 caps.RegisterHandler("PublicSnapshotDataInfo",
73 new RestStreamHandler("POST", capsBase + m_discoveryPath, OnDiscoveryAttempt)); 73 new RestStreamHandler("POST", capsBase + m_discoveryPath, OnDiscoveryAttempt));
diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
index e668dae..eb07165 100644
--- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs
@@ -46,7 +46,7 @@ namespace OpenSim.Region.Framework.Interfaces
46 /// Save the attachments that have change on this presence. 46 /// Save the attachments that have change on this presence.
47 /// </summary> 47 /// </summary>
48 /// <param name="sp"></param> 48 /// <param name="sp"></param>
49 void SaveChangedAttachments(IScenePresence sp); 49 void SaveChangedAttachments(IScenePresence sp, bool saveAllScripted);
50 50
51 /// <summary> 51 /// <summary>
52 /// Delete all the presence's attachments from the scene 52 /// Delete all the presence's attachments from the scene
diff --git a/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs b/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs
index 8670229..39a760c 100644
--- a/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IAvatarFactoryModule.cs
@@ -61,7 +61,32 @@ namespace OpenSim.Region.Framework.Interfaces
61 /// <returns>true if a valid agent was found, false otherwise</returns> 61 /// <returns>true if a valid agent was found, false otherwise</returns>
62 bool SaveBakedTextures(UUID agentId); 62 bool SaveBakedTextures(UUID agentId);
63 63
64 /// <summary>
65 /// Validate that OpenSim can find the baked textures need to display a given avatar
66 /// </summary>
67 /// <param name="client"></param>
68 /// <param name="checkonly"></param>
69 /// <returns>
70 /// true if all the baked textures referenced by the texture IDs exist or the appearance is only using default textures. false otherwise.
71 /// </returns>
64 bool ValidateBakedTextureCache(IScenePresence sp); 72 bool ValidateBakedTextureCache(IScenePresence sp);
73
74 /// <summary>
75 /// Request a rebake of textures for an avatar.
76 /// </summary>
77 /// <remarks>
78 /// This will send the request to the viewer, since it's there that the rebake is done.
79 /// </remarks>
80 /// <param name="sp">Avatar to rebake.</param>
81 /// <param name="missingTexturesOnly">
82 /// If true, only request a rebake for the textures that are missing.
83 /// If false then we request a rebake of all textures for which we already have references.
84 /// </param>
85 /// <returns>
86 /// Number of rebake requests made. This will depend upon whether we've previously received texture IDs.
87 /// </returns>
88 int RequestRebake(IScenePresence sp, bool missingTexturesOnly);
89
65 void QueueAppearanceSend(UUID agentid); 90 void QueueAppearanceSend(UUID agentid);
66 void QueueAppearanceSave(UUID agentid); 91 void QueueAppearanceSave(UUID agentid);
67 92
diff --git a/OpenSim/Region/Framework/Interfaces/IJ2KDecoder.cs b/OpenSim/Region/Framework/Interfaces/IJ2KDecoder.cs
index 856eb11..46d03b3 100644
--- a/OpenSim/Region/Framework/Interfaces/IJ2KDecoder.cs
+++ b/OpenSim/Region/Framework/Interfaces/IJ2KDecoder.cs
@@ -35,6 +35,23 @@ namespace OpenSim.Region.Framework.Interfaces
35 public interface IJ2KDecoder 35 public interface IJ2KDecoder
36 { 36 {
37 void BeginDecode(UUID assetID, byte[] j2kData, DecodedCallback callback); 37 void BeginDecode(UUID assetID, byte[] j2kData, DecodedCallback callback);
38 void Decode(UUID assetID, byte[] j2kData); 38
39 /// <summary>
40 /// Provides a synchronous decode so that caller can be assured that this executes before the next line
41 /// </summary>
42 /// <param name="assetID"></param>
43 /// <param name="j2kData"></param>
44 /// <returns>true if decode was successful. false otherwise.</returns>
45 bool Decode(UUID assetID, byte[] j2kData);
46
47 /// <summary>
48 /// Provides a synchronous decode so that caller can be assured that this executes before the next line
49 /// </summary>
50 /// <param name="assetID"></param>
51 /// <param name="j2kData"></param>
52 /// <param name="layers">layer data</param>
53 /// <param name="components">number of components</param>
54 /// <returns>true if decode was successful. false otherwise.</returns>
55 bool Decode(UUID assetID, byte[] j2kData, out OpenJPEG.J2KLayerInfo[] layers, out int components);
39 } 56 }
40} 57}
diff --git a/OpenSim/Region/Framework/Interfaces/INPCModule.cs b/OpenSim/Region/Framework/Interfaces/INPCModule.cs
index b65f82c..2731291 100644
--- a/OpenSim/Region/Framework/Interfaces/INPCModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/INPCModule.cs
@@ -31,6 +31,19 @@ using OpenSim.Region.Framework.Scenes;
31 31
32namespace OpenSim.Region.Framework.Interfaces 32namespace OpenSim.Region.Framework.Interfaces
33{ 33{
34 /// <summary>
35 /// Temporary interface. More methods to come at some point to make NPCs more object oriented rather than
36 /// controlling purely through module level interface calls (e.g. sit/stand).
37 /// </summary>
38 public interface INPC
39 {
40 /// <summary>
41 /// Should this NPC be sensed by LSL sensors as an 'agent' (interpreted here to mean a normal user)
42 /// rather than an OpenSim specific NPC extension?
43 /// </summary>
44 bool SenseAsAgent { get; }
45 }
46
34 public interface INPCModule 47 public interface INPCModule
35 { 48 {
36 /// <summary> 49 /// <summary>
@@ -39,10 +52,21 @@ namespace OpenSim.Region.Framework.Interfaces
39 /// <param name="firstname"></param> 52 /// <param name="firstname"></param>
40 /// <param name="lastname"></param> 53 /// <param name="lastname"></param>
41 /// <param name="position"></param> 54 /// <param name="position"></param>
55 /// <param name="senseAsAgent">
56 /// Make the NPC show up as an agent on LSL sensors. The default is that they
57 /// show up as the NPC type instead, but this is currently an OpenSim-only extension.
58 /// </param>
42 /// <param name="scene"></param> 59 /// <param name="scene"></param>
43 /// <param name="appearance">The avatar appearance to use for the new NPC.</param> 60 /// <param name="appearance">The avatar appearance to use for the new NPC.</param>
44 /// <returns>The UUID of the ScenePresence created.</returns> 61 /// <returns>The UUID of the ScenePresence created.</returns>
45 UUID CreateNPC(string firstname, string lastname, Vector3 position, Scene scene, AvatarAppearance appearance); 62 UUID CreateNPC(
63 string firstname,
64 string lastname,
65 Vector3 position,
66 UUID owner,
67 bool senseAsAgent,
68 Scene scene,
69 AvatarAppearance appearance);
46 70
47 /// <summary> 71 /// <summary>
48 /// Check if the agent is an NPC. 72 /// Check if the agent is an NPC.
@@ -53,6 +77,22 @@ namespace OpenSim.Region.Framework.Interfaces
53 bool IsNPC(UUID agentID, Scene scene); 77 bool IsNPC(UUID agentID, Scene scene);
54 78
55 /// <summary> 79 /// <summary>
80 /// Get the NPC. This is not currently complete - manipulation of NPCs still occurs through the region interface
81 /// </summary>
82 /// <param name="agentID"></param>
83 /// <param name="scene"></param>
84 /// <returns>The NPC. null if it does not exist.</returns>
85 INPC GetNPC(UUID agentID, Scene scene);
86
87 /// <summary>
88 /// Check if the caller has permission to manipulate the given NPC.
89 /// </summary>
90 /// <param name="npcID"></param>
91 /// <param name="callerID"></param>
92 /// <returns>true if they do, false if they don't or if there's no NPC with the given ID.</returns>
93 bool CheckPermissions(UUID npcID, UUID callerID);
94
95 /// <summary>
56 /// Set the appearance for an NPC. 96 /// Set the appearance for an NPC.
57 /// </summary> 97 /// </summary>
58 /// <param name="agentID"></param> 98 /// <param name="agentID"></param>
@@ -118,5 +158,12 @@ namespace OpenSim.Region.Framework.Interfaces
118 /// <param name="scene"></param> 158 /// <param name="scene"></param>
119 /// <returns>True if the operation succeeded, false if there was no such agent or the agent was not an NPC</returns> 159 /// <returns>True if the operation succeeded, false if there was no such agent or the agent was not an NPC</returns>
120 bool DeleteNPC(UUID agentID, Scene scene); 160 bool DeleteNPC(UUID agentID, Scene scene);
161
162 /// <summary>
163 /// Get the owner of a NPC
164 /// </summary>
165 /// <param name="agentID">The UUID of the NPC</param>
166 /// <returns>UUID of owner if the NPC exists, UUID.Zero if there was no such agent, the agent is unowned or the agent was not an NPC</returns>
167 UUID GetOwner(UUID agentID);
121 } 168 }
122} \ No newline at end of file 169} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Interfaces/IProfileModule.cs b/OpenSim/Region/Framework/Interfaces/IProfileModule.cs
new file mode 100644
index 0000000..ef03d4a
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IProfileModule.cs
@@ -0,0 +1,37 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenMetaverse;
29
30namespace OpenSim.Framework
31{
32 public interface IProfileModule
33 {
34 void RequestAvatarProperties(IClientAPI remoteClient, UUID avatarID);
35
36 }
37}
diff --git a/OpenSim/Region/Framework/Interfaces/IRegionReadyModule.cs b/OpenSim/Region/Framework/Interfaces/IRegionReadyModule.cs
new file mode 100644
index 0000000..aa4a757
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IRegionReadyModule.cs
@@ -0,0 +1,38 @@
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
29using System;
30
31namespace OpenSim.Region.Framework.Interfaces
32{
33 public interface IRegionReadyModule
34 {
35 void OarLoadingAlert(string msg);
36 }
37}
38
diff --git a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs
index 950e4b0..18c45dd 100644
--- a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs
@@ -31,8 +31,21 @@ using OpenMetaverse;
31 31
32namespace OpenSim.Region.Framework.Interfaces 32namespace OpenSim.Region.Framework.Interfaces
33{ 33{
34 public delegate void ScriptRemoved(UUID script);
35 public delegate void ObjectRemoved(UUID prim);
36
34 public interface IScriptModule: INonSharedRegionModule 37 public interface IScriptModule: INonSharedRegionModule
35 { 38 {
39 /// <summary>
40 /// Triggered when a script is removed from the script module.
41 /// </summary>
42 event ScriptRemoved OnScriptRemoved;
43
44 /// <summary>
45 /// Triggered when an object is removed via the script module.
46 /// </summary>
47 event ObjectRemoved OnObjectRemoved;
48
36 string ScriptEngineName { get; } 49 string ScriptEngineName { get; }
37 50
38 string GetXMLState(UUID itemID); 51 string GetXMLState(UUID itemID);
diff --git a/OpenSim/Region/Framework/Interfaces/ISearchModule.cs b/OpenSim/Region/Framework/Interfaces/ISearchModule.cs
new file mode 100644
index 0000000..64bf72c
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/ISearchModule.cs
@@ -0,0 +1,36 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenMetaverse;
29
30namespace OpenSim.Framework
31{
32 public interface ISearchModule
33 {
34
35 }
36}
diff --git a/OpenSim/Region/Framework/Interfaces/IUserManagement.cs b/OpenSim/Region/Framework/Interfaces/IUserManagement.cs
index 54dfaf4..bfb8369 100644
--- a/OpenSim/Region/Framework/Interfaces/IUserManagement.cs
+++ b/OpenSim/Region/Framework/Interfaces/IUserManagement.cs
@@ -14,9 +14,6 @@ namespace OpenSim.Region.Framework.Interfaces
14 string GetUserHomeURL(UUID uuid); 14 string GetUserHomeURL(UUID uuid);
15 string GetUserUUI(UUID uuid); 15 string GetUserUUI(UUID uuid);
16 string GetUserServerURL(UUID uuid, string serverType); 16 string GetUserServerURL(UUID uuid, string serverType);
17 int GetUserFlags(UUID userID);
18 int GetUserCreated(UUID userID);
19 string GetUserTitle(UUID userID);
20 17
21 /// <summary> 18 /// <summary>
22 /// Add a user. 19 /// Add a user.
@@ -50,7 +47,7 @@ namespace OpenSim.Region.Framework.Interfaces
50 /// <param name="uuid"></param> 47 /// <param name="uuid"></param>
51 /// <param name="firstName"></param> 48 /// <param name="firstName"></param>
52 /// <param name="profileURL"></param> 49 /// <param name="profileURL"></param>
53 void AddUser(UUID uuid, string firstName, string lastName, string profileURL); 50 void AddUser(UUID uuid, string firstName, string lastName, string homeURL);
54 51
55 bool IsLocalGridUser(UUID uuid); 52 bool IsLocalGridUser(UUID uuid);
56 } 53 }
diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
index eda085f..3584cda 100644
--- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
+++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
@@ -61,11 +61,12 @@ namespace OpenSim.Region.Framework.Scenes.Animation
61 public bool m_jumping = false; 61 public bool m_jumping = false;
62 public float m_jumpVelocity = 0f; 62 public float m_jumpVelocity = 0f;
63// private int m_landing = 0; 63// private int m_landing = 0;
64 public bool Falling 64
65 { 65 /// <summary>
66 get { return m_falling; } 66 /// Is the avatar falling?
67 } 67 /// </summary>
68 private bool m_falling = false; 68 public bool Falling { get; private set; }
69
69 private float m_fallHeight; 70 private float m_fallHeight;
70 71
71 /// <value> 72 /// <value>
@@ -223,7 +224,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
223 m_animTickFall = 0; 224 m_animTickFall = 0;
224 m_animTickJump = 0; 225 m_animTickJump = 0;
225 m_jumping = false; 226 m_jumping = false;
226 m_falling = true; 227 Falling = false;
227 m_jumpVelocity = 0f; 228 m_jumpVelocity = 0f;
228 actor.Selected = false; 229 actor.Selected = false;
229 m_fallHeight = actor.Position.Z; // save latest flying height 230 m_fallHeight = actor.Position.Z; // save latest flying height
@@ -238,10 +239,8 @@ namespace OpenSim.Region.Framework.Scenes.Animation
238 } 239 }
239 else if (move.Z < 0f) 240 else if (move.Z < 0f)
240 { 241 {
241 if (actor != null && actor.IsColliding) 242 if (actor != null && actor.IsColliding)
242 {
243 return "LAND"; 243 return "LAND";
244 }
245 else 244 else
246 return "HOVER_DOWN"; 245 return "HOVER_DOWN";
247 } 246 }
@@ -260,7 +259,8 @@ namespace OpenSim.Region.Framework.Scenes.Animation
260 float fallElapsed = (float)(Environment.TickCount - m_animTickFall); 259 float fallElapsed = (float)(Environment.TickCount - m_animTickFall);
261 float fallVelocity = (actor != null) ? actor.Velocity.Z : 0.0f; 260 float fallVelocity = (actor != null) ? actor.Velocity.Z : 0.0f;
262 261
263 if (!m_jumping && (fallVelocity < -3.0f) ) m_falling = true; 262 if (!m_jumping && (fallVelocity < -3.0f))
263 Falling = true;
264 264
265 if (m_animTickFall == 0 || (fallVelocity >= 0.0f)) 265 if (m_animTickFall == 0 || (fallVelocity >= 0.0f))
266 { 266 {
@@ -290,20 +290,20 @@ namespace OpenSim.Region.Framework.Scenes.Animation
290 // Start jumping, prejump 290 // Start jumping, prejump
291 m_animTickFall = 0; 291 m_animTickFall = 0;
292 m_jumping = true; 292 m_jumping = true;
293 m_falling = false; 293 Falling = false;
294 actor.Selected = true; // borrowed for jumping flag 294 actor.Selected = true; // borrowed for jumping flag
295 m_animTickJump = Environment.TickCount; 295 m_animTickJump = Environment.TickCount;
296 m_jumpVelocity = 0.35f; 296 m_jumpVelocity = 0.35f;
297 return "PREJUMP"; 297 return "PREJUMP";
298 } 298 }
299 299
300 if(m_jumping) 300 if (m_jumping)
301 { 301 {
302 if ( (jumptime > (JUMP_PERIOD * 1.5f)) && actor.IsColliding) 302 if ((jumptime > (JUMP_PERIOD * 1.5f)) && actor.IsColliding)
303 { 303 {
304 // end jumping 304 // end jumping
305 m_jumping = false; 305 m_jumping = false;
306 m_falling = false; 306 Falling = false;
307 actor.Selected = false; // borrowed for jumping flag 307 actor.Selected = false; // borrowed for jumping flag
308 m_jumpVelocity = 0f; 308 m_jumpVelocity = 0f;
309 m_animTickFall = Environment.TickCount; 309 m_animTickFall = Environment.TickCount;
@@ -330,7 +330,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
330 330
331 if (CurrentMovementAnimation == "FALLDOWN") 331 if (CurrentMovementAnimation == "FALLDOWN")
332 { 332 {
333 m_falling = false; 333 Falling = false;
334 m_animTickFall = Environment.TickCount; 334 m_animTickFall = Environment.TickCount;
335 // TODO: SOFT_LAND support 335 // TODO: SOFT_LAND support
336 float fallHeight = m_fallHeight - actor.Position.Z; 336 float fallHeight = m_fallHeight - actor.Position.Z;
@@ -364,7 +364,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
364 if (move.X != 0f || move.Y != 0f) 364 if (move.X != 0f || move.Y != 0f)
365 { 365 {
366 m_fallHeight = actor.Position.Z; // save latest flying height 366 m_fallHeight = actor.Position.Z; // save latest flying height
367 m_falling = false; 367 Falling = false;
368 // Walking / crouchwalking / running 368 // Walking / crouchwalking / running
369 if (move.Z < 0f) 369 if (move.Z < 0f)
370 return "CROUCHWALK"; 370 return "CROUCHWALK";
@@ -375,7 +375,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
375 } 375 }
376 else if (!m_jumping) 376 else if (!m_jumping)
377 { 377 {
378 m_falling = false; 378 Falling = false;
379 // Not walking 379 // Not walking
380 if (move.Z < 0) 380 if (move.Z < 0)
381 return "CROUCH"; 381 return "CROUCH";
@@ -388,7 +388,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
388 } 388 }
389 #endregion Ground Movement 389 #endregion Ground Movement
390 390
391 m_falling = false; 391 Falling = false;
392 392
393 return CurrentMovementAnimation; 393 return CurrentMovementAnimation;
394 } 394 }
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index b62023b..dd3208a 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -979,25 +979,40 @@ namespace OpenSim.Region.Framework.Scenes
979 public void RemoveTaskInventory(IClientAPI remoteClient, UUID itemID, uint localID) 979 public void RemoveTaskInventory(IClientAPI remoteClient, UUID itemID, uint localID)
980 { 980 {
981 SceneObjectPart part = GetSceneObjectPart(localID); 981 SceneObjectPart part = GetSceneObjectPart(localID);
982 if (part == null) 982 SceneObjectGroup group = null;
983 return; 983 if (part != null)
984 {
985 group = part.ParentGroup;
986 }
987 if (part != null && group != null)
988 {
989 if (!Permissions.CanEditObjectInventory(part.UUID, remoteClient.AgentId))
990 return;
984 991
985 SceneObjectGroup group = part.ParentGroup; 992 TaskInventoryItem item = group.GetInventoryItem(localID, itemID);
986 if (!Permissions.CanEditObjectInventory(part.UUID, remoteClient.AgentId)) 993 if (item == null)
987 return; 994 return;
988
989 TaskInventoryItem item = group.GetInventoryItem(localID, itemID);
990 if (item == null)
991 return;
992 995
993 if (item.Type == 10) 996 InventoryFolderBase destFolder = InventoryService.GetFolderForType(remoteClient.AgentId, AssetType.TrashFolder);
994 { 997
995 part.RemoveScriptEvents(itemID); 998 // Move the item to trash. If this is a copiable item, only
996 EventManager.TriggerRemoveScript(localID, itemID); 999 // a copy will be moved and we will still need to delete
1000 // the item from the prim. If it was no copy, is will be
1001 // deleted by this method.
1002 MoveTaskInventoryItem(remoteClient, destFolder.ID, part, itemID);
1003
1004 if (group.GetInventoryItem(localID, itemID) != null)
1005 {
1006 if (item.Type == 10)
1007 {
1008 part.RemoveScriptEvents(itemID);
1009 EventManager.TriggerRemoveScript(localID, itemID);
1010 }
1011
1012 group.RemoveInventoryItem(localID, itemID);
1013 }
1014 part.SendPropertiesToClient(remoteClient);
997 } 1015 }
998
999 group.RemoveInventoryItem(localID, itemID);
1000 part.SendPropertiesToClient(remoteClient);
1001 } 1016 }
1002 1017
1003 private InventoryItemBase CreateAgentInventoryItemFromTask(UUID destAgent, SceneObjectPart part, UUID itemId) 1018 private InventoryItemBase CreateAgentInventoryItemFromTask(UUID destAgent, SceneObjectPart part, UUID itemId)
@@ -1058,7 +1073,15 @@ namespace OpenSim.Region.Framework.Scenes
1058 if (!Permissions.BypassPermissions()) 1073 if (!Permissions.BypassPermissions())
1059 { 1074 {
1060 if ((taskItem.CurrentPermissions & (uint)PermissionMask.Copy) == 0) 1075 if ((taskItem.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
1076 {
1077 if (taskItem.Type == 10)
1078 {
1079 part.RemoveScriptEvents(itemId);
1080 EventManager.TriggerRemoveScript(part.LocalId, itemId);
1081 }
1082
1061 part.Inventory.RemoveInventoryItem(itemId); 1083 part.Inventory.RemoveInventoryItem(itemId);
1084 }
1062 } 1085 }
1063 1086
1064 return agentItem; 1087 return agentItem;
@@ -1421,7 +1444,7 @@ namespace OpenSim.Region.Framework.Scenes
1421 // If we've found the item in the user's inventory or in the library 1444 // If we've found the item in the user's inventory or in the library
1422 if (item != null) 1445 if (item != null)
1423 { 1446 {
1424 part.ParentGroup.AddInventoryItem(remoteClient, primLocalID, item, copyID); 1447 part.ParentGroup.AddInventoryItem(remoteClient.AgentId, primLocalID, item, copyID);
1425 m_log.InfoFormat( 1448 m_log.InfoFormat(
1426 "[PRIM INVENTORY]: Update with item {0} requested of prim {1} for {2}", 1449 "[PRIM INVENTORY]: Update with item {0} requested of prim {1} for {2}",
1427 item.Name, primLocalID, remoteClient.Name); 1450 item.Name, primLocalID, remoteClient.Name);
@@ -1449,20 +1472,27 @@ namespace OpenSim.Region.Framework.Scenes
1449// m_log.DebugFormat( 1472// m_log.DebugFormat(
1450// "[PRIM INVENTORY]: Updating item {0} in {1} for UpdateTaskInventory()", 1473// "[PRIM INVENTORY]: Updating item {0} in {1} for UpdateTaskInventory()",
1451// currentItem.Name, part.Name); 1474// currentItem.Name, part.Name);
1452
1453 IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>();
1454 if (agentTransactions != null)
1455 {
1456 agentTransactions.HandleTaskItemUpdateFromTransaction(
1457 remoteClient, part, transactionID, currentItem);
1458 1475
1459 if ((InventoryType)itemInfo.InvType == InventoryType.Notecard) 1476 // Viewers from at least Linden Lab 1.23 onwards use a capability to update script contents rather
1460 remoteClient.SendAgentAlertMessage("Notecard saved", false); 1477 // than UDP. With viewers from at least 1.23 onwards, changing properties on scripts (e.g. renaming) causes
1461 else if ((InventoryType)itemInfo.InvType == InventoryType.LSL) 1478 // this to spew spurious errors and "thing saved" messages.
1462 remoteClient.SendAgentAlertMessage("Script saved", false); 1479 // Rather than retaining complexity in the code and removing useful error messages, I'm going to
1463 else 1480 // comment this section out. If this was still working for very old viewers and there is
1464 remoteClient.SendAgentAlertMessage("Item saved", false); 1481 // a large population using them which cannot upgrade to 1.23 or derivatives then we can revisit
1465 } 1482 // this - justincc
1483// IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>();
1484// if (agentTransactions != null)
1485// {
1486// agentTransactions.HandleTaskItemUpdateFromTransaction(
1487// remoteClient, part, transactionID, currentItem);
1488//
1489// if ((InventoryType)itemInfo.InvType == InventoryType.Notecard)
1490// remoteClient.SendAgentAlertMessage("Notecard saved", false);
1491// else if ((InventoryType)itemInfo.InvType == InventoryType.LSL)
1492// remoteClient.SendAgentAlertMessage("Script saved", false);
1493// else
1494// remoteClient.SendAgentAlertMessage("Item saved", false);
1495// }
1466 1496
1467 // Base ALWAYS has move 1497 // Base ALWAYS has move
1468 currentItem.BasePermissions |= (uint)PermissionMask.Move; 1498 currentItem.BasePermissions |= (uint)PermissionMask.Move;
@@ -1537,104 +1567,141 @@ namespace OpenSim.Region.Framework.Scenes
1537 /// Rez a script into a prim's inventory, either ex nihilo or from an existing avatar inventory 1567 /// Rez a script into a prim's inventory, either ex nihilo or from an existing avatar inventory
1538 /// </summary> 1568 /// </summary>
1539 /// <param name="remoteClient"></param> 1569 /// <param name="remoteClient"></param>
1540 /// <param name="itemID"> </param> 1570 /// <param name="itemBase"> </param>
1571 /// <param name="transactionID"></param>
1541 /// <param name="localID"></param> 1572 /// <param name="localID"></param>
1542 public void RezScript(IClientAPI remoteClient, InventoryItemBase itemBase, UUID transactionID, uint localID) 1573 public void RezScript(IClientAPI remoteClient, InventoryItemBase itemBase, UUID transactionID, uint localID)
1543 { 1574 {
1544 UUID itemID = itemBase.ID; 1575 SceneObjectPart partWhereRezzed;
1576
1577 if (itemBase.ID != UUID.Zero)
1578 partWhereRezzed = RezScriptFromAgentInventory(remoteClient.AgentId, itemBase.ID, localID);
1579 else
1580 partWhereRezzed = RezNewScript(remoteClient.AgentId, itemBase);
1581
1582 if (partWhereRezzed != null)
1583 partWhereRezzed.SendPropertiesToClient(remoteClient);
1584 }
1585
1586 /// <summary>
1587 /// Rez a script into a prim from an agent inventory.
1588 /// </summary>
1589 /// <param name="agentID"></param>
1590 /// <param name="fromItemID"></param>
1591 /// <param name="localID"></param>
1592 /// <returns>The part where the script was rezzed if successful. False otherwise.</returns>
1593 public SceneObjectPart RezScriptFromAgentInventory(UUID agentID, UUID fromItemID, uint localID)
1594 {
1545 UUID copyID = UUID.Random(); 1595 UUID copyID = UUID.Random();
1596 InventoryItemBase item = new InventoryItemBase(fromItemID, agentID);
1597 item = InventoryService.GetItem(item);
1546 1598
1547 if (itemID != UUID.Zero) // transferred from an avatar inventory to the prim's inventory 1599 // Try library
1600 // XXX clumsy, possibly should be one call
1601 if (null == item && LibraryService != null && LibraryService.LibraryRootFolder != null)
1548 { 1602 {
1549 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); 1603 item = LibraryService.LibraryRootFolder.FindItem(fromItemID);
1550 item = InventoryService.GetItem(item); 1604 }
1551 1605
1552 // Try library 1606 if (item != null)
1553 // XXX clumsy, possibly should be one call 1607 {
1554 if (null == item && LibraryService != null && LibraryService.LibraryRootFolder != null) 1608 SceneObjectPart part = GetSceneObjectPart(localID);
1609 if (part != null)
1555 { 1610 {
1556 item = LibraryService.LibraryRootFolder.FindItem(itemID); 1611 if (!Permissions.CanEditObjectInventory(part.UUID, agentID))
1557 } 1612 return null;
1558 1613
1559 if (item != null) 1614 part.ParentGroup.AddInventoryItem(agentID, localID, item, copyID);
1560 { 1615 // TODO: switch to posting on_rez here when scripts
1561 SceneObjectPart part = GetSceneObjectPart(localID); 1616 // have state in inventory
1562 if (part != null) 1617 part.Inventory.CreateScriptInstance(copyID, 0, false, DefaultScriptEngine, 0);
1563 {
1564 if (!Permissions.CanEditObjectInventory(part.UUID, remoteClient.AgentId))
1565 return;
1566 1618
1567 part.ParentGroup.AddInventoryItem(remoteClient, localID, item, copyID); 1619 // m_log.InfoFormat("[PRIMINVENTORY]: " +
1568 // TODO: switch to posting on_rez here when scripts 1620 // "Rezzed script {0} into prim local ID {1} for user {2}",
1569 // have state in inventory 1621 // item.inventoryName, localID, remoteClient.Name);
1570 part.Inventory.CreateScriptInstance(copyID, 0, false, DefaultScriptEngine, 0); 1622 part.ParentGroup.ResumeScripts();
1571 1623
1572 // m_log.InfoFormat("[PRIMINVENTORY]: " + 1624 return part;
1573 // "Rezzed script {0} into prim local ID {1} for user {2}",
1574 // item.inventoryName, localID, remoteClient.Name);
1575 part.SendPropertiesToClient(remoteClient);
1576 part.ParentGroup.ResumeScripts();
1577 }
1578 else
1579 {
1580 m_log.ErrorFormat(
1581 "[PRIM INVENTORY]: " +
1582 "Could not rez script {0} into prim local ID {1} for user {2}"
1583 + " because the prim could not be found in the region!",
1584 item.Name, localID, remoteClient.Name);
1585 }
1586 } 1625 }
1587 else 1626 else
1588 { 1627 {
1589 m_log.ErrorFormat( 1628 m_log.ErrorFormat(
1590 "[PRIM INVENTORY]: Could not find script inventory item {0} to rez for {1}!", 1629 "[PRIM INVENTORY]: " +
1591 itemID, remoteClient.Name); 1630 "Could not rez script {0} into prim local ID {1} for user {2}"
1631 + " because the prim could not be found in the region!",
1632 item.Name, localID, agentID);
1592 } 1633 }
1593 } 1634 }
1594 else // script has been rezzed directly into a prim's inventory 1635 else
1595 { 1636 {
1596 SceneObjectPart part = GetSceneObjectPart(itemBase.Folder); 1637 m_log.ErrorFormat(
1597 if (part == null) 1638 "[PRIM INVENTORY]: Could not find script inventory item {0} to rez for {1}!",
1598 return; 1639 fromItemID, agentID);
1640 }
1599 1641
1600 if (!Permissions.CanCreateObjectInventory( 1642 return null;
1601 itemBase.InvType, part.UUID, remoteClient.AgentId)) 1643 }
1602 return;
1603 1644
1604 AssetBase asset = CreateAsset(itemBase.Name, itemBase.Description, (sbyte)itemBase.AssetType, 1645 /// <summary>
1605 Encoding.ASCII.GetBytes("default\n{\n state_entry()\n {\n llSay(0, \"Script running\");\n }\n}"), 1646 /// Rez a new script from nothing.
1606 remoteClient.AgentId); 1647 /// </summary>
1607 AssetService.Store(asset); 1648 /// <param name="remoteClient"></param>
1608 1649 /// <param name="itemBase"></param>
1609 TaskInventoryItem taskItem = new TaskInventoryItem(); 1650 /// <returns>The part where the script was rezzed if successful. False otherwise.</returns>
1610 1651 public SceneObjectPart RezNewScript(UUID agentID, InventoryItemBase itemBase)
1611 taskItem.ResetIDs(itemBase.Folder); 1652 {
1612 taskItem.ParentID = itemBase.Folder; 1653 // The part ID is the folder ID!
1613 taskItem.CreationDate = (uint)itemBase.CreationDate; 1654 SceneObjectPart part = GetSceneObjectPart(itemBase.Folder);
1614 taskItem.Name = itemBase.Name; 1655 if (part == null)
1615 taskItem.Description = itemBase.Description; 1656 {
1616 taskItem.Type = itemBase.AssetType; 1657// m_log.DebugFormat(
1617 taskItem.InvType = itemBase.InvType; 1658// "[SCENE INVENTORY]: Could not find part with id {0} for {1} to rez new script",
1618 taskItem.OwnerID = itemBase.Owner; 1659// itemBase.Folder, agentID);
1619 taskItem.CreatorID = itemBase.CreatorIdAsUuid;
1620 taskItem.BasePermissions = itemBase.BasePermissions;
1621 taskItem.CurrentPermissions = itemBase.CurrentPermissions;
1622 taskItem.EveryonePermissions = itemBase.EveryOnePermissions;
1623 taskItem.GroupPermissions = itemBase.GroupPermissions;
1624 taskItem.NextPermissions = itemBase.NextPermissions;
1625 taskItem.GroupID = itemBase.GroupID;
1626 taskItem.GroupPermissions = 0;
1627 taskItem.Flags = itemBase.Flags;
1628 taskItem.PermsGranter = UUID.Zero;
1629 taskItem.PermsMask = 0;
1630 taskItem.AssetID = asset.FullID;
1631
1632 part.Inventory.AddInventoryItem(taskItem, false);
1633 part.SendPropertiesToClient(remoteClient);
1634 1660
1635 part.Inventory.CreateScriptInstance(taskItem, 0, false, DefaultScriptEngine, 0); 1661 return null;
1636 part.ParentGroup.ResumeScripts(); 1662 }
1663
1664 if (!Permissions.CanCreateObjectInventory(itemBase.InvType, part.UUID, agentID))
1665 {
1666// m_log.DebugFormat(
1667// "[SCENE INVENTORY]: No permission to create new script in {0} for {1}", part.Name, agentID);
1668
1669 return null;
1637 } 1670 }
1671
1672 AssetBase asset = CreateAsset(itemBase.Name, itemBase.Description, (sbyte)itemBase.AssetType,
1673 Encoding.ASCII.GetBytes("default\n{\n state_entry()\n {\n llSay(0, \"Script running\");\n }\n}"),
1674 agentID);
1675 AssetService.Store(asset);
1676
1677 TaskInventoryItem taskItem = new TaskInventoryItem();
1678
1679 taskItem.ResetIDs(itemBase.Folder);
1680 taskItem.ParentID = itemBase.Folder;
1681 taskItem.CreationDate = (uint)itemBase.CreationDate;
1682 taskItem.Name = itemBase.Name;
1683 taskItem.Description = itemBase.Description;
1684 taskItem.Type = itemBase.AssetType;
1685 taskItem.InvType = itemBase.InvType;
1686 taskItem.OwnerID = itemBase.Owner;
1687 taskItem.CreatorID = itemBase.CreatorIdAsUuid;
1688 taskItem.BasePermissions = itemBase.BasePermissions;
1689 taskItem.CurrentPermissions = itemBase.CurrentPermissions;
1690 taskItem.EveryonePermissions = itemBase.EveryOnePermissions;
1691 taskItem.GroupPermissions = itemBase.GroupPermissions;
1692 taskItem.NextPermissions = itemBase.NextPermissions;
1693 taskItem.GroupID = itemBase.GroupID;
1694 taskItem.GroupPermissions = 0;
1695 taskItem.Flags = itemBase.Flags;
1696 taskItem.PermsGranter = UUID.Zero;
1697 taskItem.PermsMask = 0;
1698 taskItem.AssetID = asset.FullID;
1699
1700 part.Inventory.AddInventoryItem(taskItem, false);
1701 part.Inventory.CreateScriptInstance(taskItem, 0, false, DefaultScriptEngine, 0);
1702 part.ParentGroup.ResumeScripts();
1703
1704 return part;
1638 } 1705 }
1639 1706
1640 /// <summary> 1707 /// <summary>
@@ -1643,7 +1710,7 @@ namespace OpenSim.Region.Framework.Scenes
1643 /// <param name="remoteClient"></param> 1710 /// <param name="remoteClient"></param>
1644 /// <param name="itemID"> </param> 1711 /// <param name="itemID"> </param>
1645 /// <param name="localID"></param> 1712 /// <param name="localID"></param>
1646 public void RezScript(UUID srcId, SceneObjectPart srcPart, UUID destId, int pin, int running, int start_param) 1713 public void RezScriptFromPrim(UUID srcId, SceneObjectPart srcPart, UUID destId, int pin, int running, int start_param)
1647 { 1714 {
1648 TaskInventoryItem srcTaskItem = srcPart.Inventory.GetInventoryItem(srcId); 1715 TaskInventoryItem srcTaskItem = srcPart.Inventory.GetInventoryItem(srcId);
1649 1716
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 3d8c714..bfe8d2c 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -65,6 +65,7 @@ namespace OpenSim.Region.Framework.Scenes
65 #region Fields 65 #region Fields
66 66
67 public bool EmergencyMonitoring = false; 67 public bool EmergencyMonitoring = false;
68 public bool DEBUG = false;
68 69
69 public SynchronizeSceneHandler SynchronizeScene; 70 public SynchronizeSceneHandler SynchronizeScene;
70 public SimStatsReporter StatsReporter; 71 public SimStatsReporter StatsReporter;
@@ -599,23 +600,6 @@ namespace OpenSim.Region.Framework.Scenes
599 "reload estate", 600 "reload estate",
600 "Reload the estate data", HandleReloadEstate); 601 "Reload the estate data", HandleReloadEstate);
601 602
602 MainConsole.Instance.Commands.AddCommand("region", false, "delete object owner",
603 "delete object owner <UUID>",
604 "Delete object by owner", HandleDeleteObject);
605 MainConsole.Instance.Commands.AddCommand("region", false, "delete object creator",
606 "delete object creator <UUID>",
607 "Delete object by creator", HandleDeleteObject);
608 MainConsole.Instance.Commands.AddCommand("region", false, "delete object uuid",
609 "delete object uuid <UUID>",
610 "Delete object by uuid", HandleDeleteObject);
611 MainConsole.Instance.Commands.AddCommand("region", false, "delete object name",
612 "delete object name <name>",
613 "Delete object by name", HandleDeleteObject);
614
615 MainConsole.Instance.Commands.AddCommand("region", false, "delete object outside",
616 "delete object outside",
617 "Delete all objects outside boundaries", HandleDeleteObject);
618
619 //Bind Storage Manager functions to some land manager functions for this scene 603 //Bind Storage Manager functions to some land manager functions for this scene
620 EventManager.OnLandObjectAdded += 604 EventManager.OnLandObjectAdded +=
621 new EventManager.LandObjectAdded(simDataService.StoreLandObject); 605 new EventManager.LandObjectAdded(simDataService.StoreLandObject);
@@ -1942,6 +1926,7 @@ namespace OpenSim.Region.Framework.Scenes
1942 /// If true, the object is made persistent into the scene. 1926 /// If true, the object is made persistent into the scene.
1943 /// If false, the object will not persist over server restarts 1927 /// If false, the object will not persist over server restarts
1944 /// </param> 1928 /// </param>
1929 /// <returns>true if the object was added. false if not</returns>
1945 public bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup) 1930 public bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup)
1946 { 1931 {
1947 return AddNewSceneObject(sceneObject, attachToBackup, true); 1932 return AddNewSceneObject(sceneObject, attachToBackup, true);
@@ -1959,6 +1944,7 @@ namespace OpenSim.Region.Framework.Scenes
1959 /// If true, updates for the new scene object are sent to all viewers in range. 1944 /// If true, updates for the new scene object are sent to all viewers in range.
1960 /// If false, it is left to the caller to schedule the update 1945 /// If false, it is left to the caller to schedule the update
1961 /// </param> 1946 /// </param>
1947 /// <returns>true if the object was added. false if not</returns>
1962 public bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates) 1948 public bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates)
1963 { 1949 {
1964 if (m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup, sendClientUpdates)) 1950 if (m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup, sendClientUpdates))
@@ -2528,7 +2514,7 @@ namespace OpenSim.Region.Framework.Scenes
2528 sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type); 2514 sp = m_sceneGraph.CreateAndAddChildScenePresence(client, aCircuit.Appearance, type);
2529 m_eventManager.TriggerOnNewPresence(sp); 2515 m_eventManager.TriggerOnNewPresence(sp);
2530 2516
2531 sp.TeleportFlags = (TeleportFlags)aCircuit.teleportFlags; 2517 sp.TeleportFlags = (TPFlags)aCircuit.teleportFlags;
2532 2518
2533 // The first agent upon login is a root agent by design. 2519 // The first agent upon login is a root agent by design.
2534 // For this agent we will have to rez the attachments. 2520 // For this agent we will have to rez the attachments.
@@ -3070,11 +3056,11 @@ namespace OpenSim.Region.Framework.Scenes
3070 public override void RemoveClient(UUID agentID, bool closeChildAgents) 3056 public override void RemoveClient(UUID agentID, bool closeChildAgents)
3071 { 3057 {
3072 CheckHeartbeat(); 3058 CheckHeartbeat();
3073 bool childagentYN = false; 3059 bool isChildAgent = false;
3074 ScenePresence avatar = GetScenePresence(agentID); 3060 ScenePresence avatar = GetScenePresence(agentID);
3075 if (avatar != null) 3061 if (avatar != null)
3076 { 3062 {
3077 childagentYN = avatar.IsChildAgent; 3063 isChildAgent = avatar.IsChildAgent;
3078 3064
3079 if (avatar.ParentID != 0) 3065 if (avatar.ParentID != 0)
3080 { 3066 {
@@ -3085,9 +3071,9 @@ namespace OpenSim.Region.Framework.Scenes
3085 { 3071 {
3086 m_log.DebugFormat( 3072 m_log.DebugFormat(
3087 "[SCENE]: Removing {0} agent {1} from region {2}", 3073 "[SCENE]: Removing {0} agent {1} from region {2}",
3088 (childagentYN ? "child" : "root"), agentID, RegionInfo.RegionName); 3074 (isChildAgent ? "child" : "root"), agentID, RegionInfo.RegionName);
3089 3075
3090 m_sceneGraph.removeUserCount(!childagentYN); 3076 m_sceneGraph.removeUserCount(!isChildAgent);
3091 3077
3092 // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop 3078 // TODO: We shouldn't use closeChildAgents here - it's being used by the NPC module to stop
3093 // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI 3079 // unnecessary operations. This should go away once NPCs have no accompanying IClientAPI
@@ -3117,8 +3103,18 @@ namespace OpenSim.Region.Framework.Scenes
3117 { 3103 {
3118 m_eventManager.TriggerOnRemovePresence(agentID); 3104 m_eventManager.TriggerOnRemovePresence(agentID);
3119 3105
3120 if (AttachmentsModule != null && !avatar.IsChildAgent && avatar.PresenceType != PresenceType.Npc) 3106 if (AttachmentsModule != null && !isChildAgent && avatar.PresenceType != PresenceType.Npc)
3121 AttachmentsModule.SaveChangedAttachments(avatar); 3107 {
3108 IUserManagement uMan = RequestModuleInterface<IUserManagement>();
3109 // Don't save attachments for HG visitors, it
3110 // messes up their inventory. When a HG visitor logs
3111 // out on a foreign grid, their attachments will be
3112 // reloaded in the state they were in when they left
3113 // the home grid. This is best anyway as the visited
3114 // grid may use an incompatible script engine.
3115 if (uMan == null || uMan.IsLocalGridUser(avatar.UUID))
3116 AttachmentsModule.SaveChangedAttachments(avatar, false);
3117 }
3122 3118
3123 ForEachClient( 3119 ForEachClient(
3124 delegate(IClientAPI client) 3120 delegate(IClientAPI client)
@@ -3333,7 +3329,7 @@ namespace OpenSim.Region.Framework.Scenes
3333 { 3329 {
3334 // Let the SP know how we got here. This has a lot of interesting 3330 // Let the SP know how we got here. This has a lot of interesting
3335 // uses down the line. 3331 // uses down the line.
3336 sp.TeleportFlags = (TeleportFlags)teleportFlags; 3332 sp.TeleportFlags = (TPFlags)teleportFlags;
3337 3333
3338 if (sp.IsChildAgent) 3334 if (sp.IsChildAgent)
3339 { 3335 {
@@ -4867,93 +4863,6 @@ namespace OpenSim.Region.Framework.Scenes
4867 } 4863 }
4868 } 4864 }
4869 4865
4870 private void HandleDeleteObject(string module, string[] cmd)
4871 {
4872 if (cmd.Length < 3)
4873 return;
4874
4875 string mode = cmd[2];
4876 string o = "";
4877
4878 if (mode != "outside")
4879 {
4880 if (cmd.Length < 4)
4881 return;
4882
4883 o = cmd[3];
4884 }
4885
4886 List<SceneObjectGroup> deletes = new List<SceneObjectGroup>();
4887
4888 UUID match;
4889
4890 switch (mode)
4891 {
4892 case "owner":
4893 if (!UUID.TryParse(o, out match))
4894 return;
4895 ForEachSOG(delegate (SceneObjectGroup g)
4896 {
4897 if (g.OwnerID == match && !g.IsAttachment)
4898 deletes.Add(g);
4899 });
4900 break;
4901 case "creator":
4902 if (!UUID.TryParse(o, out match))
4903 return;
4904 ForEachSOG(delegate (SceneObjectGroup g)
4905 {
4906 if (g.RootPart.CreatorID == match && !g.IsAttachment)
4907 deletes.Add(g);
4908 });
4909 break;
4910 case "uuid":
4911 if (!UUID.TryParse(o, out match))
4912 return;
4913 ForEachSOG(delegate (SceneObjectGroup g)
4914 {
4915 if (g.UUID == match && !g.IsAttachment)
4916 deletes.Add(g);
4917 });
4918 break;
4919 case "name":
4920 ForEachSOG(delegate (SceneObjectGroup g)
4921 {
4922 if (g.RootPart.Name == o && !g.IsAttachment)
4923 deletes.Add(g);
4924 });
4925 break;
4926 case "outside":
4927 ForEachSOG(delegate (SceneObjectGroup g)
4928 {
4929 SceneObjectPart rootPart = g.RootPart;
4930 bool delete = false;
4931
4932 if (rootPart.GroupPosition.Z < 0.0 || rootPart.GroupPosition.Z > 10000.0)
4933 {
4934 delete = true;
4935 }
4936 else
4937 {
4938 ILandObject parcel = LandChannel.GetLandObject(rootPart.GroupPosition.X, rootPart.GroupPosition.Y);
4939
4940 if (parcel == null || parcel.LandData.Name == "NO LAND")
4941 delete = true;
4942 }
4943
4944 if (delete && !g.IsAttachment && !deletes.Contains(g))
4945 deletes.Add(g);
4946 });
4947 break;
4948 }
4949
4950 foreach (SceneObjectGroup g in deletes)
4951 {
4952 m_log.InfoFormat("[SCENE]: Deleting object {0}", g.UUID);
4953 DeleteSceneObject(g, false);
4954 }
4955 }
4956
4957 private void HandleReloadEstate(string module, string[] cmd) 4866 private void HandleReloadEstate(string module, string[] cmd)
4958 { 4867 {
4959 if (MainConsole.Instance.ConsoleScene == null || 4868 if (MainConsole.Instance.ConsoleScene == null ||
@@ -5076,6 +4985,36 @@ namespace OpenSim.Region.Framework.Scenes
5076 } 4985 }
5077 } 4986 }
5078 4987
4988 if (position == Vector3.Zero) // Teleport
4989 {
4990 if (!RegionInfo.EstateSettings.AllowDirectTeleport)
4991 {
4992 SceneObjectGroup telehub;
4993 if (RegionInfo.RegionSettings.TelehubObject != UUID.Zero && (telehub = GetSceneObjectGroup(RegionInfo.RegionSettings.TelehubObject)) != null)
4994 {
4995 List<SpawnPoint> spawnPoints = RegionInfo.RegionSettings.SpawnPoints();
4996 bool banned = true;
4997 foreach (SpawnPoint sp in spawnPoints)
4998 {
4999 Vector3 spawnPoint = sp.GetLocation(telehub.AbsolutePosition, telehub.GroupRotation);
5000 ILandObject land = LandChannel.GetLandObject(spawnPoint.X, spawnPoint.Y);
5001 if (land == null)
5002 continue;
5003 if (land.IsEitherBannedOrRestricted(agentID))
5004 continue;
5005 banned = false;
5006 break;
5007 }
5008
5009 if (banned)
5010 {
5011 reason = "No suitable landing point found";
5012 return false;
5013 }
5014 }
5015 }
5016 }
5017
5079 reason = String.Empty; 5018 reason = String.Empty;
5080 return true; 5019 return true;
5081 } 5020 }
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index f481e72..1487fac 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -41,12 +41,6 @@ namespace OpenSim.Region.Framework.Scenes
41{ 41{
42 public delegate void PhysicsCrash(); 42 public delegate void PhysicsCrash();
43 43
44 public delegate void ObjectDuplicateDelegate(EntityBase original, EntityBase clone);
45
46 public delegate void ObjectCreateDelegate(EntityBase obj);
47
48 public delegate void ObjectDeleteDelegate(EntityBase obj);
49
50 /// <summary> 44 /// <summary>
51 /// This class used to be called InnerScene and may not yet truly be a SceneGraph. The non scene graph components 45 /// This class used to be called InnerScene and may not yet truly be a SceneGraph. The non scene graph components
52 /// should be migrated out over time. 46 /// should be migrated out over time.
@@ -60,10 +54,6 @@ namespace OpenSim.Region.Framework.Scenes
60 protected internal event PhysicsCrash UnRecoverableError; 54 protected internal event PhysicsCrash UnRecoverableError;
61 private PhysicsCrash handlerPhysicsCrash = null; 55 private PhysicsCrash handlerPhysicsCrash = null;
62 56
63 public event ObjectDuplicateDelegate OnObjectDuplicate;
64 public event ObjectCreateDelegate OnObjectCreate;
65 public event ObjectDeleteDelegate OnObjectRemove;
66
67 #endregion 57 #endregion
68 58
69 #region Fields 59 #region Fields
@@ -364,11 +354,23 @@ namespace OpenSim.Region.Framework.Scenes
364 /// </returns> 354 /// </returns>
365 protected bool AddSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates) 355 protected bool AddSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates)
366 { 356 {
367 if (sceneObject == null || sceneObject.RootPart.UUID == UUID.Zero) 357 if (sceneObject.UUID == UUID.Zero)
358 {
359 m_log.ErrorFormat(
360 "[SCENEGRAPH]: Tried to add scene object {0} to {1} with illegal UUID of {2}",
361 sceneObject.Name, m_parentScene.RegionInfo.RegionName, UUID.Zero);
362
368 return false; 363 return false;
364 }
369 365
370 if (Entities.ContainsKey(sceneObject.UUID)) 366 if (Entities.ContainsKey(sceneObject.UUID))
367 {
368// m_log.DebugFormat(
369// "[SCENEGRAPH]: Scene graph for {0} already contains object {1} in AddSceneObject()",
370// m_parentScene.RegionInfo.RegionName, sceneObject.UUID);
371
371 return false; 372 return false;
373 }
372 374
373// m_log.DebugFormat( 375// m_log.DebugFormat(
374// "[SCENEGRAPH]: Adding scene object {0} {1}, with {2} parts on {3}", 376// "[SCENEGRAPH]: Adding scene object {0} {1}, with {2} parts on {3}",
@@ -405,9 +407,6 @@ namespace OpenSim.Region.Framework.Scenes
405 if (attachToBackup) 407 if (attachToBackup)
406 sceneObject.AttachToBackup(); 408 sceneObject.AttachToBackup();
407 409
408 if (OnObjectCreate != null)
409 OnObjectCreate(sceneObject);
410
411 lock (SceneObjectGroupsByFullID) 410 lock (SceneObjectGroupsByFullID)
412 SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; 411 SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject;
413 412
@@ -456,9 +455,6 @@ namespace OpenSim.Region.Framework.Scenes
456 if ((grp.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) 455 if ((grp.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics)
457 RemovePhysicalPrim(grp.PrimCount); 456 RemovePhysicalPrim(grp.PrimCount);
458 } 457 }
459
460 if (OnObjectRemove != null)
461 OnObjectRemove(Entities[uuid]);
462 458
463 lock (SceneObjectGroupsByFullID) 459 lock (SceneObjectGroupsByFullID)
464 SceneObjectGroupsByFullID.Remove(grp.UUID); 460 SceneObjectGroupsByFullID.Remove(grp.UUID);
@@ -1154,8 +1150,10 @@ namespace OpenSim.Region.Framework.Scenes
1154 /// <param name="action"></param> 1150 /// <param name="action"></param>
1155 protected internal void ForEachSOG(Action<SceneObjectGroup> action) 1151 protected internal void ForEachSOG(Action<SceneObjectGroup> action)
1156 { 1152 {
1157 // FIXME: Need to lock here, really. 1153 List<SceneObjectGroup> objlist;
1158 List<SceneObjectGroup> objlist = new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values); 1154 lock (SceneObjectGroupsByFullID)
1155 objlist = new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values);
1156
1159 foreach (SceneObjectGroup obj in objlist) 1157 foreach (SceneObjectGroup obj in objlist)
1160 { 1158 {
1161 try 1159 try
@@ -1164,7 +1162,7 @@ namespace OpenSim.Region.Framework.Scenes
1164 } 1162 }
1165 catch (Exception e) 1163 catch (Exception e)
1166 { 1164 {
1167 // Catch it and move on. This includes situations where splist has inconsistent info 1165 // Catch it and move on. This includes situations where objlist has inconsistent info
1168 m_log.WarnFormat( 1166 m_log.WarnFormat(
1169 "[SCENEGRAPH]: Problem processing action in ForEachSOG: {0} {1}", e.Message, e.StackTrace); 1167 "[SCENEGRAPH]: Problem processing action in ForEachSOG: {0} {1}", e.Message, e.StackTrace);
1170 } 1168 }
@@ -1399,10 +1397,10 @@ namespace OpenSim.Region.Framework.Scenes
1399 /// <summary> 1397 /// <summary>
1400 /// Update the texture entry of the given prim. 1398 /// Update the texture entry of the given prim.
1401 /// </summary> 1399 /// </summary>
1402 /// 1400 /// <remarks>
1403 /// A texture entry is an object that contains details of all the textures of the prim's face. In this case, 1401 /// A texture entry is an object that contains details of all the textures of the prim's face. In this case,
1404 /// the texture is given in its byte serialized form. 1402 /// the texture is given in its byte serialized form.
1405 /// 1403 /// </remarks>
1406 /// <param name="localID"></param> 1404 /// <param name="localID"></param>
1407 /// <param name="texture"></param> 1405 /// <param name="texture"></param>
1408 /// <param name="remoteClient"></param> 1406 /// <param name="remoteClient"></param>
@@ -1980,9 +1978,6 @@ namespace OpenSim.Region.Framework.Scenes
1980 // required for physics to update it's position 1978 // required for physics to update it's position
1981 copy.AbsolutePosition = copy.AbsolutePosition; 1979 copy.AbsolutePosition = copy.AbsolutePosition;
1982 1980
1983 if (OnObjectDuplicate != null)
1984 OnObjectDuplicate(original, copy);
1985
1986 return copy; 1981 return copy;
1987 } 1982 }
1988 } 1983 }
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
index 905ecc9..f173c95 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
@@ -83,13 +83,12 @@ namespace OpenSim.Region.Framework.Scenes
83 /// <summary> 83 /// <summary>
84 /// Add an inventory item from a user's inventory to a prim in this scene object. 84 /// Add an inventory item from a user's inventory to a prim in this scene object.
85 /// </summary> 85 /// </summary>
86 /// <param name="remoteClient">The client adding the item.</param> 86 /// <param name="agentID">The agent adding the item.</param>
87 /// <param name="localID">The local ID of the part receiving the add.</param> 87 /// <param name="localID">The local ID of the part receiving the add.</param>
88 /// <param name="item">The user inventory item being added.</param> 88 /// <param name="item">The user inventory item being added.</param>
89 /// <param name="copyItemID">The item UUID that should be used by the new item.</param> 89 /// <param name="copyItemID">The item UUID that should be used by the new item.</param>
90 /// <returns></returns> 90 /// <returns></returns>
91 public bool AddInventoryItem(IClientAPI remoteClient, uint localID, 91 public bool AddInventoryItem(UUID agentID, uint localID, InventoryItemBase item, UUID copyItemID)
92 InventoryItemBase item, UUID copyItemID)
93 { 92 {
94// m_log.DebugFormat( 93// m_log.DebugFormat(
95// "[PRIM INVENTORY]: Adding inventory item {0} from {1} to part with local ID {2}", 94// "[PRIM INVENTORY]: Adding inventory item {0} from {1} to part with local ID {2}",
@@ -111,9 +110,7 @@ namespace OpenSim.Region.Framework.Scenes
111 taskItem.Type = item.AssetType; 110 taskItem.Type = item.AssetType;
112 taskItem.InvType = item.InvType; 111 taskItem.InvType = item.InvType;
113 112
114 if (remoteClient != null && 113 if (agentID != part.OwnerID && m_scene.Permissions.PropagatePermissions())
115 remoteClient.AgentId != part.OwnerID &&
116 m_scene.Permissions.PropagatePermissions())
117 { 114 {
118 taskItem.BasePermissions = item.BasePermissions & 115 taskItem.BasePermissions = item.BasePermissions &
119 item.NextPermissions; 116 item.NextPermissions;
@@ -148,11 +145,7 @@ namespace OpenSim.Region.Framework.Scenes
148// taskItem.SaleType = item.SaleType; 145// taskItem.SaleType = item.SaleType;
149 taskItem.CreationDate = (uint)item.CreationDate; 146 taskItem.CreationDate = (uint)item.CreationDate;
150 147
151 bool addFromAllowedDrop = false; 148 bool addFromAllowedDrop = agentID != part.OwnerID;
152 if (remoteClient != null)
153 {
154 addFromAllowedDrop = remoteClient.AgentId != part.OwnerID;
155 }
156 149
157 part.Inventory.AddInventoryItem(taskItem, addFromAllowedDrop); 150 part.Inventory.AddInventoryItem(taskItem, addFromAllowedDrop);
158 151
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 8860764..e7f2fdb 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -264,6 +264,12 @@ namespace OpenSim.Region.Framework.Scenes
264 set { RootPart.Name = value; } 264 set { RootPart.Name = value; }
265 } 265 }
266 266
267 public string Description
268 {
269 get { return RootPart.Description; }
270 set { RootPart.Description = value; }
271 }
272
267 /// <summary> 273 /// <summary>
268 /// Added because the Parcel code seems to use it 274 /// Added because the Parcel code seems to use it
269 /// but not sure a object should have this 275 /// but not sure a object should have this
@@ -441,6 +447,12 @@ namespace OpenSim.Region.Framework.Scenes
441 } 447 }
442 } 448 }
443 449
450 public UUID LastOwnerID
451 {
452 get { return m_rootPart.LastOwnerID; }
453 set { m_rootPart.LastOwnerID = value; }
454 }
455
444 public UUID OwnerID 456 public UUID OwnerID
445 { 457 {
446 get { return m_rootPart.OwnerID; } 458 get { return m_rootPart.OwnerID; }
@@ -1613,12 +1625,6 @@ namespace OpenSim.Region.Framework.Scenes
1613 RootPart.PhysActor.PIDActive = false; 1625 RootPart.PhysActor.PIDActive = false;
1614 } 1626 }
1615 1627
1616 public void stopLookAt()
1617 {
1618 if (RootPart.PhysActor != null)
1619 RootPart.PhysActor.APIDActive = false;
1620 }
1621
1622 /// <summary> 1628 /// <summary>
1623 /// Uses a PID to attempt to clamp the object on the Z axis at the given height over tau seconds. 1629 /// Uses a PID to attempt to clamp the object on the Z axis at the given height over tau seconds.
1624 /// </summary> 1630 /// </summary>
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 8e59abf..9b660b6 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -217,11 +217,10 @@ namespace OpenSim.Region.Framework.Scenes
217 217
218 public Quaternion SpinOldOrientation = Quaternion.Identity; 218 public Quaternion SpinOldOrientation = Quaternion.Identity;
219 219
220 public Quaternion m_APIDTarget = Quaternion.Identity; 220 protected int m_APIDIterations = 0;
221 221 protected Quaternion m_APIDTarget = Quaternion.Identity;
222 public float m_APIDDamp = 0; 222 protected float m_APIDDamp = 0;
223 223 protected float m_APIDStrength = 0;
224 public float m_APIDStrength = 0;
225 224
226 /// <summary> 225 /// <summary>
227 /// This part's inventory 226 /// This part's inventory
@@ -394,7 +393,7 @@ namespace OpenSim.Region.Framework.Scenes
394 393
395 private string m_creatorData = string.Empty; 394 private string m_creatorData = string.Empty;
396 /// <summary> 395 /// <summary>
397 /// Data about the creator in the form profile_url;name 396 /// Data about the creator in the form home_url;name
398 /// </summary> 397 /// </summary>
399 public string CreatorData 398 public string CreatorData
400 { 399 {
@@ -405,7 +404,7 @@ namespace OpenSim.Region.Framework.Scenes
405 /// <summary> 404 /// <summary>
406 /// Used by the DB layer to retrieve / store the entire user identification. 405 /// Used by the DB layer to retrieve / store the entire user identification.
407 /// The identification can either be a simple UUID or a string of the form 406 /// The identification can either be a simple UUID or a string of the form
408 /// uuid[;profile_url[;name]] 407 /// uuid[;home_url[;name]]
409 /// </summary> 408 /// </summary>
410 public string CreatorIdentification 409 public string CreatorIdentification
411 { 410 {
@@ -563,22 +562,21 @@ namespace OpenSim.Region.Framework.Scenes
563 } 562 }
564 } 563 }
565 564
566 565 protected Quaternion APIDTarget
567 public Quaternion APIDTarget
568 { 566 {
569 get { return m_APIDTarget; } 567 get { return m_APIDTarget; }
570 set { m_APIDTarget = value; } 568 set { m_APIDTarget = value; }
571 } 569 }
572 570
573 571
574 public float APIDDamp 572 protected float APIDDamp
575 { 573 {
576 get { return m_APIDDamp; } 574 get { return m_APIDDamp; }
577 set { m_APIDDamp = value; } 575 set { m_APIDDamp = value; }
578 } 576 }
579 577
580 578
581 public float APIDStrength 579 protected float APIDStrength
582 { 580 {
583 get { return m_APIDStrength; } 581 get { return m_APIDStrength; }
584 set { m_APIDStrength = value; } 582 set { m_APIDStrength = value; }
@@ -1946,19 +1944,13 @@ namespace OpenSim.Region.Framework.Scenes
1946 public Vector3 GetWorldPosition() 1944 public Vector3 GetWorldPosition()
1947 { 1945 {
1948 Quaternion parentRot = ParentGroup.RootPart.RotationOffset; 1946 Quaternion parentRot = ParentGroup.RootPart.RotationOffset;
1949
1950 Vector3 axPos = OffsetPosition; 1947 Vector3 axPos = OffsetPosition;
1951
1952 axPos *= parentRot; 1948 axPos *= parentRot;
1953 Vector3 translationOffsetPosition = axPos; 1949 Vector3 translationOffsetPosition = axPos;
1954 1950 if(_parentID == 0)
1955// m_log.DebugFormat("[SCENE OBJECT PART]: Found group pos {0} for part {1}", GroupPosition, Name); 1951 return GroupPosition;
1956 1952 else
1957 Vector3 worldPos = GroupPosition + translationOffsetPosition; 1953 return ParentGroup.AbsolutePosition + translationOffsetPosition;
1958
1959// m_log.DebugFormat("[SCENE OBJECT PART]: Found world pos {0} for part {1}", worldPos, Name);
1960
1961 return worldPos;
1962 } 1954 }
1963 1955
1964 /// <summary> 1956 /// <summary>
@@ -2689,11 +2681,6 @@ namespace OpenSim.Region.Framework.Scenes
2689 2681
2690 public void RotLookAt(Quaternion target, float strength, float damping) 2682 public void RotLookAt(Quaternion target, float strength, float damping)
2691 { 2683 {
2692 rotLookAt(target, strength, damping);
2693 }
2694
2695 public void rotLookAt(Quaternion target, float strength, float damping)
2696 {
2697 if (ParentGroup.IsAttachment) 2684 if (ParentGroup.IsAttachment)
2698 { 2685 {
2699 /* 2686 /*
@@ -2708,17 +2695,26 @@ namespace OpenSim.Region.Framework.Scenes
2708 APIDDamp = damping; 2695 APIDDamp = damping;
2709 APIDStrength = strength; 2696 APIDStrength = strength;
2710 APIDTarget = target; 2697 APIDTarget = target;
2698
2699 if (APIDStrength <= 0)
2700 {
2701 m_log.WarnFormat("[SceneObjectPart] Invalid rotation strength {0}",APIDStrength);
2702 return;
2703 }
2704
2705 m_APIDIterations = 1 + (int)(Math.PI * APIDStrength);
2711 } 2706 }
2707
2708 // Necessary to get the lookat deltas applied
2709 ParentGroup.QueueForUpdateCheck();
2712 } 2710 }
2713 2711
2714 public void startLookAt(Quaternion rot, float damp, float strength) 2712 public void StartLookAt(Quaternion target, float strength, float damping)
2715 { 2713 {
2716 APIDDamp = damp; 2714 RotLookAt(target,strength,damping);
2717 APIDStrength = strength;
2718 APIDTarget = rot;
2719 } 2715 }
2720 2716
2721 public void stopLookAt() 2717 public void StopLookAt()
2722 { 2718 {
2723 APIDTarget = Quaternion.Identity; 2719 APIDTarget = Quaternion.Identity;
2724 } 2720 }
@@ -3413,13 +3409,6 @@ namespace OpenSim.Region.Framework.Scenes
3413 } 3409 }
3414 } 3410 }
3415 3411
3416 public void StopLookAt()
3417 {
3418 ParentGroup.stopLookAt();
3419
3420 ParentGroup.ScheduleGroupForTerseUpdate();
3421 }
3422
3423 /// <summary> 3412 /// <summary>
3424 /// Set the text displayed for this part. 3413 /// Set the text displayed for this part.
3425 /// </summary> 3414 /// </summary>
@@ -4521,10 +4510,18 @@ namespace OpenSim.Region.Framework.Scenes
4521 /// <summary> 4510 /// <summary>
4522 /// Update the texture entry for this part. 4511 /// Update the texture entry for this part.
4523 /// </summary> 4512 /// </summary>
4524 /// <param name="textureEntry"></param> 4513 /// <param name="serializedTextureEntry"></param>
4525 public void UpdateTextureEntry(byte[] textureEntry) 4514 public void UpdateTextureEntry(byte[] serializedTextureEntry)
4515 {
4516 UpdateTextureEntry(new Primitive.TextureEntry(serializedTextureEntry, 0, serializedTextureEntry.Length));
4517 }
4518
4519 /// <summary>
4520 /// Update the texture entry for this part.
4521 /// </summary>
4522 /// <param name="newTex"></param>
4523 public void UpdateTextureEntry(Primitive.TextureEntry newTex)
4526 { 4524 {
4527 Primitive.TextureEntry newTex = new Primitive.TextureEntry(textureEntry, 0, textureEntry.Length);
4528 Primitive.TextureEntry oldTex = Shape.Textures; 4525 Primitive.TextureEntry oldTex = Shape.Textures;
4529 4526
4530 Changed changeFlags = 0; 4527 Changed changeFlags = 0;
@@ -4556,7 +4553,7 @@ namespace OpenSim.Region.Framework.Scenes
4556 break; 4553 break;
4557 } 4554 }
4558 4555
4559 m_shape.TextureEntry = textureEntry; 4556 m_shape.TextureEntry = newTex.GetBytes();
4560 if (changeFlags != 0) 4557 if (changeFlags != 0)
4561 TriggerScriptChangedEvent(changeFlags); 4558 TriggerScriptChangedEvent(changeFlags);
4562 UpdateFlag = UpdateRequired.FULL; 4559 UpdateFlag = UpdateRequired.FULL;
@@ -4727,24 +4724,20 @@ namespace OpenSim.Region.Framework.Scenes
4727 { 4724 {
4728 if (APIDTarget != Quaternion.Identity) 4725 if (APIDTarget != Quaternion.Identity)
4729 { 4726 {
4730 if (Single.IsNaN(APIDTarget.W) == true) 4727 if (m_APIDIterations <= 1)
4731 { 4728 {
4729 UpdateRotation(APIDTarget);
4732 APIDTarget = Quaternion.Identity; 4730 APIDTarget = Quaternion.Identity;
4733 return; 4731 return;
4734 } 4732 }
4735 Quaternion rot = RotationOffset; 4733
4736 Quaternion dir = (rot - APIDTarget); 4734 Quaternion rot = Quaternion.Slerp(RotationOffset,APIDTarget,1.0f/(float)m_APIDIterations);
4737 float speed = ((APIDStrength / APIDDamp) * (float)(Math.PI / 180.0f));
4738 if (dir.Z > speed)
4739 {
4740 rot.Z -= speed;
4741 }
4742 if (dir.Z < -speed)
4743 {
4744 rot.Z += speed;
4745 }
4746 rot.Normalize();
4747 UpdateRotation(rot); 4735 UpdateRotation(rot);
4736
4737 m_APIDIterations--;
4738
4739 // This ensures that we'll check this object on the next iteration
4740 ParentGroup.QueueForUpdateCheck();
4748 } 4741 }
4749 } 4742 }
4750 catch (Exception ex) 4743 catch (Exception ex)
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 42cd4be..5c56150 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -40,6 +40,7 @@ using OpenSim.Region.Framework.Scenes.Types;
40using OpenSim.Region.Physics.Manager; 40using OpenSim.Region.Physics.Manager;
41using GridRegion = OpenSim.Services.Interfaces.GridRegion; 41using GridRegion = OpenSim.Services.Interfaces.GridRegion;
42using OpenSim.Services.Interfaces; 42using OpenSim.Services.Interfaces;
43using TeleportFlags = OpenSim.Framework.Constants.TeleportFlags;
43 44
44namespace OpenSim.Region.Framework.Scenes 45namespace OpenSim.Region.Framework.Scenes
45{ 46{
@@ -892,6 +893,8 @@ namespace OpenSim.Region.Framework.Scenes
892 pos.Y = crossedBorder.BorderLine.Z - 1; 893 pos.Y = crossedBorder.BorderLine.Z - 1;
893 } 894 }
894 895
896 CheckAndAdjustLandingPoint(ref pos);
897
895 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) 898 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
896 { 899 {
897 m_log.WarnFormat( 900 m_log.WarnFormat(
@@ -1056,6 +1059,7 @@ namespace OpenSim.Region.Framework.Scenes
1056 bool isFlying = Flying; 1059 bool isFlying = Flying;
1057 RemoveFromPhysicalScene(); 1060 RemoveFromPhysicalScene();
1058 Velocity = Vector3.Zero; 1061 Velocity = Vector3.Zero;
1062 CheckLandingPoint(ref pos);
1059 AbsolutePosition = pos; 1063 AbsolutePosition = pos;
1060 AddToPhysicalScene(isFlying); 1064 AddToPhysicalScene(isFlying);
1061 1065
@@ -1066,6 +1070,7 @@ namespace OpenSim.Region.Framework.Scenes
1066 { 1070 {
1067 bool isFlying = Flying; 1071 bool isFlying = Flying;
1068 RemoveFromPhysicalScene(); 1072 RemoveFromPhysicalScene();
1073 CheckLandingPoint(ref pos);
1069 AbsolutePosition = pos; 1074 AbsolutePosition = pos;
1070 AddToPhysicalScene(isFlying); 1075 AddToPhysicalScene(isFlying);
1071 1076
@@ -1180,6 +1185,7 @@ namespace OpenSim.Region.Framework.Scenes
1180 client.Name, Scene.RegionInfo.RegionName, AbsolutePosition); 1185 client.Name, Scene.RegionInfo.RegionName, AbsolutePosition);
1181 1186
1182 Vector3 look = Velocity; 1187 Vector3 look = Velocity;
1188
1183 if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) 1189 if ((look.X == 0) && (look.Y == 0) && (look.Z == 0))
1184 { 1190 {
1185 look = new Vector3(0.99f, 0.042f, 0); 1191 look = new Vector3(0.99f, 0.042f, 0);
@@ -1206,7 +1212,7 @@ namespace OpenSim.Region.Framework.Scenes
1206 m_callbackURI = null; 1212 m_callbackURI = null;
1207 } 1213 }
1208 1214
1209 //m_log.DebugFormat("[SCENE PRESENCE] Completed movement"); 1215// m_log.DebugFormat("[SCENE PRESENCE] Completed movement");
1210 1216
1211 ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look); 1217 ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look);
1212 ValidateAndSendAppearanceAndAgentData(); 1218 ValidateAndSendAppearanceAndAgentData();
@@ -1274,8 +1280,8 @@ namespace OpenSim.Region.Framework.Scenes
1274 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) 1280 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
1275 { 1281 {
1276// m_log.DebugFormat( 1282// m_log.DebugFormat(
1277// "[SCENE PRESENCE]: In {0} received agent update from {1}", 1283// "[SCENE PRESENCE]: In {0} received agent update from {1}, flags {2}",
1278// Scene.RegionInfo.RegionName, remoteClient.Name); 1284// Scene.RegionInfo.RegionName, remoteClient.Name, agentData.ControlFlags);
1279 1285
1280 if (IsChildAgent) 1286 if (IsChildAgent)
1281 { 1287 {
@@ -2312,6 +2318,8 @@ namespace OpenSim.Region.Framework.Scenes
2312 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2318 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
2313 public void AddNewMovement(Vector3 vec) 2319 public void AddNewMovement(Vector3 vec)
2314 { 2320 {
2321// m_log.DebugFormat("[SCENE PRESENCE]: Adding new movement {0} for {1}", vec, Name);
2322
2315 Vector3 direc = vec * Rotation; 2323 Vector3 direc = vec * Rotation;
2316 direc.Normalize(); 2324 direc.Normalize();
2317 2325
@@ -3801,5 +3809,146 @@ namespace OpenSim.Region.Framework.Scenes
3801 m_reprioritization_called = false; 3809 m_reprioritization_called = false;
3802 } 3810 }
3803 } 3811 }
3812
3813 private void CheckLandingPoint(ref Vector3 pos)
3814 {
3815 // Never constrain lures
3816 if ((TeleportFlags & TeleportFlags.ViaLure) != 0)
3817 return;
3818
3819 if (m_scene.RegionInfo.EstateSettings.AllowDirectTeleport)
3820 return;
3821
3822 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
3823
3824 if (land.LandData.LandingType == (byte)LandingType.LandingPoint &&
3825 land.LandData.UserLocation != Vector3.Zero &&
3826 land.LandData.OwnerID != m_uuid &&
3827 (!m_scene.Permissions.IsGod(m_uuid)) &&
3828 (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid)))
3829 {
3830 float curr = Vector3.Distance(AbsolutePosition, pos);
3831 if (Vector3.Distance(land.LandData.UserLocation, pos) < curr)
3832 pos = land.LandData.UserLocation;
3833 else
3834 ControllingClient.SendAlertMessage("Can't teleport closer to destination");
3835 }
3836 }
3837
3838 private void CheckAndAdjustTelehub(SceneObjectGroup telehub, ref Vector3 pos)
3839 {
3840 if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) ==
3841 (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) ||
3842 (m_teleportFlags & TeleportFlags.ViaLandmark) != 0 ||
3843 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 ||
3844 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0)
3845 {
3846 if (GodLevel < 200 &&
3847 ((!m_scene.Permissions.IsGod(m_uuid) &&
3848 !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid)) ||
3849 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 ||
3850 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0))
3851 {
3852 SpawnPoint[] spawnPoints = m_scene.RegionInfo.RegionSettings.SpawnPoints().ToArray();
3853 if (spawnPoints.Length == 0)
3854 return;
3855
3856 float distance = 9999;
3857 int closest = -1;
3858
3859 for (int i = 0 ; i < spawnPoints.Length ; i++)
3860 {
3861 Vector3 spawnPosition = spawnPoints[i].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation);
3862 Vector3 offset = spawnPosition - pos;
3863 float d = Vector3.Mag(offset);
3864 if (d >= distance)
3865 continue;
3866 ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y);
3867 if (land == null)
3868 continue;
3869 if (land.IsEitherBannedOrRestricted(UUID))
3870 continue;
3871 distance = d;
3872 closest = i;
3873 }
3874 if (closest == -1)
3875 return;
3876
3877 pos = spawnPoints[closest].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation);
3878 }
3879 }
3880 }
3881
3882 private void CheckAndAdjustLandingPoint(ref Vector3 pos)
3883 {
3884 SceneObjectGroup telehub = null;
3885 if (m_scene.RegionInfo.RegionSettings.TelehubObject != UUID.Zero && (telehub = m_scene.GetSceneObjectGroup(m_scene.RegionInfo.RegionSettings.TelehubObject)) != null)
3886 {
3887 if (!m_scene.RegionInfo.EstateSettings.AllowDirectTeleport)
3888 {
3889 CheckAndAdjustTelehub(telehub, ref pos);
3890 return;
3891 }
3892 }
3893
3894 ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y);
3895 if (land != null)
3896 {
3897 if (Scene.DEBUG)
3898 TeleportFlagsDebug();
3899
3900 // If we come in via login, landmark or map, we want to
3901 // honor landing points. If we come in via Lure, we want
3902 // to ignore them.
3903 if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) ==
3904 (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) ||
3905 (m_teleportFlags & TeleportFlags.ViaLandmark) != 0 ||
3906 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 ||
3907 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0)
3908 {
3909 // Don't restrict gods, estate managers, or land owners to
3910 // the TP point. This behaviour mimics agni.
3911 if (land.LandData.LandingType == (byte)LandingType.LandingPoint &&
3912 land.LandData.UserLocation != Vector3.Zero &&
3913 GodLevel < 200 &&
3914 ((land.LandData.OwnerID != m_uuid &&
3915 !m_scene.Permissions.IsGod(m_uuid) &&
3916 !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid)) ||
3917 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 ||
3918 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0))
3919 {
3920 pos = land.LandData.UserLocation;
3921 }
3922 }
3923
3924 land.SendLandUpdateToClient(ControllingClient);
3925 }
3926 }
3927
3928 private void TeleportFlagsDebug() {
3929
3930 // Some temporary debugging help to show all the TeleportFlags we have...
3931 bool HG = false;
3932 if((m_teleportFlags & TeleportFlags.ViaHGLogin) == TeleportFlags.ViaHGLogin)
3933 HG = true;
3934
3935 m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************");
3936
3937 uint i = 0u;
3938 for (int x = 0; x <= 30 ; x++, i = 1u << x)
3939 {
3940 i = 1u << x;
3941
3942 if((m_teleportFlags & (TeleportFlags)i) == (TeleportFlags)i)
3943 if (HG == false)
3944 m_log.InfoFormat("[SCENE PRESENCE]: Teleport Flags include {0}", ((TeleportFlags) i).ToString());
3945 else
3946 m_log.InfoFormat("[SCENE PRESENCE]: HG Teleport Flags include {0}", ((TeleportFlags)i).ToString());
3947 }
3948
3949 m_log.InfoFormat("[SCENE PRESENCE]: TELEPORT ******************");
3950
3951 }
3952
3804 } 3953 }
3805} 3954}
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
index bca49f7..3a08271 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
@@ -54,7 +54,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
54 /// Deserialize a scene object from the original xml format 54 /// Deserialize a scene object from the original xml format
55 /// </summary> 55 /// </summary>
56 /// <param name="xmlData"></param> 56 /// <param name="xmlData"></param>
57 /// <returns></returns> 57 /// <returns>The scene object deserialized. Null on failure.</returns>
58 public static SceneObjectGroup FromOriginalXmlFormat(string xmlData) 58 public static SceneObjectGroup FromOriginalXmlFormat(string xmlData)
59 { 59 {
60 //m_log.DebugFormat("[SOG]: Starting deserialization of SOG"); 60 //m_log.DebugFormat("[SOG]: Starting deserialization of SOG");
@@ -1134,12 +1134,12 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1134 1134
1135 if (sop.CreatorData != null && sop.CreatorData != string.Empty) 1135 if (sop.CreatorData != null && sop.CreatorData != string.Empty)
1136 writer.WriteElementString("CreatorData", sop.CreatorData); 1136 writer.WriteElementString("CreatorData", sop.CreatorData);
1137 else if (options.ContainsKey("profile")) 1137 else if (options.ContainsKey("home"))
1138 { 1138 {
1139 if (m_UserManagement == null) 1139 if (m_UserManagement == null)
1140 m_UserManagement = sop.ParentGroup.Scene.RequestModuleInterface<IUserManagement>(); 1140 m_UserManagement = sop.ParentGroup.Scene.RequestModuleInterface<IUserManagement>();
1141 string name = m_UserManagement.GetUserName(sop.CreatorID); 1141 string name = m_UserManagement.GetUserName(sop.CreatorID);
1142 writer.WriteElementString("CreatorData", (string)options["profile"] + "/" + sop.CreatorID + ";" + name); 1142 writer.WriteElementString("CreatorData", (string)options["home"] + ";" + name);
1143 } 1143 }
1144 1144
1145 WriteUUID(writer, "FolderID", sop.FolderID, options); 1145 WriteUUID(writer, "FolderID", sop.FolderID, options);
@@ -1192,8 +1192,13 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1192 writer.WriteElementString("ObjectSaleType", sop.ObjectSaleType.ToString()); 1192 writer.WriteElementString("ObjectSaleType", sop.ObjectSaleType.ToString());
1193 writer.WriteElementString("OwnershipCost", sop.OwnershipCost.ToString()); 1193 writer.WriteElementString("OwnershipCost", sop.OwnershipCost.ToString());
1194 WriteUUID(writer, "GroupID", sop.GroupID, options); 1194 WriteUUID(writer, "GroupID", sop.GroupID, options);
1195 WriteUUID(writer, "OwnerID", sop.OwnerID, options); 1195
1196 WriteUUID(writer, "LastOwnerID", sop.LastOwnerID, options); 1196 UUID ownerID = options.ContainsKey("wipe-owners") ? UUID.Zero : sop.OwnerID;
1197 WriteUUID(writer, "OwnerID", ownerID, options);
1198
1199 UUID lastOwnerID = options.ContainsKey("wipe-owners") ? UUID.Zero : sop.LastOwnerID;
1200 WriteUUID(writer, "LastOwnerID", lastOwnerID, options);
1201
1197 writer.WriteElementString("BaseMask", sop.BaseMask.ToString()); 1202 writer.WriteElementString("BaseMask", sop.BaseMask.ToString());
1198 writer.WriteElementString("OwnerMask", sop.OwnerMask.ToString()); 1203 writer.WriteElementString("OwnerMask", sop.OwnerMask.ToString());
1199 writer.WriteElementString("GroupMask", sop.GroupMask.ToString()); 1204 writer.WriteElementString("GroupMask", sop.GroupMask.ToString());
@@ -1277,17 +1282,16 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1277 writer.WriteElementString("BasePermissions", item.BasePermissions.ToString()); 1282 writer.WriteElementString("BasePermissions", item.BasePermissions.ToString());
1278 writer.WriteElementString("CreationDate", item.CreationDate.ToString()); 1283 writer.WriteElementString("CreationDate", item.CreationDate.ToString());
1279 1284
1280
1281 WriteUUID(writer, "CreatorID", item.CreatorID, options); 1285 WriteUUID(writer, "CreatorID", item.CreatorID, options);
1282 1286
1283 if (item.CreatorData != null && item.CreatorData != string.Empty) 1287 if (item.CreatorData != null && item.CreatorData != string.Empty)
1284 writer.WriteElementString("CreatorData", item.CreatorData); 1288 writer.WriteElementString("CreatorData", item.CreatorData);
1285 else if (options.ContainsKey("profile")) 1289 else if (options.ContainsKey("home"))
1286 { 1290 {
1287 if (m_UserManagement == null) 1291 if (m_UserManagement == null)
1288 m_UserManagement = scene.RequestModuleInterface<IUserManagement>(); 1292 m_UserManagement = scene.RequestModuleInterface<IUserManagement>();
1289 string name = m_UserManagement.GetUserName(item.CreatorID); 1293 string name = m_UserManagement.GetUserName(item.CreatorID);
1290 writer.WriteElementString("CreatorData", (string)options["profile"] + "/" + item.CreatorID + ";" + name); 1294 writer.WriteElementString("CreatorData", (string)options["home"] + ";" + name);
1291 } 1295 }
1292 1296
1293 writer.WriteElementString("Description", item.Description); 1297 writer.WriteElementString("Description", item.Description);
@@ -1298,10 +1302,16 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1298 writer.WriteElementString("InvType", item.InvType.ToString()); 1302 writer.WriteElementString("InvType", item.InvType.ToString());
1299 WriteUUID(writer, "ItemID", item.ItemID, options); 1303 WriteUUID(writer, "ItemID", item.ItemID, options);
1300 WriteUUID(writer, "OldItemID", item.OldItemID, options); 1304 WriteUUID(writer, "OldItemID", item.OldItemID, options);
1301 WriteUUID(writer, "LastOwnerID", item.LastOwnerID, options); 1305
1306 UUID lastOwnerID = options.ContainsKey("wipe-owners") ? UUID.Zero : item.LastOwnerID;
1307 WriteUUID(writer, "LastOwnerID", lastOwnerID, options);
1308
1302 writer.WriteElementString("Name", item.Name); 1309 writer.WriteElementString("Name", item.Name);
1303 writer.WriteElementString("NextPermissions", item.NextPermissions.ToString()); 1310 writer.WriteElementString("NextPermissions", item.NextPermissions.ToString());
1304 WriteUUID(writer, "OwnerID", item.OwnerID, options); 1311
1312 UUID ownerID = options.ContainsKey("wipe-owners") ? UUID.Zero : item.OwnerID;
1313 WriteUUID(writer, "OwnerID", ownerID, options);
1314
1305 writer.WriteElementString("CurrentPermissions", item.CurrentPermissions.ToString()); 1315 writer.WriteElementString("CurrentPermissions", item.CurrentPermissions.ToString());
1306 WriteUUID(writer, "ParentID", item.ParentID, options); 1316 WriteUUID(writer, "ParentID", item.ParentID, options);
1307 WriteUUID(writer, "ParentPartID", item.ParentPartID, options); 1317 WriteUUID(writer, "ParentPartID", item.ParentPartID, options);
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectScriptTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectScriptTests.cs
new file mode 100644
index 0000000..6f99abd
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectScriptTests.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
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using NUnit.Framework;
32using OpenMetaverse;
33using OpenSim.Framework;
34using OpenSim.Framework.Communications;
35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.Framework.Scenes;
37using OpenSim.Tests.Common;
38using OpenSim.Tests.Common.Mock;
39
40namespace OpenSim.Region.Framework.Scenes.Tests
41{
42 [TestFixture]
43 public class SceneObjectScriptTests
44 {
45 [Test]
46 public void TestAddScript()
47 {
48 TestHelpers.InMethod();
49// log4net.Config.XmlConfigurator.Configure();
50
51 UUID userId = TestHelpers.ParseTail(0x1);
52 UUID itemId = TestHelpers.ParseTail(0x2);
53 string itemName = "Test Script Item";
54
55 Scene scene = SceneHelpers.SetupScene();
56 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId);
57 scene.AddNewSceneObject(so, true);
58
59 InventoryItemBase itemTemplate = new InventoryItemBase();
60 itemTemplate.Name = itemName;
61 itemTemplate.Folder = so.UUID;
62 itemTemplate.InvType = (int)InventoryType.LSL;
63
64 SceneObjectPart partWhereScriptAdded = scene.RezNewScript(userId, itemTemplate);
65
66 Assert.That(partWhereScriptAdded, Is.Not.Null);
67
68 IEntityInventory primInventory = partWhereScriptAdded.Inventory;
69 Assert.That(primInventory.GetInventoryList().Count, Is.EqualTo(1));
70 Assert.That(primInventory.ContainsScripts(), Is.True);
71
72 IList<TaskInventoryItem> primItems = primInventory.GetInventoryItems(itemName);
73 Assert.That(primItems.Count, Is.EqualTo(1));
74 }
75 }
76} \ No newline at end of file
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
index 32de85f..bbf3729 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
@@ -658,6 +658,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
658 public event ModifyTerrain OnModifyTerrain; 658 public event ModifyTerrain OnModifyTerrain;
659 public event BakeTerrain OnBakeTerrain; 659 public event BakeTerrain OnBakeTerrain;
660 public event EstateChangeInfo OnEstateChangeInfo; 660 public event EstateChangeInfo OnEstateChangeInfo;
661 public event EstateManageTelehub OnEstateManageTelehub;
661 public event SetAppearance OnSetAppearance; 662 public event SetAppearance OnSetAppearance;
662 public event AvatarNowWearing OnAvatarNowWearing; 663 public event AvatarNowWearing OnAvatarNowWearing;
663 public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv; 664 public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv;
@@ -1530,6 +1531,11 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
1530 1531
1531 } 1532 }
1532 1533
1534 public void SendTelehubInfo(UUID ObjectID, string ObjectName, Vector3 ObjectPos, Quaternion ObjectRot, List<Vector3> SpawnPoint)
1535 {
1536
1537 }
1538
1533 public void SendMapItemReply(mapItemReply[] replies, uint mapitemtype, uint flags) 1539 public void SendMapItemReply(mapItemReply[] replies, uint mapitemtype, uint flags)
1534 { 1540 {
1535 1541
diff --git a/OpenSim/Region/OptionalModules/Agent/TextureSender/J2KDecoderCommandModule.cs b/OpenSim/Region/OptionalModules/Agent/TextureSender/J2KDecoderCommandModule.cs
new file mode 100644
index 0000000..439096a
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Agent/TextureSender/J2KDecoderCommandModule.cs
@@ -0,0 +1,155 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.IO;
31using System.Reflection;
32using System.Text;
33using log4net;
34using Mono.Addins;
35using Nini.Config;
36using OpenMetaverse;
37using OpenMetaverse.Imaging;
38using OpenSim.Framework;
39using OpenSim.Framework.Console;
40using OpenSim.Region.Framework.Interfaces;
41using OpenSim.Region.Framework.Scenes;
42
43namespace OpenSim.Region.OptionalModules.Agent.TextureSender
44{
45 /// <summary>
46 /// Commands for the J2KDecoder module. For debugging purposes.
47 /// </summary>
48 /// <remarks>
49 /// Placed here so that they can be removed if not required and to keep the J2KDecoder module itself simple.
50 /// </remarks>
51 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "J2KDecoderCommandModule")]
52 public class J2KDecoderCommandModule : ISharedRegionModule
53 {
54// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55
56 private Scene m_scene;
57
58 public string Name { get { return "Asset Information Module"; } }
59
60 public Type ReplaceableInterface { get { return null; } }
61
62 public void Initialise(IConfigSource source)
63 {
64// m_log.DebugFormat("[J2K DECODER COMMAND MODULE]: INITIALIZED MODULE");
65 }
66
67 public void PostInitialise()
68 {
69// m_log.DebugFormat("[J2K DECODER COMMAND MODULE]: POST INITIALIZED MODULE");
70 }
71
72 public void Close()
73 {
74// m_log.DebugFormat("[J2K DECODER COMMAND MODULE]: CLOSED MODULE");
75 }
76
77 public void AddRegion(Scene scene)
78 {
79// m_log.DebugFormat("[J2K DECODER COMMAND MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName);
80 }
81
82 public void RemoveRegion(Scene scene)
83 {
84// m_log.DebugFormat("[J2K DECODER COMMAND MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName);
85 }
86
87 public void RegionLoaded(Scene scene)
88 {
89// m_log.DebugFormat("[J2K DECODER COMMAND MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName);
90
91 if (m_scene == null)
92 m_scene = scene;
93
94 MainConsole.Instance.Commands.AddCommand(
95 "j2k",
96 false,
97 "j2k decode",
98 "j2k decode <ID>",
99 "Do JPEG2000 decoding of an asset.",
100 "This is for debugging purposes. The asset id given must contain JPEG2000 data.",
101 HandleDecode);
102 }
103
104 void HandleDecode(string module, string[] args)
105 {
106 if (args.Length < 3)
107 {
108 MainConsole.Instance.Output("Usage is j2k decode <ID>");
109 return;
110 }
111
112 UUID assetId;
113 string rawAssetId = args[2];
114
115 if (!UUID.TryParse(rawAssetId, out assetId))
116 {
117 MainConsole.Instance.OutputFormat("ERROR: {0} is not a valid ID format", rawAssetId);
118 return;
119 }
120
121 AssetBase asset = m_scene.AssetService.Get(assetId.ToString());
122 if (asset == null)
123 {
124 MainConsole.Instance.OutputFormat("ERROR: No asset found with ID {0}", assetId);
125 return;
126 }
127
128 if (asset.Type != (sbyte)AssetType.Texture)
129 {
130 MainConsole.Instance.OutputFormat("ERROR: Asset {0} is not a texture type", assetId);
131 return;
132 }
133
134 IJ2KDecoder decoder = m_scene.RequestModuleInterface<IJ2KDecoder>();
135 if (decoder == null)
136 {
137 MainConsole.Instance.OutputFormat("ERROR: No IJ2KDecoder module available");
138 return;
139 }
140
141 OpenJPEG.J2KLayerInfo[] layers;
142 int components;
143 if (decoder.Decode(assetId, asset.Data, out layers, out components))
144 {
145 MainConsole.Instance.OutputFormat(
146 "Successfully decoded asset {0} with {1} layers and {2} components",
147 assetId, layers.Length, components);
148 }
149 else
150 {
151 MainConsole.Instance.OutputFormat("Decode of asset {0} failed", assetId);
152 }
153 }
154 }
155} \ No newline at end of file
diff --git a/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs b/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs
index c754019..261029c 100644
--- a/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs
+++ b/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs
@@ -79,7 +79,19 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
79// m_log.DebugFormat("[LINDEN UDP INFO MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName); 79// m_log.DebugFormat("[LINDEN UDP INFO MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName);
80 80
81 lock (m_scenes) 81 lock (m_scenes)
82 m_scenes[scene.RegionInfo.RegionID] = scene; 82 m_scenes[scene.RegionInfo.RegionID] = scene;
83
84 scene.AddCommand(
85 this, "image queues clear",
86 "image queues clear <first-name> <last-name>",
87 "Clear the image queues (textures downloaded via UDP) for a particular client.",
88 (mod, cmd) => MainConsole.Instance.Output(HandleImageQueuesClear(cmd)));
89
90 scene.AddCommand(
91 this, "image queues show",
92 "image queues show <first-name> <last-name>",
93 "Show the image queues (textures downloaded via UDP) for a particular client.",
94 (mod, cmd) => MainConsole.Instance.Output(GetImageQueuesReport(cmd)));
83 95
84 scene.AddCommand( 96 scene.AddCommand(
85 this, "show pqueues", 97 this, "show pqueues",
@@ -87,7 +99,7 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
87 "Show priority queue data for each client", 99 "Show priority queue data for each client",
88 "Without the 'full' option, only root agents are shown." 100 "Without the 'full' option, only root agents are shown."
89 + " With the 'full' option child agents are also shown.", 101 + " With the 'full' option child agents are also shown.",
90 ShowPQueuesReport); 102 (mod, cmd) => MainConsole.Instance.Output(GetPQueuesReport(cmd)));
91 103
92 scene.AddCommand( 104 scene.AddCommand(
93 this, "show queues", 105 this, "show queues",
@@ -95,7 +107,13 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
95 "Show queue data for each client", 107 "Show queue data for each client",
96 "Without the 'full' option, only root agents are shown." 108 "Without the 'full' option, only root agents are shown."
97 + " With the 'full' option child agents are also shown.", 109 + " With the 'full' option child agents are also shown.",
98 ShowQueuesReport); 110 (mod, cmd) => MainConsole.Instance.Output(GetQueuesReport(cmd)));
111
112 scene.AddCommand(
113 this, "show image queues",
114 "show image queues <first-name> <last-name>",
115 "Show the image queues (textures downloaded via UDP) for a particular client.",
116 (mod, cmd) => MainConsole.Instance.Output(GetImageQueuesReport(cmd)));
99 117
100 scene.AddCommand( 118 scene.AddCommand(
101 this, "show throttles", 119 this, "show throttles",
@@ -103,14 +121,14 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
103 "Show throttle settings for each client and for the server overall", 121 "Show throttle settings for each client and for the server overall",
104 "Without the 'full' option, only root agents are shown." 122 "Without the 'full' option, only root agents are shown."
105 + " With the 'full' option child agents are also shown.", 123 + " With the 'full' option child agents are also shown.",
106 ShowThrottlesReport); 124 (mod, cmd) => MainConsole.Instance.Output(GetThrottlesReport(cmd)));
107 125
108 scene.AddCommand( 126 scene.AddCommand(
109 this, "emergency-monitoring", 127 this, "emergency-monitoring",
110 "emergency-monitoring", 128 "emergency-monitoring",
111 "Go on/off emergency monitoring mode", 129 "Go on/off emergency monitoring mode",
112 "Go on/off emergency monitoring mode", 130 "Go on/off emergency monitoring mode",
113 EmergencyMonitoring); 131 HandleEmergencyMonitoring);
114 } 132 }
115 133
116 public void RemoveRegion(Scene scene) 134 public void RemoveRegion(Scene scene)
@@ -124,24 +142,51 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
124 public void RegionLoaded(Scene scene) 142 public void RegionLoaded(Scene scene)
125 { 143 {
126// m_log.DebugFormat("[LINDEN UDP INFO MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); 144// m_log.DebugFormat("[LINDEN UDP INFO MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName);
127 }
128
129 protected void ShowPQueuesReport(string module, string[] cmd)
130 {
131 MainConsole.Instance.Output(GetPQueuesReport(cmd));
132 } 145 }
133 146
134 protected void ShowQueuesReport(string module, string[] cmd) 147 protected string HandleImageQueuesClear(string[] cmd)
135 {
136 MainConsole.Instance.Output(GetQueuesReport(cmd));
137 }
138
139 protected void ShowThrottlesReport(string module, string[] cmd)
140 { 148 {
141 MainConsole.Instance.Output(GetThrottlesReport(cmd)); 149 if (cmd.Length != 5)
150 return "Usage: image queues clear <first-name> <last-name>";
151
152 string firstName = cmd[3];
153 string lastName = cmd[4];
154
155 List<ScenePresence> foundAgents = new List<ScenePresence>();
156
157 lock (m_scenes)
158 {
159 foreach (Scene scene in m_scenes.Values)
160 {
161 ScenePresence sp = scene.GetScenePresence(firstName, lastName);
162 if (sp != null)
163 foundAgents.Add(sp);
164 }
165 }
166
167 if (foundAgents.Count == 0)
168 return string.Format("No agents found for {0} {1}", firstName, lastName);
169
170 StringBuilder report = new StringBuilder();
171
172 foreach (ScenePresence agent in foundAgents)
173 {
174 LLClientView client = agent.ControllingClient as LLClientView;
175
176 if (client == null)
177 return "This command is only supported for LLClientView";
178
179 int requestsDeleted = client.ImageManager.ClearImageQueue();
180
181 report.AppendFormat(
182 "In region {0} ({1} agent) cleared {2} requests\n",
183 agent.Scene.RegionInfo.RegionName, agent.IsChildAgent ? "child" : "root", requestsDeleted);
184 }
185
186 return report.ToString();
142 } 187 }
143 188
144 protected void EmergencyMonitoring(string module, string[] cmd) 189 protected void HandleEmergencyMonitoring(string module, string[] cmd)
145 { 190 {
146 bool mode = true; 191 bool mode = true;
147 if (cmd.Length == 1 || (cmd.Length > 1 && cmd[1] == "on")) 192 if (cmd.Length == 1 || (cmd.Length > 1 && cmd[1] == "on"))
@@ -166,7 +211,6 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
166 entry.Length > maxLength ? entry.Substring(0, maxLength) : entry, 211 entry.Length > maxLength ? entry.Substring(0, maxLength) : entry,
167 ""); 212 "");
168 } 213 }
169
170 214
171 /// <summary> 215 /// <summary>
172 /// Generate UDP Queue data report for each client 216 /// Generate UDP Queue data report for each client
@@ -240,6 +284,73 @@ namespace OpenSim.Region.CoreModules.UDP.Linden
240 284
241 return report.ToString(); 285 return report.ToString();
242 } 286 }
287
288 /// <summary>
289 /// Generate an image queue report
290 /// </summary>
291 /// <param name="showParams"></param>
292 /// <returns></returns>
293 private string GetImageQueuesReport(string[] showParams)
294 {
295 if (showParams.Length < 5 || showParams.Length > 6)
296 return "Usage: image queues show <first-name> <last-name> [full]";
297
298 string firstName = showParams[3];
299 string lastName = showParams[4];
300
301 bool showChildAgents = showParams.Length == 6;
302
303 List<ScenePresence> foundAgents = new List<ScenePresence>();
304
305 lock (m_scenes)
306 {
307 foreach (Scene scene in m_scenes.Values)
308 {
309 ScenePresence sp = scene.GetScenePresence(firstName, lastName);
310 if (sp != null && (showChildAgents || !sp.IsChildAgent))
311 foundAgents.Add(sp);
312 }
313 }
314
315 if (foundAgents.Count == 0)
316 return string.Format("No agents found for {0} {1}", firstName, lastName);
317
318 StringBuilder report = new StringBuilder();
319
320 foreach (ScenePresence agent in foundAgents)
321 {
322 LLClientView client = agent.ControllingClient as LLClientView;
323
324 if (client == null)
325 return "This command is only supported for LLClientView";
326
327 J2KImage[] images = client.ImageManager.GetImages();
328
329 report.AppendFormat(
330 "In region {0} ({1} agent)\n",
331 agent.Scene.RegionInfo.RegionName, agent.IsChildAgent ? "child" : "root");
332 report.AppendFormat("Images in queue: {0}\n", images.Length);
333
334 if (images.Length > 0)
335 {
336 report.AppendFormat(
337 "{0,-36} {1,-8} {2,-10} {3,-9} {4,-9} {5,-7}\n",
338 "Texture ID",
339 "Last Seq",
340 "Priority",
341 "Start Pkt",
342 "Has Asset",
343 "Decoded");
344
345 foreach (J2KImage image in images)
346 report.AppendFormat(
347 "{0,36} {1,8} {2,10} {3,10} {4,9} {5,7}\n",
348 image.TextureID, image.LastSequence, image.Priority, image.StartPacket, image.HasAsset, image.IsDecoded);
349 }
350 }
351
352 return report.ToString();
353 }
243 354
244 /// <summary> 355 /// <summary>
245 /// Generate UDP Queue data report for each client 356 /// Generate UDP Queue data report for each client
diff --git a/OpenSim/Region/OptionalModules/Asset/AssetInfoModule.cs b/OpenSim/Region/OptionalModules/Asset/AssetInfoModule.cs
new file mode 100644
index 0000000..a5207eb
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Asset/AssetInfoModule.cs
@@ -0,0 +1,185 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.IO;
31using System.Reflection;
32using System.Text;
33using log4net;
34using Mono.Addins;
35using Nini.Config;
36using OpenMetaverse;
37using OpenSim.Framework;
38using OpenSim.Framework.Console;
39using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes;
41
42namespace OpenSim.Region.OptionalModules.Asset
43{
44 /// <summary>
45 /// A module that just holds commands for inspecting assets.
46 /// </summary>
47 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AssetInfoModule")]
48 public class AssetInfoModule : ISharedRegionModule
49 {
50// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51
52 private Scene m_scene;
53
54 public string Name { get { return "Asset Information Module"; } }
55
56 public Type ReplaceableInterface { get { return null; } }
57
58 public void Initialise(IConfigSource source)
59 {
60// m_log.DebugFormat("[ASSET INFO MODULE]: INITIALIZED MODULE");
61 }
62
63 public void PostInitialise()
64 {
65// m_log.DebugFormat("[ASSET INFO MODULE]: POST INITIALIZED MODULE");
66 }
67
68 public void Close()
69 {
70// m_log.DebugFormat("[ASSET INFO MODULE]: CLOSED MODULE");
71 }
72
73 public void AddRegion(Scene scene)
74 {
75// m_log.DebugFormat("[ASSET INFO MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName);
76 }
77
78 public void RemoveRegion(Scene scene)
79 {
80// m_log.DebugFormat("[ASSET INFO MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName);
81 }
82
83 public void RegionLoaded(Scene scene)
84 {
85// m_log.DebugFormat("[ASSET INFO MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName);
86
87 if (m_scene == null)
88 m_scene = scene;
89
90 MainConsole.Instance.Commands.AddCommand(
91 "asset",
92 false,
93 "show asset",
94 "show asset <ID>",
95 "Show asset information",
96 HandleShowAsset);
97
98 MainConsole.Instance.Commands.AddCommand(
99 "asset", false, "dump asset",
100 "dump asset <id>",
101 "Dump an asset",
102 HandleDumpAsset);
103 }
104
105 void HandleDumpAsset(string module, string[] args)
106 {
107 if (args.Length < 3)
108 {
109 MainConsole.Instance.Output("Usage is dump asset <ID>");
110 return;
111 }
112
113 UUID assetId;
114 string rawAssetId = args[2];
115
116 if (!UUID.TryParse(rawAssetId, out assetId))
117 {
118 MainConsole.Instance.OutputFormat("ERROR: {0} is not a valid ID format", rawAssetId);
119 return;
120 }
121
122 AssetBase asset = m_scene.AssetService.Get(assetId.ToString());
123 if (asset == null)
124 {
125 MainConsole.Instance.OutputFormat("ERROR: No asset found with ID {0}", assetId);
126 return;
127 }
128
129 string fileName = rawAssetId;
130
131 using (FileStream fs = new FileStream(fileName, FileMode.CreateNew))
132 {
133 using (BinaryWriter bw = new BinaryWriter(fs))
134 {
135 bw.Write(asset.Data);
136 }
137 }
138
139 MainConsole.Instance.OutputFormat("Asset dumped to file {0}", fileName);
140 }
141
142 void HandleShowAsset(string module, string[] args)
143 {
144 if (args.Length < 3)
145 {
146 MainConsole.Instance.Output("Syntax: show asset <ID>");
147 return;
148 }
149
150 AssetBase asset = m_scene.AssetService.Get(args[2]);
151
152 if (asset == null || asset.Data.Length == 0)
153 {
154 MainConsole.Instance.Output("Asset not found");
155 return;
156 }
157
158 int i;
159
160 MainConsole.Instance.OutputFormat("Name: {0}", asset.Name);
161 MainConsole.Instance.OutputFormat("Description: {0}", asset.Description);
162 MainConsole.Instance.OutputFormat("Type: {0} (type number = {1})", (AssetType)asset.Type, asset.Type);
163 MainConsole.Instance.OutputFormat("Content-type: {0}", asset.Metadata.ContentType);
164 MainConsole.Instance.OutputFormat("Size: {0} bytes", asset.Data.Length);
165 MainConsole.Instance.OutputFormat("Temporary: {0}", asset.Temporary ? "yes" : "no");
166 MainConsole.Instance.OutputFormat("Flags: {0}", asset.Metadata.Flags);
167
168 for (i = 0 ; i < 5 ; i++)
169 {
170 int off = i * 16;
171 if (asset.Data.Length <= off)
172 break;
173 int len = 16;
174 if (asset.Data.Length < off + len)
175 len = asset.Data.Length - off;
176
177 byte[] line = new byte[len];
178 Array.Copy(asset.Data, off, line, 0, len);
179
180 string text = BitConverter.ToString(line);
181 MainConsole.Instance.Output(String.Format("{0:x4}: {1}", off, text));
182 }
183 }
184 }
185} \ No newline at end of file
diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs
index 1ce24f1..2369d94 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Linq;
30using System.Reflection; 31using System.Reflection;
31using System.Text; 32using System.Text;
32using log4net; 33using log4net;
@@ -114,6 +115,23 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
114 "Send appearance data for each avatar in the simulator to other viewers.", 115 "Send appearance data for each avatar in the simulator to other viewers.",
115 "Optionally, you can specify that only a particular avatar's appearance data is sent.", 116 "Optionally, you can specify that only a particular avatar's appearance data is sent.",
116 HandleSendAppearanceCommand); 117 HandleSendAppearanceCommand);
118
119 scene.AddCommand(
120 this, "appearance rebake",
121 "appearance rebake <first-name> <last-name>",
122 "Send a request to the user's viewer for it to rebake and reupload its appearance textures.",
123 "This is currently done for all baked texture references previously received, whether the simulator can find the asset or not."
124 + "\nThis will only work for texture ids that the viewer has already uploaded."
125 + "\nIf the viewer has not yet sent the server any texture ids then nothing will happen"
126 + "\nsince requests can only be made for ids that the client has already sent us",
127 HandleRebakeAppearanceCommand);
128
129 scene.AddCommand(
130 this, "appearance find",
131 "appearance find <uuid-or-start-of-uuid>",
132 "Find out which avatar uses the given asset as a baked texture, if any.",
133 "You can specify just the beginning of the uuid, e.g. 2008a8d. A longer UUID must be in dashed format.",
134 HandleFindAppearanceCommand);
117 } 135 }
118 136
119 private void HandleSendAppearanceCommand(string module, string[] cmd) 137 private void HandleSendAppearanceCommand(string module, string[] cmd)
@@ -210,6 +228,81 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
210 } 228 }
211 } 229 }
212 } 230 }
213 } 231 }
232
233 private void HandleRebakeAppearanceCommand(string module, string[] cmd)
234 {
235 if (cmd.Length != 4)
236 {
237 MainConsole.Instance.OutputFormat("Usage: appearance rebake <first-name> <last-name>");
238 return;
239 }
240
241 string firstname = cmd[2];
242 string lastname = cmd[3];
243
244 lock (m_scenes)
245 {
246 foreach (Scene scene in m_scenes.Values)
247 {
248 ScenePresence sp = scene.GetScenePresence(firstname, lastname);
249 if (sp != null && !sp.IsChildAgent)
250 {
251 int rebakesRequested = scene.AvatarFactory.RequestRebake(sp, false);
252
253 if (rebakesRequested > 0)
254 MainConsole.Instance.OutputFormat(
255 "Requesting rebake of {0} uploaded textures for {1} in {2}",
256 rebakesRequested, sp.Name, scene.RegionInfo.RegionName);
257 else
258 MainConsole.Instance.OutputFormat(
259 "No texture IDs available for rebake request for {0} in {1}",
260 sp.Name, scene.RegionInfo.RegionName);
261 }
262 }
263 }
264 }
265
266 protected void HandleFindAppearanceCommand(string module, string[] cmd)
267 {
268 if (cmd.Length != 3)
269 {
270 MainConsole.Instance.OutputFormat("Usage: appearance find <uuid-or-start-of-uuid>");
271 return;
272 }
273
274 string rawUuid = cmd[2];
275
276 HashSet<ScenePresence> matchedAvatars = new HashSet<ScenePresence>();
277
278 lock (m_scenes)
279 {
280 foreach (Scene scene in m_scenes.Values)
281 {
282 scene.ForEachRootScenePresence(
283 sp =>
284 {
285 Dictionary<BakeType, Primitive.TextureEntryFace> bakedFaces = scene.AvatarFactory.GetBakedTextureFaces(sp.UUID);
286 foreach (Primitive.TextureEntryFace face in bakedFaces.Values)
287 {
288 if (face != null && face.TextureID.ToString().StartsWith(rawUuid))
289 matchedAvatars.Add(sp);
290 }
291 });
292 }
293 }
294
295 if (matchedAvatars.Count == 0)
296 {
297 MainConsole.Instance.OutputFormat("{0} did not match any baked avatar textures in use", rawUuid);
298 }
299 else
300 {
301 MainConsole.Instance.OutputFormat(
302 "{0} matched {1}",
303 rawUuid,
304 string.Join(", ", matchedAvatars.ToList().ConvertAll<string>(sp => sp.Name).ToArray()));
305 }
306 }
214 } 307 }
215} \ No newline at end of file 308} \ No newline at end of file
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
index 740dbdd..b60cd42 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
@@ -713,7 +713,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
713 if (money != null) 713 if (money != null)
714 { 714 {
715 // do the transaction, that is if the agent has got sufficient funds 715 // do the transaction, that is if the agent has got sufficient funds
716 if (!money.AmountCovered(remoteClient, money.GroupCreationCharge)) { 716 if (!money.AmountCovered(remoteClient.AgentId, money.GroupCreationCharge)) {
717 remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have got issuficient funds to create a group."); 717 remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have got issuficient funds to create a group.");
718 return UUID.Zero; 718 return UUID.Zero;
719 } 719 }
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IInventoryItem.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IInventoryItem.cs
index 16cd7e4..a8e545c 100644
--- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IInventoryItem.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Interfaces/IInventoryItem.cs
@@ -30,8 +30,7 @@ using OpenMetaverse;
30using OpenMetaverse.Assets; 30using OpenMetaverse.Assets;
31 31
32namespace OpenSim.Region.OptionalModules.Scripting.Minimodule 32namespace OpenSim.Region.OptionalModules.Scripting.Minimodule
33{ 33{
34
35 /// <summary> 34 /// <summary>
36 /// This implements the methods needed to operate on individual inventory items. 35 /// This implements the methods needed to operate on individual inventory items.
37 /// </summary> 36 /// </summary>
@@ -39,6 +38,6 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule
39 { 38 {
40 int Type { get; } 39 int Type { get; }
41 UUID AssetID { get; } 40 UUID AssetID { get; }
42 T RetrieveAsset<T>() where T : Asset, new(); 41 T RetrieveAsset<T>() where T : OpenMetaverse.Assets.Asset, new();
43 } 42 }
44} 43}
diff --git a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs
index 4c4f5fb..d2810be 100644
--- a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs
@@ -44,12 +44,13 @@ using OpenSim.Region.Framework.Scenes;
44 44
45namespace OpenSim.Region.OptionalModules.Scripting.RegionReady 45namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
46{ 46{
47 public class RegionReadyModule : INonSharedRegionModule 47 public class RegionReadyModule : IRegionReadyModule, INonSharedRegionModule
48 { 48 {
49 private static readonly ILog m_log = 49 private static readonly ILog m_log =
50 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 50 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51 51
52 private IConfig m_config = null; 52 private IConfig m_config = null;
53 private bool m_ScriptRez;
53 private bool m_firstEmptyCompileQueue; 54 private bool m_firstEmptyCompileQueue;
54 private bool m_oarFileLoading; 55 private bool m_oarFileLoading;
55 private bool m_lastOarLoadedOk; 56 private bool m_lastOarLoadedOk;
@@ -93,14 +94,17 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
93 if (!m_enabled) 94 if (!m_enabled)
94 return; 95 return;
95 96
97 m_scene = scene;
98
99 m_scene.RegisterModuleInterface<IRegionReadyModule>(this);
100
101 m_ScriptRez = false;
96 m_firstEmptyCompileQueue = true; 102 m_firstEmptyCompileQueue = true;
97 m_oarFileLoading = false; 103 m_oarFileLoading = false;
98 m_lastOarLoadedOk = true; 104 m_lastOarLoadedOk = true;
99 105
100 m_scene = scene;
101
102 m_scene.EventManager.OnEmptyScriptCompileQueue += OnEmptyScriptCompileQueue;
103 m_scene.EventManager.OnOarFileLoaded += OnOarFileLoaded; 106 m_scene.EventManager.OnOarFileLoaded += OnOarFileLoaded;
107 m_scene.EventManager.OnRezScript += OnRezScript;
104 m_scene.EventManager.OnLoginsEnabled += OnLoginsEnabled; 108 m_scene.EventManager.OnLoginsEnabled += OnLoginsEnabled;
105 109
106 m_log.DebugFormat("[RegionReady]: Enabled for region {0}", scene.RegionInfo.RegionName); 110 m_log.DebugFormat("[RegionReady]: Enabled for region {0}", scene.RegionInfo.RegionName);
@@ -118,6 +122,16 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
118 } 122 }
119 } 123 }
120 124
125 void OnRezScript (uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine, int stateSource)
126 {
127 if (!m_ScriptRez)
128 {
129 m_ScriptRez = true;
130 m_scene.EventManager.OnEmptyScriptCompileQueue += OnEmptyScriptCompileQueue;
131 m_scene.EventManager.OnRezScript -= OnRezScript;
132 }
133 }
134
121 public void RemoveRegion(Scene scene) 135 public void RemoveRegion(Scene scene)
122 { 136 {
123 if (!m_enabled) 137 if (!m_enabled)
@@ -125,6 +139,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
125 139
126 m_scene.EventManager.OnEmptyScriptCompileQueue -= OnEmptyScriptCompileQueue; 140 m_scene.EventManager.OnEmptyScriptCompileQueue -= OnEmptyScriptCompileQueue;
127 m_scene.EventManager.OnOarFileLoaded -= OnOarFileLoaded; 141 m_scene.EventManager.OnOarFileLoaded -= OnOarFileLoaded;
142 m_scene.EventManager.OnLoginsEnabled -= OnLoginsEnabled;
128 143
129 if(m_uri != string.Empty) 144 if(m_uri != string.Empty)
130 { 145 {
@@ -148,9 +163,12 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
148 } 163 }
149 164
150 #endregion 165 #endregion
151 166
167
152 void OnEmptyScriptCompileQueue(int numScriptsFailed, string message) 168 void OnEmptyScriptCompileQueue(int numScriptsFailed, string message)
153 { 169 {
170 m_log.InfoFormat("[RegionReady]: Script compile queue empty!");
171
154 if (m_firstEmptyCompileQueue || m_oarFileLoading) 172 if (m_firstEmptyCompileQueue || m_oarFileLoading)
155 { 173 {
156 OSChatMessage c = new OSChatMessage(); 174 OSChatMessage c = new OSChatMessage();
@@ -197,6 +215,10 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
197 } 215 }
198 } 216 }
199 217
218 // This will be triggerd by Scene if we have no scripts
219 // m_ScriptsRezzing will be false if there were none
220 // else it will be true and we should wait on the
221 // empty compile queue
200 void OnLoginsEnabled(string regionName) 222 void OnLoginsEnabled(string regionName)
201 { 223 {
202 if (m_disable_logins == true) 224 if (m_disable_logins == true)
@@ -205,7 +227,12 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
205 { 227 {
206 m_scene.LoginsDisabled = false; 228 m_scene.LoginsDisabled = false;
207 m_scene.LoginLock = false; 229 m_scene.LoginLock = false;
208 m_log.InfoFormat("[RegionReady]: Logins enabled for {0}", m_scene.RegionInfo.RegionName); 230
231 m_scene.EventManager.OnEmptyScriptCompileQueue -= OnEmptyScriptCompileQueue;
232
233 m_log.InfoFormat("[RegionReady]: Logins enabled for {0}, Oar {1}",
234 m_scene.RegionInfo.RegionName, m_oarFileLoading.ToString());
235
209 if ( m_uri != string.Empty ) 236 if ( m_uri != string.Empty )
210 { 237 {
211 RRAlert("enabled"); 238 RRAlert("enabled");
@@ -214,6 +241,31 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
214 } 241 }
215 } 242 }
216 243
244 public void OarLoadingAlert(string msg)
245 {
246 // Let's bypass this for now until some better feedback can be established
247 //
248 return;
249
250 if (msg == "load")
251 {
252 m_scene.EventManager.OnEmptyScriptCompileQueue += OnEmptyScriptCompileQueue;
253 m_scene.EventManager.OnOarFileLoaded += OnOarFileLoaded;
254 m_scene.EventManager.OnLoginsEnabled += OnLoginsEnabled;
255 m_scene.EventManager.OnRezScript += OnRezScript;
256 m_oarFileLoading = true;
257 m_firstEmptyCompileQueue = true;
258
259 m_scene.LoginsDisabled = true;
260 m_scene.LoginLock = true;
261 if ( m_uri != string.Empty )
262 {
263 RRAlert("loading oar");
264 RRAlert("disabled");
265 }
266 }
267 }
268
217 public void RRAlert(string status) 269 public void RRAlert(string status)
218 { 270 {
219 string request_method = "POST"; 271 string request_method = "POST";
diff --git a/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs b/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs
index 8fc50ff..9c838d0 100644
--- a/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs
+++ b/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs
@@ -775,11 +775,11 @@ namespace OpenSim.Region.OptionalModules.World.MoneyModule
775 // Please do not refactor these to be just one method 775 // Please do not refactor these to be just one method
776 // Existing implementations need the distinction 776 // Existing implementations need the distinction
777 // 777 //
778 public bool UploadCovered(IClientAPI client, int amount) 778 public bool UploadCovered(UUID agentID, int amount)
779 { 779 {
780 return true; 780 return true;
781 } 781 }
782 public bool AmountCovered(IClientAPI client, int amount) 782 public bool AmountCovered(UUID agentID, int amount)
783 { 783 {
784 return true; 784 return true;
785 } 785 }
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
index 84055cc..6d40a92 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
@@ -31,24 +31,32 @@ using System.Net;
31using OpenMetaverse; 31using OpenMetaverse;
32using OpenMetaverse.Packets; 32using OpenMetaverse.Packets;
33using OpenSim.Framework; 33using OpenSim.Framework;
34using OpenSim.Region.Framework.Interfaces;
34using OpenSim.Region.Framework.Scenes; 35using OpenSim.Region.Framework.Scenes;
36using OpenSim.Region.CoreModules.World.Estate;
35 37
36namespace OpenSim.Region.OptionalModules.World.NPC 38namespace OpenSim.Region.OptionalModules.World.NPC
37{ 39{
38 public class NPCAvatar : IClientAPI 40 public class NPCAvatar : IClientAPI, INPC
39 { 41 {
42 public bool SenseAsAgent { get; set; }
43
40 private readonly string m_firstname; 44 private readonly string m_firstname;
41 private readonly string m_lastname; 45 private readonly string m_lastname;
42 private readonly Vector3 m_startPos; 46 private readonly Vector3 m_startPos;
43 private readonly UUID m_uuid = UUID.Random(); 47 private readonly UUID m_uuid = UUID.Random();
44 private readonly Scene m_scene; 48 private readonly Scene m_scene;
49 private readonly UUID m_ownerID;
45 50
46 public NPCAvatar(string firstname, string lastname, Vector3 position, Scene scene) 51 public NPCAvatar(
52 string firstname, string lastname, Vector3 position, UUID ownerID, bool senseAsAgent, Scene scene)
47 { 53 {
48 m_firstname = firstname; 54 m_firstname = firstname;
49 m_lastname = lastname; 55 m_lastname = lastname;
50 m_startPos = position; 56 m_startPos = position;
51 m_scene = scene; 57 m_scene = scene;
58 m_ownerID = ownerID;
59 SenseAsAgent = senseAsAgent;
52 } 60 }
53 61
54 public IScene Scene 62 public IScene Scene
@@ -56,6 +64,11 @@ namespace OpenSim.Region.OptionalModules.World.NPC
56 get { return m_scene; } 64 get { return m_scene; }
57 } 65 }
58 66
67 public UUID OwnerID
68 {
69 get { return m_ownerID; }
70 }
71
59 public ISceneAgent SceneAgent { get { throw new NotImplementedException(); } } 72 public ISceneAgent SceneAgent { get { throw new NotImplementedException(); } }
60 73
61 public void Say(string message) 74 public void Say(string message)
@@ -327,6 +340,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
327 public event EstateTeleportOneUserHomeRequest OnEstateTeleportOneUserHomeRequest; 340 public event EstateTeleportOneUserHomeRequest OnEstateTeleportOneUserHomeRequest;
328 public event EstateTeleportAllUsersHomeRequest OnEstateTeleportAllUsersHomeRequest; 341 public event EstateTeleportAllUsersHomeRequest OnEstateTeleportAllUsersHomeRequest;
329 public event EstateChangeInfo OnEstateChangeInfo; 342 public event EstateChangeInfo OnEstateChangeInfo;
343 public event EstateManageTelehub OnEstateManageTelehub;
330 public event ScriptReset OnScriptReset; 344 public event ScriptReset OnScriptReset;
331 public event GetScriptRunning OnGetScriptRunning; 345 public event GetScriptRunning OnGetScriptRunning;
332 public event SetScriptRunning OnSetScriptRunning; 346 public event SetScriptRunning OnSetScriptRunning;
@@ -916,6 +930,9 @@ namespace OpenSim.Region.OptionalModules.World.NPC
916 public void SendEstateCovenantInformation(UUID covenant) 930 public void SendEstateCovenantInformation(UUID covenant)
917 { 931 {
918 } 932 }
933 public void SendTelehubInfo(UUID ObjectID, string ObjectName, Vector3 ObjectPos, Quaternion ObjectRot, List<Vector3> SpawnPoint)
934 {
935 }
919 public void SendDetailedEstateData(UUID invoice, string estateName, uint estateID, uint parentEstate, uint estateFlags, uint sunPosition, UUID covenant, string abuseEmail, UUID estateOwner) 936 public void SendDetailedEstateData(UUID invoice, string estateName, uint estateID, uint parentEstate, uint estateFlags, uint sunPosition, UUID covenant, string abuseEmail, UUID estateOwner)
920 { 937 {
921 } 938 }
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
index 56ff367..3831d7a 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
@@ -56,6 +56,24 @@ namespace OpenSim.Region.OptionalModules.World.NPC
56 } 56 }
57 } 57 }
58 58
59 public void PostInitialise()
60 {
61 }
62
63 public void Close()
64 {
65 }
66
67 public string Name
68 {
69 get { return "NPCModule"; }
70 }
71
72 public bool IsSharedModule
73 {
74 get { return true; }
75 }
76
59 public bool IsNPC(UUID agentId, Scene scene) 77 public bool IsNPC(UUID agentId, Scene scene)
60 { 78 {
61 // FIXME: This implementation could not just use the ScenePresence.PresenceType (and callers could inspect 79 // FIXME: This implementation could not just use the ScenePresence.PresenceType (and callers could inspect
@@ -91,9 +109,15 @@ namespace OpenSim.Region.OptionalModules.World.NPC
91 } 109 }
92 110
93 public UUID CreateNPC( 111 public UUID CreateNPC(
94 string firstname, string lastname, Vector3 position, Scene scene, AvatarAppearance appearance) 112 string firstname,
113 string lastname,
114 Vector3 position,
115 UUID owner,
116 bool senseAsAgent,
117 Scene scene,
118 AvatarAppearance appearance)
95 { 119 {
96 NPCAvatar npcAvatar = new NPCAvatar(firstname, lastname, position, scene); 120 NPCAvatar npcAvatar = new NPCAvatar(firstname, lastname, position, owner, senseAsAgent, scene);
97 npcAvatar.CircuitCode = (uint)Util.RandomClass.Next(0, int.MaxValue); 121 npcAvatar.CircuitCode = (uint)Util.RandomClass.Next(0, int.MaxValue);
98 122
99 m_log.DebugFormat( 123 m_log.DebugFormat(
@@ -234,38 +258,69 @@ namespace OpenSim.Region.OptionalModules.World.NPC
234 return false; 258 return false;
235 } 259 }
236 260
237 public bool DeleteNPC(UUID agentID, Scene scene) 261 public UUID GetOwner(UUID agentID)
238 { 262 {
239 lock (m_avatars) 263 lock (m_avatars)
240 { 264 {
241 if (m_avatars.ContainsKey(agentID)) 265 NPCAvatar av;
266 if (m_avatars.TryGetValue(agentID, out av))
242 { 267 {
243 scene.RemoveClient(agentID, false); 268 return av.OwnerID;
244 m_avatars.Remove(agentID);
245
246 return true;
247 } 269 }
248 } 270 }
249 271
250 return false; 272 return UUID.Zero;
251 } 273 }
252 274
253 public void PostInitialise() 275 public INPC GetNPC(UUID agentID, Scene scene)
254 { 276 {
277 lock (m_avatars)
278 {
279 if (m_avatars.ContainsKey(agentID))
280 return m_avatars[agentID];
281 else
282 return null;
283 }
255 } 284 }
256 285
257 public void Close() 286 public bool DeleteNPC(UUID agentID, Scene scene)
258 { 287 {
288 lock (m_avatars)
289 {
290 NPCAvatar av;
291 if (m_avatars.TryGetValue(agentID, out av))
292 {
293 scene.RemoveClient(agentID, false);
294 m_avatars.Remove(agentID);
295
296 return true;
297 }
298 }
299
300 return false;
259 } 301 }
260 302
261 public string Name 303 public bool CheckPermissions(UUID npcID, UUID callerID)
262 { 304 {
263 get { return "NPCModule"; } 305 lock (m_avatars)
306 {
307 NPCAvatar av;
308 if (m_avatars.TryGetValue(npcID, out av))
309 return CheckPermissions(av, callerID);
310 else
311 return false;
312 }
264 } 313 }
265 314
266 public bool IsSharedModule 315 /// <summary>
316 /// Check if the caller has permission to manipulate the given NPC.
317 /// </summary>
318 /// <param name="av"></param>
319 /// <param name="callerID"></param>
320 /// <returns>true if they do, false if they don't.</returns>
321 private bool CheckPermissions(NPCAvatar av, UUID callerID)
267 { 322 {
268 get { return true; } 323 return callerID == UUID.Zero || av.OwnerID == UUID.Zero || av.OwnerID == callerID;
269 } 324 }
270 } 325 }
271} \ No newline at end of file 326}
diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
index 9c66b25..d507822 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
@@ -109,7 +109,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
109 afm.SetAppearance(sp, originalTe, null); 109 afm.SetAppearance(sp, originalTe, null);
110 110
111 INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); 111 INPCModule npcModule = scene.RequestModuleInterface<INPCModule>();
112 UUID npcId = npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), scene, sp.Appearance); 112 UUID npcId = npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), UUID.Zero, true, scene, sp.Appearance);
113 113
114 ScenePresence npc = scene.GetScenePresence(npcId); 114 ScenePresence npc = scene.GetScenePresence(npcId);
115 115
@@ -119,6 +119,26 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
119 } 119 }
120 120
121 [Test] 121 [Test]
122 public void TestRemove()
123 {
124 TestHelpers.InMethod();
125// log4net.Config.XmlConfigurator.Configure();
126
127 ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1));
128// ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId);
129
130 Vector3 startPos = new Vector3(128, 128, 30);
131 INPCModule npcModule = scene.RequestModuleInterface<INPCModule>();
132 UUID npcId = npcModule.CreateNPC("John", "Smith", startPos, UUID.Zero, true, scene, sp.Appearance);
133
134 npcModule.DeleteNPC(npcId, scene);
135
136 ScenePresence deletedNpc = scene.GetScenePresence(npcId);
137
138 Assert.That(deletedNpc, Is.Null);
139 }
140
141 [Test]
122 public void TestAttachments() 142 public void TestAttachments()
123 { 143 {
124 TestHelpers.InMethod(); 144 TestHelpers.InMethod();
@@ -137,7 +157,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
137 am.RezSingleAttachmentFromInventory(sp, attItemId, (uint)AttachmentPoint.Chest); 157 am.RezSingleAttachmentFromInventory(sp, attItemId, (uint)AttachmentPoint.Chest);
138 158
139 INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); 159 INPCModule npcModule = scene.RequestModuleInterface<INPCModule>();
140 UUID npcId = npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), scene, sp.Appearance); 160 UUID npcId = npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), UUID.Zero, true, scene, sp.Appearance);
141 161
142 ScenePresence npc = scene.GetScenePresence(npcId); 162 ScenePresence npc = scene.GetScenePresence(npcId);
143 163
@@ -169,7 +189,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
169 189
170 Vector3 startPos = new Vector3(128, 128, 30); 190 Vector3 startPos = new Vector3(128, 128, 30);
171 INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); 191 INPCModule npcModule = scene.RequestModuleInterface<INPCModule>();
172 UUID npcId = npcModule.CreateNPC("John", "Smith", startPos, scene, sp.Appearance); 192 UUID npcId = npcModule.CreateNPC("John", "Smith", startPos, UUID.Zero, true, scene, sp.Appearance);
173 193
174 ScenePresence npc = scene.GetScenePresence(npcId); 194 ScenePresence npc = scene.GetScenePresence(npcId);
175 Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); 195 Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos));
@@ -240,7 +260,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
240 260
241 Vector3 startPos = new Vector3(128, 128, 30); 261 Vector3 startPos = new Vector3(128, 128, 30);
242 INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); 262 INPCModule npcModule = scene.RequestModuleInterface<INPCModule>();
243 UUID npcId = npcModule.CreateNPC("John", "Smith", startPos, scene, sp.Appearance); 263 UUID npcId = npcModule.CreateNPC("John", "Smith", startPos, UUID.Zero, true, scene, sp.Appearance);
244 264
245 ScenePresence npc = scene.GetScenePresence(npcId); 265 ScenePresence npc = scene.GetScenePresence(npcId);
246 SceneObjectPart part = SceneHelpers.AddSceneObject(scene); 266 SceneObjectPart part = SceneHelpers.AddSceneObject(scene);
@@ -273,7 +293,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
273 Vector3 startPos = new Vector3(1, 1, 1); 293 Vector3 startPos = new Vector3(1, 1, 1);
274 294
275 INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); 295 INPCModule npcModule = scene.RequestModuleInterface<INPCModule>();
276 UUID npcId = npcModule.CreateNPC("John", "Smith", startPos, scene, sp.Appearance); 296 UUID npcId = npcModule.CreateNPC("John", "Smith", startPos, UUID.Zero, true, scene, sp.Appearance);
277 297
278 ScenePresence npc = scene.GetScenePresence(npcId); 298 ScenePresence npc = scene.GetScenePresence(npcId);
279 SceneObjectPart part = SceneHelpers.AddSceneObject(scene); 299 SceneObjectPart part = SceneHelpers.AddSceneObject(scene);
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index 7704002..e9a849c 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -72,6 +72,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
72 72
73 private bool m_initialized = false; 73 private bool m_initialized = false;
74 74
75 private int m_detailedStatsStep = 0;
76
75 public IMesher mesher; 77 public IMesher mesher;
76 private float m_meshLOD; 78 private float m_meshLOD;
77 public float MeshLOD 79 public float MeshLOD
@@ -192,6 +194,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
192 m_meshLOD = 8f; 194 m_meshLOD = 8f;
193 m_sculptLOD = 32f; 195 m_sculptLOD = 32f;
194 196
197 m_detailedStatsStep = 0; // disabled
198
195 m_maxSubSteps = 10; 199 m_maxSubSteps = 10;
196 m_fixedTimeStep = 1f / 60f; 200 m_fixedTimeStep = 1f / 60f;
197 m_maxCollisionsPerFrame = 2048; 201 m_maxCollisionsPerFrame = 2048;
@@ -209,8 +213,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters
209 parms.deactivationTime = 0.2f; 213 parms.deactivationTime = 0.2f;
210 parms.linearSleepingThreshold = 0.8f; 214 parms.linearSleepingThreshold = 0.8f;
211 parms.angularSleepingThreshold = 1.0f; 215 parms.angularSleepingThreshold = 1.0f;
212 parms.ccdMotionThreshold = 0.5f; // set to zero to disable 216 parms.ccdMotionThreshold = 0.0f; // set to zero to disable
213 parms.ccdSweptSphereRadius = 0.2f; 217 parms.ccdSweptSphereRadius = 0.0f;
218 parms.contactProcessingThreshold = 0.1f;
214 219
215 parms.terrainFriction = 0.5f; 220 parms.terrainFriction = 0.5f;
216 parms.terrainHitFraction = 0.8f; 221 parms.terrainHitFraction = 0.8f;
@@ -231,6 +236,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
231 _meshSculptedPrim = pConfig.GetBoolean("MeshSculptedPrim", _meshSculptedPrim); 236 _meshSculptedPrim = pConfig.GetBoolean("MeshSculptedPrim", _meshSculptedPrim);
232 _forceSimplePrimMeshing = pConfig.GetBoolean("ForceSimplePrimMeshing", _forceSimplePrimMeshing); 237 _forceSimplePrimMeshing = pConfig.GetBoolean("ForceSimplePrimMeshing", _forceSimplePrimMeshing);
233 238
239 m_detailedStatsStep = pConfig.GetInt("DetailedStatsStep", m_detailedStatsStep);
234 m_meshLOD = pConfig.GetFloat("MeshLevelOfDetail", m_meshLOD); 240 m_meshLOD = pConfig.GetFloat("MeshLevelOfDetail", m_meshLOD);
235 m_sculptLOD = pConfig.GetFloat("SculptLevelOfDetail", m_sculptLOD); 241 m_sculptLOD = pConfig.GetFloat("SculptLevelOfDetail", m_sculptLOD);
236 242
@@ -253,6 +259,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
253 parms.angularSleepingThreshold = pConfig.GetFloat("AngularSleepingThreshold", parms.angularSleepingThreshold); 259 parms.angularSleepingThreshold = pConfig.GetFloat("AngularSleepingThreshold", parms.angularSleepingThreshold);
254 parms.ccdMotionThreshold = pConfig.GetFloat("CcdMotionThreshold", parms.ccdMotionThreshold); 260 parms.ccdMotionThreshold = pConfig.GetFloat("CcdMotionThreshold", parms.ccdMotionThreshold);
255 parms.ccdSweptSphereRadius = pConfig.GetFloat("CcdSweptSphereRadius", parms.ccdSweptSphereRadius); 261 parms.ccdSweptSphereRadius = pConfig.GetFloat("CcdSweptSphereRadius", parms.ccdSweptSphereRadius);
262 parms.contactProcessingThreshold = pConfig.GetFloat("ContactProcessingThreshold", parms.contactProcessingThreshold);
256 263
257 parms.terrainFriction = pConfig.GetFloat("TerrainFriction", parms.terrainFriction); 264 parms.terrainFriction = pConfig.GetFloat("TerrainFriction", parms.terrainFriction);
258 parms.terrainHitFraction = pConfig.GetFloat("TerrainHitFraction", parms.terrainHitFraction); 265 parms.terrainHitFraction = pConfig.GetFloat("TerrainHitFraction", parms.terrainHitFraction);
@@ -398,6 +405,14 @@ public class BSScene : PhysicsScene, IPhysicsParameters
398 } 405 }
399 } 406 }
400 407
408 if (m_detailedStatsStep > 0)
409 {
410 if ((m_simulationStep % m_detailedStatsStep) == 0)
411 {
412 BulletSimAPI.DumpBulletStatistics();
413 }
414 }
415
401 // TODO: FIX THIS: fps calculation wrong. This calculation always returns about 1 in normal operation. 416 // TODO: FIX THIS: fps calculation wrong. This calculation always returns about 1 in normal operation.
402 return timeStep / (numSubSteps * m_fixedTimeStep) * 1000f; 417 return timeStep / (numSubSteps * m_fixedTimeStep) * 1000f;
403 } 418 }
@@ -671,6 +686,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
671 new PhysParameterEntry("MaxSubStep", "In simulation step, maximum number of substeps"), 686 new PhysParameterEntry("MaxSubStep", "In simulation step, maximum number of substeps"),
672 new PhysParameterEntry("FixedTimeStep", "In simulation step, seconds of one substep (1/60)"), 687 new PhysParameterEntry("FixedTimeStep", "In simulation step, seconds of one substep (1/60)"),
673 new PhysParameterEntry("MaxObjectMass", "Maximum object mass (10000.01)"), 688 new PhysParameterEntry("MaxObjectMass", "Maximum object mass (10000.01)"),
689 new PhysParameterEntry("DetailedStats", "Frames between outputting detailed phys stats. Zero is off"),
674 690
675 new PhysParameterEntry("DefaultFriction", "Friction factor used on new objects"), 691 new PhysParameterEntry("DefaultFriction", "Friction factor used on new objects"),
676 new PhysParameterEntry("DefaultDensity", "Density for new objects" ), 692 new PhysParameterEntry("DefaultDensity", "Density for new objects" ),
@@ -685,6 +701,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
685 new PhysParameterEntry("AngularSleepingThreshold", "Seconds to measure angular movement before considering static" ), 701 new PhysParameterEntry("AngularSleepingThreshold", "Seconds to measure angular movement before considering static" ),
686 // new PhysParameterEntry("CcdMotionThreshold", "" ), 702 // new PhysParameterEntry("CcdMotionThreshold", "" ),
687 // new PhysParameterEntry("CcdSweptSphereRadius", "" ), 703 // new PhysParameterEntry("CcdSweptSphereRadius", "" ),
704 new PhysParameterEntry("ContactProcessingThreshold", "Distance between contacts before doing collision check" ),
688 705
689 new PhysParameterEntry("TerrainFriction", "Factor to reduce movement against terrain surface" ), 706 new PhysParameterEntry("TerrainFriction", "Factor to reduce movement against terrain surface" ),
690 new PhysParameterEntry("TerrainHitFraction", "Distance to measure hit collisions" ), 707 new PhysParameterEntry("TerrainHitFraction", "Distance to measure hit collisions" ),
@@ -715,6 +732,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
715 string lparm = parm.ToLower(); 732 string lparm = parm.ToLower();
716 switch (lparm) 733 switch (lparm)
717 { 734 {
735 case "detailedstats": m_detailedStatsStep = (int)val; break;
718 case "meshlod": m_meshLOD = (int)val; break; 736 case "meshlod": m_meshLOD = (int)val; break;
719 case "sculptlod": m_sculptLOD = (int)val; break; 737 case "sculptlod": m_sculptLOD = (int)val; break;
720 case "maxsubstep": m_maxSubSteps = (int)val; break; 738 case "maxsubstep": m_maxSubSteps = (int)val; break;
@@ -725,7 +743,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
725 case "defaultdensity": m_params[0].defaultDensity = val; break; 743 case "defaultdensity": m_params[0].defaultDensity = val; break;
726 case "defaultrestitution": m_params[0].defaultRestitution = val; break; 744 case "defaultrestitution": m_params[0].defaultRestitution = val; break;
727 case "collisionmargin": m_params[0].collisionMargin = val; break; 745 case "collisionmargin": m_params[0].collisionMargin = val; break;
728 case "gravity": m_params[0].gravity = val; TaintedUpdateParameter(lparm, PhysParameterEntry.APPLY_TO_NONE, val); break; 746 case "gravity": m_params[0].gravity = val; TaintedUpdateParameter(lparm, PhysParameterEntry.APPLY_TO_NONE, val); break;
729 747
730 case "lineardamping": UpdateParameterPrims(ref m_params[0].linearDamping, lparm, localID, val); break; 748 case "lineardamping": UpdateParameterPrims(ref m_params[0].linearDamping, lparm, localID, val); break;
731 case "angulardamping": UpdateParameterPrims(ref m_params[0].angularDamping, lparm, localID, val); break; 749 case "angulardamping": UpdateParameterPrims(ref m_params[0].angularDamping, lparm, localID, val); break;
@@ -734,6 +752,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
734 case "angularsleepingthreshold": UpdateParameterPrims(ref m_params[0].angularDamping, lparm, localID, val); break; 752 case "angularsleepingthreshold": UpdateParameterPrims(ref m_params[0].angularDamping, lparm, localID, val); break;
735 case "ccdmotionthreshold": UpdateParameterPrims(ref m_params[0].ccdMotionThreshold, lparm, localID, val); break; 753 case "ccdmotionthreshold": UpdateParameterPrims(ref m_params[0].ccdMotionThreshold, lparm, localID, val); break;
736 case "ccdsweptsphereradius": UpdateParameterPrims(ref m_params[0].ccdSweptSphereRadius, lparm, localID, val); break; 754 case "ccdsweptsphereradius": UpdateParameterPrims(ref m_params[0].ccdSweptSphereRadius, lparm, localID, val); break;
755 case "contactprocessingthreshold": UpdateParameterPrims(ref m_params[0].contactProcessingThreshold, lparm, localID, val); break;
737 756
738 // set a terrain physical feature and cause terrain to be recalculated 757 // set a terrain physical feature and cause terrain to be recalculated
739 case "terrainfriction": m_params[0].terrainFriction = val; TaintedUpdateParameter("terrain", 0, val); break; 758 case "terrainfriction": m_params[0].terrainFriction = val; TaintedUpdateParameter("terrain", 0, val); break;
@@ -741,10 +760,10 @@ public class BSScene : PhysicsScene, IPhysicsParameters
741 case "terrainrestitution": m_params[0].terrainRestitution = val; TaintedUpdateParameter("terrain", 0, val); break; 760 case "terrainrestitution": m_params[0].terrainRestitution = val; TaintedUpdateParameter("terrain", 0, val); break;
742 // set an avatar physical feature and cause avatar(s) to be recalculated 761 // set an avatar physical feature and cause avatar(s) to be recalculated
743 case "avatarfriction": UpdateParameterAvatars(ref m_params[0].avatarFriction, "avatar", localID, val); break; 762 case "avatarfriction": UpdateParameterAvatars(ref m_params[0].avatarFriction, "avatar", localID, val); break;
744 case "avatardensity": UpdateParameterAvatars(ref m_params[0].avatarDensity, "avatar", localID, val); break; 763 case "avatardensity": UpdateParameterAvatars(ref m_params[0].avatarDensity, "avatar", localID, val); break;
745 case "avatarrestitution": UpdateParameterAvatars(ref m_params[0].avatarRestitution, "avatar", localID, val); break; 764 case "avatarrestitution": UpdateParameterAvatars(ref m_params[0].avatarRestitution, "avatar", localID, val); break;
746 case "avatarcapsuleradius": UpdateParameterAvatars(ref m_params[0].avatarCapsuleRadius, "avatar", localID, val); break; 765 case "avatarcapsuleradius": UpdateParameterAvatars(ref m_params[0].avatarCapsuleRadius, "avatar", localID, val); break;
747 case "avatarcapsuleheight": UpdateParameterAvatars(ref m_params[0].avatarCapsuleHeight, "avatar", localID, val); break; 766 case "avatarcapsuleheight": UpdateParameterAvatars(ref m_params[0].avatarCapsuleHeight, "avatar", localID, val); break;
748 767
749 default: ret = false; break; 768 default: ret = false; break;
750 } 769 }
@@ -816,6 +835,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
816 bool ret = true; 835 bool ret = true;
817 switch (parm.ToLower()) 836 switch (parm.ToLower())
818 { 837 {
838 case "detailedstats": val = (int)m_detailedStatsStep; break;
819 case "meshlod": val = (float)m_meshLOD; break; 839 case "meshlod": val = (float)m_meshLOD; break;
820 case "sculptlod": val = (float)m_sculptLOD; break; 840 case "sculptlod": val = (float)m_sculptLOD; break;
821 case "maxsubstep": val = (float)m_maxSubSteps; break; 841 case "maxsubstep": val = (float)m_maxSubSteps; break;
@@ -835,6 +855,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
835 case "angularsleepingthreshold": val = m_params[0].angularDamping; break; 855 case "angularsleepingthreshold": val = m_params[0].angularDamping; break;
836 case "ccdmotionthreshold": val = m_params[0].ccdMotionThreshold; break; 856 case "ccdmotionthreshold": val = m_params[0].ccdMotionThreshold; break;
837 case "ccdsweptsphereradius": val = m_params[0].ccdSweptSphereRadius; break; 857 case "ccdsweptsphereradius": val = m_params[0].ccdSweptSphereRadius; break;
858 case "contactprocessingthreshold": val = m_params[0].contactProcessingThreshold; break;
838 859
839 case "terrainfriction": val = m_params[0].terrainFriction; break; 860 case "terrainfriction": val = m_params[0].terrainFriction; break;
840 case "terrainhitfraction": val = m_params[0].terrainHitFraction; break; 861 case "terrainhitfraction": val = m_params[0].terrainHitFraction; break;
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
index a610c8d..d12bd7d 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
@@ -122,6 +122,7 @@ public struct ConfigurationParameters
122 public float angularSleepingThreshold; 122 public float angularSleepingThreshold;
123 public float ccdMotionThreshold; 123 public float ccdMotionThreshold;
124 public float ccdSweptSphereRadius; 124 public float ccdSweptSphereRadius;
125 public float contactProcessingThreshold;
125 126
126 public float terrainFriction; 127 public float terrainFriction;
127 public float terrainHitFraction; 128 public float terrainHitFraction;
@@ -248,6 +249,9 @@ public static extern RaycastHit RayTest(uint worldID, uint id, Vector3 from, Vec
248[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 249[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
249public static extern Vector3 RecoverFromPenetration(uint worldID, uint id); 250public static extern Vector3 RecoverFromPenetration(uint worldID, uint id);
250 251
252[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
253public static extern void DumpBulletStatistics();
254
251// Log a debug message 255// Log a debug message
252[UnmanagedFunctionPointer(CallingConvention.Cdecl)] 256[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
253public delegate void DebugLogCallback([MarshalAs(UnmanagedType.LPStr)]string msg); 257public delegate void DebugLogCallback([MarshalAs(UnmanagedType.LPStr)]string msg);
diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
index 68999fc..7c1c046 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
@@ -134,9 +134,18 @@ namespace OpenSim.Region.Physics.OdePlugin
134 | CollisionCategories.Body 134 | CollisionCategories.Body
135 | CollisionCategories.Character 135 | CollisionCategories.Character
136 | CollisionCategories.Land); 136 | CollisionCategories.Land);
137 internal IntPtr Body = IntPtr.Zero; 137 /// <summary>
138 /// Body for dynamics simulation
139 /// </summary>
140 internal IntPtr Body { get; private set; }
141
138 private OdeScene _parent_scene; 142 private OdeScene _parent_scene;
139 internal IntPtr Shell = IntPtr.Zero; 143
144 /// <summary>
145 /// Collision geometry
146 /// </summary>
147 internal IntPtr Shell { get; private set; }
148
140 private IntPtr Amotor = IntPtr.Zero; 149 private IntPtr Amotor = IntPtr.Zero;
141 private d.Mass ShellMass; 150 private d.Mass ShellMass;
142 151
@@ -1018,6 +1027,13 @@ namespace OpenSim.Region.Physics.OdePlugin
1018 /// <param name="tensor"></param> 1027 /// <param name="tensor"></param>
1019 private void CreateOdeStructures(float npositionX, float npositionY, float npositionZ, float tensor) 1028 private void CreateOdeStructures(float npositionX, float npositionY, float npositionZ, float tensor)
1020 { 1029 {
1030 if (!(Shell == IntPtr.Zero && Body == IntPtr.Zero && Amotor == IntPtr.Zero))
1031 {
1032 m_log.ErrorFormat(
1033 "[ODE CHARACTER]: Creating ODE structures for {0} even though some already exist. Shell = {1}, Body = {2}, Amotor = {3}",
1034 Name, Shell, Body, Amotor);
1035 }
1036
1021 int dAMotorEuler = 1; 1037 int dAMotorEuler = 1;
1022// _parent_scene.waitForSpaceUnlock(_parent_scene.space); 1038// _parent_scene.waitForSpaceUnlock(_parent_scene.space);
1023 if (CAPSULE_LENGTH <= 0) 1039 if (CAPSULE_LENGTH <= 0)
@@ -1032,6 +1048,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1032 CAPSULE_RADIUS = 0.01f; 1048 CAPSULE_RADIUS = 0.01f;
1033 } 1049 }
1034 1050
1051// lock (OdeScene.UniversalColliderSyncObject)
1035 Shell = d.CreateCapsule(_parent_scene.space, CAPSULE_RADIUS, CAPSULE_LENGTH); 1052 Shell = d.CreateCapsule(_parent_scene.space, CAPSULE_RADIUS, CAPSULE_LENGTH);
1036 1053
1037 d.GeomSetCategoryBits(Shell, (int)m_collisionCategories); 1054 d.GeomSetCategoryBits(Shell, (int)m_collisionCategories);
@@ -1135,6 +1152,14 @@ namespace OpenSim.Region.Physics.OdePlugin
1135 /// </summary> 1152 /// </summary>
1136 internal void DestroyOdeStructures() 1153 internal void DestroyOdeStructures()
1137 { 1154 {
1155 // Create avatar capsule and related ODE data
1156 if (Shell == IntPtr.Zero || Body == IntPtr.Zero || Amotor == IntPtr.Zero)
1157 {
1158 m_log.ErrorFormat(
1159 "[ODE CHARACTER]: Destroying ODE structures for {0} even though some are already null. Shell = {1}, Body = {2}, Amotor = {3}",
1160 Name, Shell, Body, Amotor);
1161 }
1162
1138 // destroy avatar capsule and related ODE data 1163 // destroy avatar capsule and related ODE data
1139 if (Amotor != IntPtr.Zero) 1164 if (Amotor != IntPtr.Zero)
1140 { 1165 {
@@ -1155,7 +1180,9 @@ namespace OpenSim.Region.Physics.OdePlugin
1155 1180
1156 if (Shell != IntPtr.Zero) 1181 if (Shell != IntPtr.Zero)
1157 { 1182 {
1183// lock (OdeScene.UniversalColliderSyncObject)
1158 d.GeomDestroy(Shell); 1184 d.GeomDestroy(Shell);
1185
1159 _parent_scene.geom_name_map.Remove(Shell); 1186 _parent_scene.geom_name_map.Remove(Shell);
1160 _parent_scene.actor_name_map.Remove(Shell); 1187 _parent_scene.actor_name_map.Remove(Shell);
1161 1188
@@ -1260,15 +1287,6 @@ namespace OpenSim.Region.Physics.OdePlugin
1260 { 1287 {
1261 if (m_tainted_isPhysical) 1288 if (m_tainted_isPhysical)
1262 { 1289 {
1263 // Create avatar capsule and related ODE data
1264 if (!(Shell == IntPtr.Zero && Body == IntPtr.Zero && Amotor == IntPtr.Zero))
1265 {
1266 m_log.Warn("[ODE CHARACTER]: re-creating the following avatar ODE data for " + Name + ", even though it already exists - "
1267 + (Shell!=IntPtr.Zero ? "Shell ":"")
1268 + (Body!=IntPtr.Zero ? "Body ":"")
1269 + (Amotor!=IntPtr.Zero ? "Amotor ":""));
1270 }
1271
1272 CreateOdeStructures(_position.X, _position.Y, _position.Z, m_tensor); 1290 CreateOdeStructures(_position.X, _position.Y, _position.Z, m_tensor);
1273 _parent_scene.AddCharacter(this); 1291 _parent_scene.AddCharacter(this);
1274 } 1292 }
diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
index 228eca9..4530c09 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
@@ -105,6 +105,32 @@ namespace OpenSim.Region.Physics.OdePlugin
105 private readonly ILog m_log; 105 private readonly ILog m_log;
106 // private Dictionary<string, sCollisionData> m_storedCollisions = new Dictionary<string, sCollisionData>(); 106 // private Dictionary<string, sCollisionData> m_storedCollisions = new Dictionary<string, sCollisionData>();
107 107
108 /// <summary>
109 /// Provide a sync object so that only one thread calls d.Collide() at a time across all OdeScene instances.
110 /// </summary>
111 /// <remarks>
112 /// With ODE as of r1755 (though also tested on r1860), only one thread can call d.Collide() at a
113 /// time, even where physics objects are in entirely different ODE worlds. This is because generating contacts
114 /// uses a static cache at the ODE level.
115 ///
116 /// Without locking, simulators running multiple regions will eventually crash with a native stack trace similar
117 /// to
118 ///
119 /// mono() [0x489171]
120 /// mono() [0x4d154f]
121 /// /lib/x86_64-linux-gnu/libpthread.so.0(+0xfc60) [0x7f6ded592c60]
122 /// .../opensim/bin/libode-x86_64.so(_ZN6Opcode11OBBCollider8_CollideEPKNS_14AABBNoLeafNodeE+0xd7a) [0x7f6dd822628a]
123 ///
124 /// ODE provides an experimental option to cache in thread local storage but compiling ODE with this option
125 /// causes OpenSimulator to immediately crash with a native stack trace similar to
126 ///
127 /// mono() [0x489171]
128 /// mono() [0x4d154f]
129 /// /lib/x86_64-linux-gnu/libpthread.so.0(+0xfc60) [0x7f03c9849c60]
130 /// .../opensim/bin/libode-x86_64.so(_Z12dCollideCCTLP6dxGeomS0_iP12dContactGeomi+0x92) [0x7f03b44bcf82]
131 /// </remarks>
132 internal static Object UniversalColliderSyncObject = new Object();
133
108 private Random fluidRandomizer = new Random(Environment.TickCount); 134 private Random fluidRandomizer = new Random(Environment.TickCount);
109 135
110 private const uint m_regionWidth = Constants.RegionSize; 136 private const uint m_regionWidth = Constants.RegionSize;
@@ -799,7 +825,9 @@ namespace OpenSim.Region.Physics.OdePlugin
799 if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact)) 825 if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact))
800 return; 826 return;
801 827
802 count = d.Collide(g1, g2, contacts.Length, contacts, d.ContactGeom.SizeOf); 828 lock (OdeScene.UniversalColliderSyncObject)
829 count = d.Collide(g1, g2, contacts.Length, contacts, d.ContactGeom.SizeOf);
830
803 if (count > contacts.Length) 831 if (count > contacts.Length)
804 m_log.Error("[ODE SCENE]: Got " + count + " contacts when we asked for a maximum of " + contacts.Length); 832 m_log.Error("[ODE SCENE]: Got " + count + " contacts when we asked for a maximum of " + contacts.Length);
805 } 833 }
@@ -1525,7 +1553,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1525 chr.CollidingGround = false; 1553 chr.CollidingGround = false;
1526 chr.CollidingObj = false; 1554 chr.CollidingObj = false;
1527 1555
1528 // test the avatar's geometry for collision with the space 1556 // Test the avatar's geometry for collision with the space
1529 // This will return near and the space that they are the closest to 1557 // This will return near and the space that they are the closest to
1530 // And we'll run this again against the avatar and the space segment 1558 // And we'll run this again against the avatar and the space segment
1531 // This will return with a bunch of possible objects in the space segment 1559 // This will return with a bunch of possible objects in the space segment
diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs
index 581a9a9..17c2708 100644
--- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs
+++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs
@@ -42,10 +42,6 @@ namespace OpenSim.Region.ScriptEngine.Interfaces
42 /// An interface for a script API module to communicate with 42 /// An interface for a script API module to communicate with
43 /// the engine it's running under 43 /// the engine it's running under
44 /// </summary> 44 /// </summary>
45
46 public delegate void ScriptRemoved(UUID script);
47 public delegate void ObjectRemoved(UUID prim);
48
49 public interface IScriptEngine 45 public interface IScriptEngine
50 { 46 {
51 /// <summary> 47 /// <summary>
@@ -57,9 +53,6 @@ namespace OpenSim.Region.ScriptEngine.Interfaces
57 53
58 IScriptModule ScriptModule { get; } 54 IScriptModule ScriptModule { get; }
59 55
60 event ScriptRemoved OnScriptRemoved;
61 event ObjectRemoved OnObjectRemoved;
62
63 /// <summary> 56 /// <summary>
64 /// Post an event to a single script 57 /// Post an event to a single script
65 /// </summary> 58 /// </summary>
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 443e7a5..67dee02 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -126,11 +126,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
126 m_TransferModule = 126 m_TransferModule =
127 m_ScriptEngine.World.RequestModuleInterface<IMessageTransferModule>(); 127 m_ScriptEngine.World.RequestModuleInterface<IMessageTransferModule>();
128 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>(); 128 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>();
129 if (m_UrlModule != null)
130 {
131 m_ScriptEngine.OnScriptRemoved += m_UrlModule.ScriptRemoved;
132 m_ScriptEngine.OnObjectRemoved += m_UrlModule.ObjectRemoved;
133 }
134 129
135 AsyncCommands = new AsyncCommandManager(ScriptEngine); 130 AsyncCommands = new AsyncCommandManager(ScriptEngine);
136 } 131 }
@@ -468,26 +463,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
468 463
469 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 464 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
470 465
471 // Old implementation of llRot2Euler. Normalization not required as Atan2 function will 466 /// <summary>
472 // only return values >= -PI (-180 degrees) and <= PI (180 degrees). 467 /// Convert an LSL rotation to a Euler vector.
473 468 /// </summary>
469 /// <remarks>
470 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
471 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
472 /// </remarks>
473 /// <param name="r"></param>
474 /// <returns></returns>
474 public LSL_Vector llRot2Euler(LSL_Rotation r) 475 public LSL_Vector llRot2Euler(LSL_Rotation r)
475 { 476 {
476 m_host.AddScriptLPS(1); 477 m_host.AddScriptLPS(1);
477 //This implementation is from http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryRotationFunctions. ckrinke 478
478 LSL_Rotation t = new LSL_Rotation(r.x * r.x, r.y * r.y, r.z * r.z, r.s * r.s); 479 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r.
479 double m = (t.x + t.y + t.z + t.s); 480 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later.
480 if (m == 0) return new LSL_Vector(); 481 if (m == 0.0) return new LSL_Vector();
481 double n = 2 * (r.y * r.s + r.x * r.z); 482 double x = Math.Atan2(-v.y, v.z);
482 double p = m * m - n * n; 483 double sin = v.x / m;
483 if (p > 0) 484 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities.
484 return new LSL_Vector(Math.Atan2(2.0 * (r.x * r.s - r.y * r.z), (-t.x - t.y + t.z + t.s)), 485 double y = Math.Asin(sin);
485 Math.Atan2(n, Math.Sqrt(p)), 486 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
486 Math.Atan2(2.0 * (r.z * r.s - r.x * r.y), (t.x - t.y - t.z + t.s))); 487 v = new LSL_Vector(1.0, 0.0, 0.0) * ((r * new LSL_Rotation(Math.Sin(-x / 2.0), 0.0, 0.0, Math.Cos(-x / 2.0))) * new LSL_Rotation(0.0, Math.Sin(-y / 2.0), 0.0, Math.Cos(-y / 2.0)));
487 else if (n > 0) 488 double z = Math.Atan2(v.y, v.x);
488 return new LSL_Vector(0.0, Math.PI * 0.5, Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z)); 489
489 else 490 return new LSL_Vector(x, y, z);
490 return new LSL_Vector(0.0, -Math.PI * 0.5, Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z));
491 } 491 }
492 492
493 /* From wiki: 493 /* From wiki:
@@ -2856,11 +2856,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2856 // we need to convert from a vector describing 2856 // we need to convert from a vector describing
2857 // the angles of rotation in radians into rotation value 2857 // the angles of rotation in radians into rotation value
2858 2858
2859 LSL_Types.Quaternion rot = llEuler2Rot(angle); 2859 LSL_Rotation rot = llEuler2Rot(angle);
2860 Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s); 2860
2861 m_host.startLookAt(rotation, (float)damping, (float)strength); 2861 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2862 // Orient the object to the angle calculated 2862 // set the rotation of the object, copy that behavior
2863 //llSetRot(rot); 2863 if (strength == 0 || m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2864 {
2865 llSetRot(rot);
2866 }
2867 else
2868 {
2869 m_host.StartLookAt(Rot2Quaternion(rot), (float)strength, (float)damping);
2870 }
2864 } 2871 }
2865 2872
2866 public void llStopLookAt() 2873 public void llStopLookAt()
@@ -3236,8 +3243,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3236 public void llRotLookAt(LSL_Rotation target, double strength, double damping) 3243 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3237 { 3244 {
3238 m_host.AddScriptLPS(1); 3245 m_host.AddScriptLPS(1);
3239 Quaternion rot = new Quaternion((float)target.x, (float)target.y, (float)target.z, (float)target.s); 3246
3240 m_host.RotLookAt(rot, (float)strength, (float)damping); 3247 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
3248 // set the rotation of the object, copy that behavior
3249 if (strength == 0 || m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
3250 {
3251 llSetLocalRot(target);
3252 }
3253 else
3254 {
3255 m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping);
3256 }
3241 } 3257 }
3242 3258
3243 public LSL_Integer llStringLength(string str) 3259 public LSL_Integer llStringLength(string str)
@@ -4023,9 +4039,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4023 Vector3 av3 = new Vector3(Util.Clip((float)color.x, 0.0f, 1.0f), 4039 Vector3 av3 = new Vector3(Util.Clip((float)color.x, 0.0f, 1.0f),
4024 Util.Clip((float)color.y, 0.0f, 1.0f), 4040 Util.Clip((float)color.y, 0.0f, 1.0f),
4025 Util.Clip((float)color.z, 0.0f, 1.0f)); 4041 Util.Clip((float)color.z, 0.0f, 1.0f));
4026 m_host.SetText(text, av3, Util.Clip((float)alpha, 0.0f, 1.0f)); 4042 m_host.SetText(text.Length > 254 ? text.Remove(255) : text, av3, Util.Clip((float)alpha, 0.0f, 1.0f));
4027 m_host.ParentGroup.HasGroupChanged = true; 4043 //m_host.ParentGroup.HasGroupChanged = true;
4028 m_host.ParentGroup.ScheduleGroupForFullUpdate(); 4044 //m_host.ParentGroup.ScheduleGroupForFullUpdate();
4029 } 4045 }
4030 4046
4031 public LSL_Float llWater(LSL_Vector offset) 4047 public LSL_Float llWater(LSL_Vector offset)
@@ -4693,15 +4709,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4693 return (double)Math.Asin(val); 4709 return (double)Math.Asin(val);
4694 } 4710 }
4695 4711
4696 // Xantor 30/apr/2008 4712 // jcochran 5/jan/2012
4697 public LSL_Float llAngleBetween(LSL_Rotation a, LSL_Rotation b) 4713 public LSL_Float llAngleBetween(LSL_Rotation a, LSL_Rotation b)
4698 { 4714 {
4699 m_host.AddScriptLPS(1); 4715 m_host.AddScriptLPS(1);
4700 4716
4701 double angle = Math.Acos(a.x * b.x + a.y * b.y + a.z * b.z + a.s * b.s) * 2; 4717 double aa = (a.x * a.x + a.y * a.y + a.z * a.z + a.s * a.s);
4702 if (angle < 0) angle = -angle; 4718 double bb = (b.x * b.x + b.y * b.y + b.z * b.z + b.s * b.s);
4703 if (angle > Math.PI) return (Math.PI * 2 - angle); 4719 double aa_bb = aa * bb;
4704 return angle; 4720 if (aa_bb == 0) return 0.0;
4721 double ab = (a.x * b.x + a.y * b.y + a.z * b.z + a.s * b.s);
4722 double quotient = (ab * ab) / aa_bb;
4723 if (quotient >= 1.0) return 0.0;
4724 return Math.Acos(2 * quotient - 1);
4705 } 4725 }
4706 4726
4707 public LSL_String llGetInventoryKey(string name) 4727 public LSL_String llGetInventoryKey(string name)
@@ -5486,7 +5506,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5486 5506
5487 foreach (GridRegion sri in neighbors) 5507 foreach (GridRegion sri in neighbors)
5488 { 5508 {
5489 if (sri.RegionLocX == neighborX && sri.RegionLocY == neighborY) 5509 if (sri.RegionCoordX == neighborX && sri.RegionCoordY == neighborY)
5490 return 0; 5510 return 0;
5491 } 5511 }
5492 5512
@@ -6583,7 +6603,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6583 } 6603 }
6584 6604
6585 // the rest of the permission checks are done in RezScript, so check the pin there as well 6605 // the rest of the permission checks are done in RezScript, so check the pin there as well
6586 World.RezScript(srcId, m_host, destId, pin, running, start_param); 6606 World.RezScriptFromPrim(srcId, m_host, destId, pin, running, start_param);
6607
6587 // this will cause the delay even if the script pin or permissions were wrong - seems ok 6608 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6588 ScriptSleep(3000); 6609 ScriptSleep(3000);
6589 } 6610 }
@@ -7546,6 +7567,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7546 ScriptSleep(2000); 7567 ScriptSleep(2000);
7547 } 7568 }
7548 7569
7570 public LSL_String llGetParcelMusicURL()
7571 {
7572 m_host.AddScriptLPS(1);
7573
7574 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y);
7575
7576 if (land.LandData.OwnerID != m_host.OwnerID)
7577 return String.Empty;
7578
7579 return land.GetMusicUrl();
7580 }
7581
7549 public LSL_Vector llGetRootPosition() 7582 public LSL_Vector llGetRootPosition()
7550 { 7583 {
7551 m_host.AddScriptLPS(1); 7584 m_host.AddScriptLPS(1);
@@ -10613,6 +10646,75 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10613 return list; 10646 return list;
10614 } 10647 }
10615 10648
10649 public LSL_Integer llManageEstateAccess(int action, string avatar)
10650 {
10651 m_host.AddScriptLPS(1);
10652 EstateSettings estate = World.RegionInfo.EstateSettings;
10653 bool isAccount = false;
10654 bool isGroup = false;
10655
10656 if (!estate.IsEstateOwner(m_host.OwnerID) || !estate.IsEstateManager(m_host.OwnerID))
10657 return 0;
10658
10659 UUID id = new UUID();
10660 if (!UUID.TryParse(avatar, out id))
10661 return 0;
10662
10663 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, id);
10664 isAccount = account != null ? true : false;
10665 if (!isAccount)
10666 {
10667 IGroupsModule groups = World.RequestModuleInterface<IGroupsModule>();
10668 if (groups != null)
10669 {
10670 GroupRecord group = groups.GetGroupRecord(id);
10671 isGroup = group != null ? true : false;
10672 if (!isGroup)
10673 return 0;
10674 }
10675 else
10676 return 0;
10677 }
10678
10679 switch (action)
10680 {
10681 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
10682 if (!isAccount) return 0;
10683 if (estate.HasAccess(id)) return 1;
10684 if (estate.IsBanned(id))
10685 estate.RemoveBan(id);
10686 estate.AddEstateUser(id);
10687 break;
10688 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_REMOVE:
10689 if (!isAccount || !estate.HasAccess(id)) return 0;
10690 estate.RemoveEstateUser(id);
10691 break;
10692 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_GROUP_ADD:
10693 if (!isGroup) return 0;
10694 if (estate.GroupAccess(id)) return 1;
10695 estate.AddEstateGroup(id);
10696 break;
10697 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_GROUP_REMOVE:
10698 if (!isGroup || !estate.GroupAccess(id)) return 0;
10699 estate.RemoveEstateGroup(id);
10700 break;
10701 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
10702 if (!isAccount) return 0;
10703 if (estate.IsBanned(id)) return 1;
10704 EstateBan ban = new EstateBan();
10705 ban.EstateID = estate.EstateID;
10706 ban.BannedUserID = id;
10707 estate.AddBan(ban);
10708 break;
10709 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
10710 if (!isAccount || !estate.IsBanned(id)) return 0;
10711 estate.RemoveBan(id);
10712 break;
10713 default: return 0;
10714 }
10715 return 1;
10716 }
10717
10616 #region Not Implemented 10718 #region Not Implemented
10617 // 10719 //
10618 // Listing the unimplemented lsl functions here, please move 10720 // Listing the unimplemented lsl functions here, please move
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 503b5d0..b1583eb 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -157,6 +157,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
157 string risk = m_ScriptEngine.Config.GetString("OSFunctionThreatLevel", "VeryLow"); 157 string risk = m_ScriptEngine.Config.GetString("OSFunctionThreatLevel", "VeryLow");
158 switch (risk) 158 switch (risk)
159 { 159 {
160 case "NoAccess":
161 m_MaxThreatLevel = ThreatLevel.NoAccess;
162 break;
160 case "None": 163 case "None":
161 m_MaxThreatLevel = ThreatLevel.None; 164 m_MaxThreatLevel = ThreatLevel.None;
162 break; 165 break;
@@ -413,6 +416,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
413 public LSL_Integer osSetTerrainHeight(int x, int y, double val) 416 public LSL_Integer osSetTerrainHeight(int x, int y, double val)
414 { 417 {
415 CheckThreatLevel(ThreatLevel.High, "osSetTerrainHeight"); 418 CheckThreatLevel(ThreatLevel.High, "osSetTerrainHeight");
419
416 return SetTerrainHeight(x, y, val); 420 return SetTerrainHeight(x, y, val);
417 } 421 }
418 422
@@ -420,12 +424,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
420 { 424 {
421 CheckThreatLevel(ThreatLevel.High, "osTerrainSetHeight"); 425 CheckThreatLevel(ThreatLevel.High, "osTerrainSetHeight");
422 OSSLDeprecated("osTerrainSetHeight", "osSetTerrainHeight"); 426 OSSLDeprecated("osTerrainSetHeight", "osSetTerrainHeight");
427
423 return SetTerrainHeight(x, y, val); 428 return SetTerrainHeight(x, y, val);
424 } 429 }
425 430
426 private LSL_Integer SetTerrainHeight(int x, int y, double val) 431 private LSL_Integer SetTerrainHeight(int x, int y, double val)
427 { 432 {
428 m_host.AddScriptLPS(1); 433 m_host.AddScriptLPS(1);
434
429 if (x > ((int)Constants.RegionSize - 1) || x < 0 || y > ((int)Constants.RegionSize - 1) || y < 0) 435 if (x > ((int)Constants.RegionSize - 1) || x < 0 || y > ((int)Constants.RegionSize - 1) || y < 0)
430 OSSLError("osSetTerrainHeight: Coordinate out of bounds"); 436 OSSLError("osSetTerrainHeight: Coordinate out of bounds");
431 437
@@ -465,6 +471,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
465 public void osTerrainFlush() 471 public void osTerrainFlush()
466 { 472 {
467 CheckThreatLevel(ThreatLevel.VeryLow, "osTerrainFlush"); 473 CheckThreatLevel(ThreatLevel.VeryLow, "osTerrainFlush");
474 m_host.AddScriptLPS(1);
468 475
469 ITerrainModule terrainModule = World.RequestModuleInterface<ITerrainModule>(); 476 ITerrainModule terrainModule = World.RequestModuleInterface<ITerrainModule>();
470 if (terrainModule != null) terrainModule.TaintTerrain(); 477 if (terrainModule != null) terrainModule.TaintTerrain();
@@ -736,7 +743,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
736 { 743 {
737 // High because there is no security check. High griefer potential 744 // High because there is no security check. High griefer potential
738 // 745 //
739 CheckThreatLevel(ThreatLevel.High, "osTeleportAgent"); 746 CheckThreatLevel(ThreatLevel.Severe, "osTeleportAgent");
740 747
741 TeleportAgent(agent, regionName, position, lookat, false); 748 TeleportAgent(agent, regionName, position, lookat, false);
742 } 749 }
@@ -753,11 +760,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
753 { 760 {
754 // For osTeleportAgent, agent must be over owners land to avoid abuse 761 // For osTeleportAgent, agent must be over owners land to avoid abuse
755 // For osTeleportOwner, this restriction isn't necessary 762 // For osTeleportOwner, this restriction isn't necessary
756 if (relaxRestrictions || 763
757 m_host.OwnerID 764 // commented out because its redundant and uneeded please remove eventually.
758 == World.LandChannel.GetLandObject( 765 // if (relaxRestrictions ||
759 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 766 // m_host.OwnerID
760 { 767 // == World.LandChannel.GetLandObject(
768 // presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
769 // {
770
761 // We will launch the teleport on a new thread so that when the script threads are terminated 771 // We will launch the teleport on a new thread so that when the script threads are terminated
762 // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting. 772 // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting.
763 Util.FireAndForget( 773 Util.FireAndForget(
@@ -766,7 +776,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
766 new Vector3((float)lookat.x, (float)lookat.y, (float)lookat.z), (uint)TPFlags.ViaLocation)); 776 new Vector3((float)lookat.x, (float)lookat.y, (float)lookat.z), (uint)TPFlags.ViaLocation));
767 777
768 ScriptSleep(5000); 778 ScriptSleep(5000);
769 } 779
780 // }
781
770 } 782 }
771 } 783 }
772 } 784 }
@@ -775,7 +787,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
775 { 787 {
776 // High because there is no security check. High griefer potential 788 // High because there is no security check. High griefer potential
777 // 789 //
778 CheckThreatLevel(ThreatLevel.High, "osTeleportAgent"); 790 CheckThreatLevel(ThreatLevel.Severe, "osTeleportAgent");
779 791
780 TeleportAgent(agent, regionX, regionY, position, lookat, false); 792 TeleportAgent(agent, regionX, regionY, position, lookat, false);
781 } 793 }
@@ -794,11 +806,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
794 { 806 {
795 // For osTeleportAgent, agent must be over owners land to avoid abuse 807 // For osTeleportAgent, agent must be over owners land to avoid abuse
796 // For osTeleportOwner, this restriction isn't necessary 808 // For osTeleportOwner, this restriction isn't necessary
797 if (relaxRestrictions || 809
798 m_host.OwnerID 810 // commented out because its redundant and uneeded please remove eventually.
799 == World.LandChannel.GetLandObject( 811 // if (relaxRestrictions ||
800 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 812 // m_host.OwnerID
801 { 813 // == World.LandChannel.GetLandObject(
814 // presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
815 // {
816
802 // We will launch the teleport on a new thread so that when the script threads are terminated 817 // We will launch the teleport on a new thread so that when the script threads are terminated
803 // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting. 818 // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting.
804 Util.FireAndForget( 819 Util.FireAndForget(
@@ -807,7 +822,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
807 new Vector3((float)lookat.x, (float)lookat.y, (float)lookat.z), (uint)TPFlags.ViaLocation)); 822 new Vector3((float)lookat.x, (float)lookat.y, (float)lookat.z), (uint)TPFlags.ViaLocation));
808 823
809 ScriptSleep(5000); 824 ScriptSleep(5000);
810 } 825
826 // }
827
811 } 828 }
812 } 829 }
813 } 830 }
@@ -871,6 +888,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
871 // threat level is None as we could get this information with an 888 // threat level is None as we could get this information with an
872 // in-world script as well, just not as efficient 889 // in-world script as well, just not as efficient
873 CheckThreatLevel(ThreatLevel.None, "osGetAgents"); 890 CheckThreatLevel(ThreatLevel.None, "osGetAgents");
891 m_host.AddScriptLPS(1);
874 892
875 LSL_List result = new LSL_List(); 893 LSL_List result = new LSL_List();
876 World.ForEachRootScenePresence(delegate(ScenePresence sp) 894 World.ForEachRootScenePresence(delegate(ScenePresence sp)
@@ -885,6 +903,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
885 { 903 {
886 CheckThreatLevel(ThreatLevel.VeryHigh, "osAvatarPlayAnimation"); 904 CheckThreatLevel(ThreatLevel.VeryHigh, "osAvatarPlayAnimation");
887 905
906 AvatarPlayAnimation(avatar, animation);
907 }
908
909 private void AvatarPlayAnimation(string avatar, string animation)
910 {
888 UUID avatarID = (UUID)avatar; 911 UUID avatarID = (UUID)avatar;
889 912
890 m_host.AddScriptLPS(1); 913 m_host.AddScriptLPS(1);
@@ -918,6 +941,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
918 { 941 {
919 CheckThreatLevel(ThreatLevel.VeryHigh, "osAvatarStopAnimation"); 942 CheckThreatLevel(ThreatLevel.VeryHigh, "osAvatarStopAnimation");
920 943
944 AvatarStopAnimation(avatar, animation);
945 }
946
947 private void AvatarStopAnimation(string avatar, string animation)
948 {
921 UUID avatarID = (UUID)avatar; 949 UUID avatarID = (UUID)avatar;
922 950
923 m_host.AddScriptLPS(1); 951 m_host.AddScriptLPS(1);
@@ -1141,6 +1169,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1141 // should be removed 1169 // should be removed
1142 // 1170 //
1143 CheckThreatLevel(ThreatLevel.High, "osSetStateEvents"); 1171 CheckThreatLevel(ThreatLevel.High, "osSetStateEvents");
1172 m_host.AddScriptLPS(1);
1144 1173
1145 m_host.SetScriptEvents(m_itemID, events); 1174 m_host.SetScriptEvents(m_itemID, events);
1146 } 1175 }
@@ -1488,7 +1517,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1488 1517
1489 m_host.AddScriptLPS(1); 1518 m_host.AddScriptLPS(1);
1490 1519
1491
1492 ILandObject land 1520 ILandObject land
1493 = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 1521 = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y);
1494 1522
@@ -1549,6 +1577,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1549 // 1577 //
1550 CheckThreatLevel(ThreatLevel.High,"osGetSimulatorVersion"); 1578 CheckThreatLevel(ThreatLevel.High,"osGetSimulatorVersion");
1551 m_host.AddScriptLPS(1); 1579 m_host.AddScriptLPS(1);
1580
1552 return m_ScriptEngine.World.GetSimulatorVersion(); 1581 return m_ScriptEngine.World.GetSimulatorVersion();
1553 } 1582 }
1554 1583
@@ -1886,6 +1915,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1886 public string osAvatarName2Key(string firstname, string lastname) 1915 public string osAvatarName2Key(string firstname, string lastname)
1887 { 1916 {
1888 CheckThreatLevel(ThreatLevel.Low, "osAvatarName2Key"); 1917 CheckThreatLevel(ThreatLevel.Low, "osAvatarName2Key");
1918 m_host.AddScriptLPS(1);
1889 1919
1890 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, firstname, lastname); 1920 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, firstname, lastname);
1891 if (null == account) 1921 if (null == account)
@@ -1901,6 +1931,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1901 public string osKey2Name(string id) 1931 public string osKey2Name(string id)
1902 { 1932 {
1903 CheckThreatLevel(ThreatLevel.Low, "osKey2Name"); 1933 CheckThreatLevel(ThreatLevel.Low, "osKey2Name");
1934 m_host.AddScriptLPS(1);
1935
1904 UUID key = new UUID(); 1936 UUID key = new UUID();
1905 1937
1906 if (UUID.TryParse(id, out key)) 1938 if (UUID.TryParse(id, out key))
@@ -1921,6 +1953,69 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1921 } 1953 }
1922 } 1954 }
1923 1955
1956 private enum InfoType
1957 {
1958 Nick,
1959 Name,
1960 Login,
1961 Home,
1962 Custom
1963 };
1964
1965 private string GridUserInfo(InfoType type)
1966 {
1967 return GridUserInfo(type, "");
1968 }
1969
1970 private string GridUserInfo(InfoType type, string key)
1971 {
1972 string retval = String.Empty;
1973 IConfigSource config = m_ScriptEngine.ConfigSource;
1974 string url = config.Configs["GridInfo"].GetString("GridInfoURI", String.Empty);
1975
1976 if (String.IsNullOrEmpty(url))
1977 return "Configuration Error!";
1978
1979 string verb ="/json_grid_info";
1980 OSDMap json = new OSDMap();
1981
1982 OSDMap info = WebUtil.GetFromService(String.Format("{0}{1}",url,verb), 3000);
1983
1984 if (info["Success"] != true)
1985 return "Get GridInfo Failed!";
1986
1987 json = (OSDMap)OSDParser.DeserializeJson(info["_RawResult"].AsString());
1988
1989 switch (type)
1990 {
1991 case InfoType.Nick:
1992 retval = json["gridnick"];
1993 break;
1994
1995 case InfoType.Name:
1996 retval = json["gridname"];
1997 break;
1998
1999 case InfoType.Login:
2000 retval = json["login"];
2001 break;
2002
2003 case InfoType.Home:
2004 retval = json["home"];
2005 break;
2006
2007 case InfoType.Custom:
2008 retval = json[key];
2009 break;
2010
2011 default:
2012 retval = "error";
2013 break;
2014 }
2015
2016 return retval;
2017 }
2018
1924 /// <summary> 2019 /// <summary>
1925 /// Get the nickname of this grid, as set in the [GridInfo] config section. 2020 /// Get the nickname of this grid, as set in the [GridInfo] config section.
1926 /// </summary> 2021 /// </summary>
@@ -1934,10 +2029,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1934 { 2029 {
1935 CheckThreatLevel(ThreatLevel.Moderate, "osGetGridNick"); 2030 CheckThreatLevel(ThreatLevel.Moderate, "osGetGridNick");
1936 m_host.AddScriptLPS(1); 2031 m_host.AddScriptLPS(1);
1937 string nick = "hippogrid"; 2032
2033 string nick = String.Empty;
1938 IConfigSource config = m_ScriptEngine.ConfigSource; 2034 IConfigSource config = m_ScriptEngine.ConfigSource;
2035
1939 if (config.Configs["GridInfo"] != null) 2036 if (config.Configs["GridInfo"] != null)
1940 nick = config.Configs["GridInfo"].GetString("gridnick", nick); 2037 nick = config.Configs["GridInfo"].GetString("gridnick", nick);
2038
2039 if (String.IsNullOrEmpty(nick))
2040 nick = GridUserInfo(InfoType.Nick);
2041
1941 return nick; 2042 return nick;
1942 } 2043 }
1943 2044
@@ -1945,10 +2046,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1945 { 2046 {
1946 CheckThreatLevel(ThreatLevel.Moderate, "osGetGridName"); 2047 CheckThreatLevel(ThreatLevel.Moderate, "osGetGridName");
1947 m_host.AddScriptLPS(1); 2048 m_host.AddScriptLPS(1);
1948 string name = "the lost continent of hippo"; 2049
2050 string name = String.Empty;
1949 IConfigSource config = m_ScriptEngine.ConfigSource; 2051 IConfigSource config = m_ScriptEngine.ConfigSource;
2052
1950 if (config.Configs["GridInfo"] != null) 2053 if (config.Configs["GridInfo"] != null)
1951 name = config.Configs["GridInfo"].GetString("gridname", name); 2054 name = config.Configs["GridInfo"].GetString("gridname", name);
2055
2056 if (String.IsNullOrEmpty(name))
2057 name = GridUserInfo(InfoType.Name);
2058
1952 return name; 2059 return name;
1953 } 2060 }
1954 2061
@@ -1956,13 +2063,53 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1956 { 2063 {
1957 CheckThreatLevel(ThreatLevel.Moderate, "osGetGridLoginURI"); 2064 CheckThreatLevel(ThreatLevel.Moderate, "osGetGridLoginURI");
1958 m_host.AddScriptLPS(1); 2065 m_host.AddScriptLPS(1);
1959 string loginURI = "http://127.0.0.1:9000/"; 2066
2067 string loginURI = String.Empty;
1960 IConfigSource config = m_ScriptEngine.ConfigSource; 2068 IConfigSource config = m_ScriptEngine.ConfigSource;
2069
1961 if (config.Configs["GridInfo"] != null) 2070 if (config.Configs["GridInfo"] != null)
1962 loginURI = config.Configs["GridInfo"].GetString("login", loginURI); 2071 loginURI = config.Configs["GridInfo"].GetString("login", loginURI);
2072
2073 if (String.IsNullOrEmpty(loginURI))
2074 loginURI = GridUserInfo(InfoType.Login);
2075
1963 return loginURI; 2076 return loginURI;
1964 } 2077 }
1965 2078
2079 public string osGetGridHomeURI()
2080 {
2081 CheckThreatLevel(ThreatLevel.Moderate, "osGetGridHomeURI");
2082 m_host.AddScriptLPS(1);
2083
2084 string HomeURI = String.Empty;
2085 IConfigSource config = m_ScriptEngine.ConfigSource;
2086
2087 if (config.Configs["LoginService"] != null)
2088 HomeURI = config.Configs["LoginService"].GetString("SRV_HomeURI", HomeURI);
2089
2090 if (String.IsNullOrEmpty(HomeURI))
2091 HomeURI = GridUserInfo(InfoType.Home);
2092
2093 return HomeURI;
2094 }
2095
2096 public string osGetGridCustom(string key)
2097 {
2098 CheckThreatLevel(ThreatLevel.Moderate, "osGetGridCustom");
2099 m_host.AddScriptLPS(1);
2100
2101 string retval = String.Empty;
2102 IConfigSource config = m_ScriptEngine.ConfigSource;
2103
2104 if (config.Configs["GridInfo"] != null)
2105 retval = config.Configs["GridInfo"].GetString(key, retval);
2106
2107 if (String.IsNullOrEmpty(retval))
2108 retval = GridUserInfo(InfoType.Custom, key);
2109
2110 return retval;
2111 }
2112
1966 public LSL_String osFormatString(string str, LSL_List strings) 2113 public LSL_String osFormatString(string str, LSL_List strings)
1967 { 2114 {
1968 CheckThreatLevel(ThreatLevel.Low, "osFormatString"); 2115 CheckThreatLevel(ThreatLevel.Low, "osFormatString");
@@ -2064,10 +2211,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2064 return retVal; 2211 return retVal;
2065 } 2212 }
2066 2213
2214 public LSL_Integer osIsNpc(LSL_Key npc)
2215 {
2216 CheckThreatLevel(ThreatLevel.None, "osIsNpc");
2217 m_host.AddScriptLPS(1);
2218
2219 INPCModule module = World.RequestModuleInterface<INPCModule>();
2220 if (module != null)
2221 {
2222 UUID npcId;
2223 if (UUID.TryParse(npc.m_string, out npcId))
2224 if (module.IsNPC(npcId, World))
2225 return ScriptBaseClass.TRUE;
2226 }
2227
2228 return ScriptBaseClass.FALSE;
2229 }
2230
2067 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard) 2231 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard)
2068 { 2232 {
2069 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2233 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2234 m_host.AddScriptLPS(1);
2235
2236 return NpcCreate(firstname, lastname, position, notecard, false, true);
2237 }
2238
2239 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
2240 {
2241 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2242 m_host.AddScriptLPS(1);
2070 2243
2244 return NpcCreate(
2245 firstname, lastname, position, notecard,
2246 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2247 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) == 0);
2248 }
2249
2250 private LSL_Key NpcCreate(
2251 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2252 {
2071 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2253 INPCModule module = World.RequestModuleInterface<INPCModule>();
2072 if (module != null) 2254 if (module != null)
2073 { 2255 {
@@ -2096,9 +2278,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2096 if (appearance == null) 2278 if (appearance == null)
2097 return new LSL_Key(UUID.Zero.ToString()); 2279 return new LSL_Key(UUID.Zero.ToString());
2098 2280
2281 UUID ownerID = UUID.Zero;
2282 if (owned)
2283 ownerID = m_host.OwnerID;
2099 UUID x = module.CreateNPC(firstname, 2284 UUID x = module.CreateNPC(firstname,
2100 lastname, 2285 lastname,
2101 new Vector3((float) position.x, (float) position.y, (float) position.z), 2286 new Vector3((float) position.x, (float) position.y, (float) position.z),
2287 ownerID,
2288 senseAsAgent,
2102 World, 2289 World,
2103 appearance); 2290 appearance);
2104 2291
@@ -2117,6 +2304,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2117 public LSL_Key osNpcSaveAppearance(LSL_Key npc, string notecard) 2304 public LSL_Key osNpcSaveAppearance(LSL_Key npc, string notecard)
2118 { 2305 {
2119 CheckThreatLevel(ThreatLevel.High, "osNpcSaveAppearance"); 2306 CheckThreatLevel(ThreatLevel.High, "osNpcSaveAppearance");
2307 m_host.AddScriptLPS(1);
2120 2308
2121 INPCModule npcModule = World.RequestModuleInterface<INPCModule>(); 2309 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
2122 2310
@@ -2126,7 +2314,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2126 if (!UUID.TryParse(npc.m_string, out npcId)) 2314 if (!UUID.TryParse(npc.m_string, out npcId))
2127 return new LSL_Key(UUID.Zero.ToString()); 2315 return new LSL_Key(UUID.Zero.ToString());
2128 2316
2129 if (!npcModule.IsNPC(npcId, m_host.ParentGroup.Scene)) 2317 if (!npcModule.CheckPermissions(npcId, m_host.OwnerID))
2130 return new LSL_Key(UUID.Zero.ToString()); 2318 return new LSL_Key(UUID.Zero.ToString());
2131 2319
2132 return SaveAppearanceToNotecard(npcId, notecard); 2320 return SaveAppearanceToNotecard(npcId, notecard);
@@ -2138,6 +2326,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2138 public void osNpcLoadAppearance(LSL_Key npc, string notecard) 2326 public void osNpcLoadAppearance(LSL_Key npc, string notecard)
2139 { 2327 {
2140 CheckThreatLevel(ThreatLevel.High, "osNpcLoadAppearance"); 2328 CheckThreatLevel(ThreatLevel.High, "osNpcLoadAppearance");
2329 m_host.AddScriptLPS(1);
2141 2330
2142 INPCModule npcModule = World.RequestModuleInterface<INPCModule>(); 2331 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
2143 2332
@@ -2147,6 +2336,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2147 if (!UUID.TryParse(npc.m_string, out npcId)) 2336 if (!UUID.TryParse(npc.m_string, out npcId))
2148 return; 2337 return;
2149 2338
2339 if (!npcModule.CheckPermissions(npcId, m_host.OwnerID))
2340 return;
2341
2150 string appearanceSerialized = LoadNotecard(notecard); 2342 string appearanceSerialized = LoadNotecard(notecard);
2151 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized); 2343 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized);
2152// OSD a = OSDParser.DeserializeLLSDXml(appearanceSerialized); 2344// OSD a = OSDParser.DeserializeLLSDXml(appearanceSerialized);
@@ -2159,9 +2351,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2159 } 2351 }
2160 } 2352 }
2161 2353
2354 public LSL_Key osNpcGetOwner(LSL_Key npc)
2355 {
2356 CheckThreatLevel(ThreatLevel.None, "osNpcGetOwner");
2357 m_host.AddScriptLPS(1);
2358
2359 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
2360 if (npcModule != null)
2361 {
2362 UUID npcId;
2363 if (UUID.TryParse(npc.m_string, out npcId))
2364 {
2365 UUID owner = npcModule.GetOwner(npcId);
2366 if (owner != UUID.Zero)
2367 return new LSL_Key(owner.ToString());
2368 else
2369 return npc;
2370 }
2371 }
2372
2373 return new LSL_Key(UUID.Zero.ToString());
2374 }
2375
2162 public LSL_Vector osNpcGetPos(LSL_Key npc) 2376 public LSL_Vector osNpcGetPos(LSL_Key npc)
2163 { 2377 {
2164 CheckThreatLevel(ThreatLevel.High, "osNpcGetPos"); 2378 CheckThreatLevel(ThreatLevel.High, "osNpcGetPos");
2379 m_host.AddScriptLPS(1);
2165 2380
2166 INPCModule npcModule = World.RequestModuleInterface<INPCModule>(); 2381 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
2167 if (npcModule != null) 2382 if (npcModule != null)
@@ -2170,7 +2385,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2170 if (!UUID.TryParse(npc.m_string, out npcId)) 2385 if (!UUID.TryParse(npc.m_string, out npcId))
2171 return new LSL_Vector(0, 0, 0); 2386 return new LSL_Vector(0, 0, 0);
2172 2387
2173 if (!npcModule.IsNPC(npcId, m_host.ParentGroup.Scene)) 2388 if (!npcModule.CheckPermissions(npcId, m_host.OwnerID))
2174 return new LSL_Vector(0, 0, 0); 2389 return new LSL_Vector(0, 0, 0);
2175 2390
2176 Vector3 pos = World.GetScenePresence(npcId).AbsolutePosition; 2391 Vector3 pos = World.GetScenePresence(npcId).AbsolutePosition;
@@ -2183,6 +2398,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2183 public void osNpcMoveTo(LSL_Key npc, LSL_Vector position) 2398 public void osNpcMoveTo(LSL_Key npc, LSL_Vector position)
2184 { 2399 {
2185 CheckThreatLevel(ThreatLevel.High, "osNpcMoveTo"); 2400 CheckThreatLevel(ThreatLevel.High, "osNpcMoveTo");
2401 m_host.AddScriptLPS(1);
2186 2402
2187 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2403 INPCModule module = World.RequestModuleInterface<INPCModule>();
2188 if (module != null) 2404 if (module != null)
@@ -2190,6 +2406,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2190 UUID npcId; 2406 UUID npcId;
2191 if (!UUID.TryParse(npc.m_string, out npcId)) 2407 if (!UUID.TryParse(npc.m_string, out npcId))
2192 return; 2408 return;
2409
2410 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2411 return;
2193 2412
2194 Vector3 pos = new Vector3((float) position.x, (float) position.y, (float) position.z); 2413 Vector3 pos = new Vector3((float) position.x, (float) position.y, (float) position.z);
2195 module.MoveToTarget(npcId, World, pos, false, true); 2414 module.MoveToTarget(npcId, World, pos, false, true);
@@ -2199,6 +2418,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2199 public void osNpcMoveToTarget(LSL_Key npc, LSL_Vector target, int options) 2418 public void osNpcMoveToTarget(LSL_Key npc, LSL_Vector target, int options)
2200 { 2419 {
2201 CheckThreatLevel(ThreatLevel.High, "osNpcMoveToTarget"); 2420 CheckThreatLevel(ThreatLevel.High, "osNpcMoveToTarget");
2421 m_host.AddScriptLPS(1);
2202 2422
2203 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2423 INPCModule module = World.RequestModuleInterface<INPCModule>();
2204 if (module != null) 2424 if (module != null)
@@ -2207,6 +2427,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2207 if (!UUID.TryParse(npc.m_string, out npcId)) 2427 if (!UUID.TryParse(npc.m_string, out npcId))
2208 return; 2428 return;
2209 2429
2430 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2431 return;
2432
2210 Vector3 pos = new Vector3((float)target.x, (float)target.y, (float)target.z); 2433 Vector3 pos = new Vector3((float)target.x, (float)target.y, (float)target.z);
2211 module.MoveToTarget( 2434 module.MoveToTarget(
2212 new UUID(npc.m_string), 2435 new UUID(npc.m_string),
@@ -2220,6 +2443,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2220 public LSL_Rotation osNpcGetRot(LSL_Key npc) 2443 public LSL_Rotation osNpcGetRot(LSL_Key npc)
2221 { 2444 {
2222 CheckThreatLevel(ThreatLevel.High, "osNpcGetRot"); 2445 CheckThreatLevel(ThreatLevel.High, "osNpcGetRot");
2446 m_host.AddScriptLPS(1);
2223 2447
2224 INPCModule npcModule = World.RequestModuleInterface<INPCModule>(); 2448 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
2225 if (npcModule != null) 2449 if (npcModule != null)
@@ -2228,7 +2452,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2228 if (!UUID.TryParse(npc.m_string, out npcId)) 2452 if (!UUID.TryParse(npc.m_string, out npcId))
2229 return new LSL_Rotation(Quaternion.Identity.X, Quaternion.Identity.Y, Quaternion.Identity.Z, Quaternion.Identity.W); 2453 return new LSL_Rotation(Quaternion.Identity.X, Quaternion.Identity.Y, Quaternion.Identity.Z, Quaternion.Identity.W);
2230 2454
2231 if (!npcModule.IsNPC(npcId, m_host.ParentGroup.Scene)) 2455 if (!npcModule.CheckPermissions(npcId, m_host.OwnerID))
2232 return new LSL_Rotation(Quaternion.Identity.X, Quaternion.Identity.Y, Quaternion.Identity.Z, Quaternion.Identity.W); 2456 return new LSL_Rotation(Quaternion.Identity.X, Quaternion.Identity.Y, Quaternion.Identity.Z, Quaternion.Identity.W);
2233 2457
2234 ScenePresence sp = World.GetScenePresence(npcId); 2458 ScenePresence sp = World.GetScenePresence(npcId);
@@ -2243,6 +2467,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2243 public void osNpcSetRot(LSL_Key npc, LSL_Rotation rotation) 2467 public void osNpcSetRot(LSL_Key npc, LSL_Rotation rotation)
2244 { 2468 {
2245 CheckThreatLevel(ThreatLevel.High, "osNpcSetRot"); 2469 CheckThreatLevel(ThreatLevel.High, "osNpcSetRot");
2470 m_host.AddScriptLPS(1);
2246 2471
2247 INPCModule npcModule = World.RequestModuleInterface<INPCModule>(); 2472 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
2248 if (npcModule != null) 2473 if (npcModule != null)
@@ -2251,7 +2476,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2251 if (!UUID.TryParse(npc.m_string, out npcId)) 2476 if (!UUID.TryParse(npc.m_string, out npcId))
2252 return; 2477 return;
2253 2478
2254 if (!npcModule.IsNPC(npcId, m_host.ParentGroup.Scene)) 2479 if (!npcModule.CheckPermissions(npcId, m_host.OwnerID))
2255 return; 2480 return;
2256 2481
2257 ScenePresence sp = World.GetScenePresence(npcId); 2482 ScenePresence sp = World.GetScenePresence(npcId);
@@ -2262,53 +2487,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2262 public void osNpcStopMoveToTarget(LSL_Key npc) 2487 public void osNpcStopMoveToTarget(LSL_Key npc)
2263 { 2488 {
2264 CheckThreatLevel(ThreatLevel.VeryLow, "osNpcStopMoveTo"); 2489 CheckThreatLevel(ThreatLevel.VeryLow, "osNpcStopMoveTo");
2490 m_host.AddScriptLPS(1);
2265 2491
2266 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2492 INPCModule module = World.RequestModuleInterface<INPCModule>();
2267 if (module != null) 2493 if (module != null)
2268 module.StopMoveToTarget(new UUID(npc.m_string), World); 2494 {
2495 UUID npcId = new UUID(npc.m_string);
2496
2497 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2498 return;
2499
2500 module.StopMoveToTarget(npcId, World);
2501 }
2269 } 2502 }
2270 2503
2271 public void osNpcSay(LSL_Key npc, string message) 2504 public void osNpcSay(LSL_Key npc, string message)
2272 { 2505 {
2273 CheckThreatLevel(ThreatLevel.High, "osNpcSay"); 2506 CheckThreatLevel(ThreatLevel.High, "osNpcSay");
2507 m_host.AddScriptLPS(1);
2274 2508
2275 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2509 INPCModule module = World.RequestModuleInterface<INPCModule>();
2276 if (module != null) 2510 if (module != null)
2277 { 2511 {
2278 module.Say(new UUID(npc.m_string), World, message); 2512 UUID npcId = new UUID(npc.m_string);
2513
2514 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2515 return;
2516
2517 module.Say(npcId, World, message);
2279 } 2518 }
2280 } 2519 }
2281 2520
2282 public void osNpcSit(LSL_Key npc, LSL_Key target, int options) 2521 public void osNpcSit(LSL_Key npc, LSL_Key target, int options)
2283 { 2522 {
2284 CheckThreatLevel(ThreatLevel.High, "osNpcSit"); 2523 CheckThreatLevel(ThreatLevel.High, "osNpcSit");
2524 m_host.AddScriptLPS(1);
2285 2525
2286 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2526 INPCModule module = World.RequestModuleInterface<INPCModule>();
2287 if (module != null) 2527 if (module != null)
2288 { 2528 {
2289 module.Sit(new UUID(npc.m_string), new UUID(target.m_string), World); 2529 UUID npcId = new UUID(npc.m_string);
2530
2531 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2532 return;
2533
2534 module.Sit(npcId, new UUID(target.m_string), World);
2290 } 2535 }
2291 } 2536 }
2292 2537
2293 public void osNpcStand(LSL_Key npc) 2538 public void osNpcStand(LSL_Key npc)
2294 { 2539 {
2295 CheckThreatLevel(ThreatLevel.High, "osNpcStand"); 2540 CheckThreatLevel(ThreatLevel.High, "osNpcStand");
2541 m_host.AddScriptLPS(1);
2296 2542
2297 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2543 INPCModule module = World.RequestModuleInterface<INPCModule>();
2298 if (module != null) 2544 if (module != null)
2299 { 2545 {
2300 module.Stand(new UUID(npc.m_string), World); 2546 UUID npcId = new UUID(npc.m_string);
2547
2548 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2549 return;
2550
2551 module.Stand(npcId, World);
2301 } 2552 }
2302 } 2553 }
2303 2554
2304 public void osNpcRemove(LSL_Key npc) 2555 public void osNpcRemove(LSL_Key npc)
2305 { 2556 {
2306 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2557 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2558 m_host.AddScriptLPS(1);
2559
2560 INPCModule module = World.RequestModuleInterface<INPCModule>();
2561 if (module != null)
2562 {
2563 UUID npcId = new UUID(npc.m_string);
2564
2565 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2566 return;
2567
2568 module.DeleteNPC(npcId, World);
2569 }
2570 }
2571
2572 public void osNpcPlayAnimation(LSL_Key npc, string animation)
2573 {
2574 CheckThreatLevel(ThreatLevel.High, "osNpcPlayAnimation");
2575 m_host.AddScriptLPS(1);
2576
2577 INPCModule module = World.RequestModuleInterface<INPCModule>();
2578 if (module != null)
2579 {
2580 UUID npcID = new UUID(npc.m_string);
2581
2582 if (module.CheckPermissions(npcID, m_host.OwnerID))
2583 AvatarPlayAnimation(npcID.ToString(), animation);
2584 }
2585 }
2586
2587 public void osNpcStopAnimation(LSL_Key npc, string animation)
2588 {
2589 CheckThreatLevel(ThreatLevel.High, "osNpcStopAnimation");
2590 m_host.AddScriptLPS(1);
2307 2591
2308 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2592 INPCModule module = World.RequestModuleInterface<INPCModule>();
2309 if (module != null) 2593 if (module != null)
2310 { 2594 {
2311 module.DeleteNPC(new UUID(npc.m_string), World); 2595 UUID npcID = new UUID(npc.m_string);
2596
2597 if (module.CheckPermissions(npcID, m_host.OwnerID))
2598 AvatarPlayAnimation(npcID.ToString(), animation);
2312 } 2599 }
2313 } 2600 }
2314 2601
@@ -2320,6 +2607,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2320 public LSL_Key osOwnerSaveAppearance(string notecard) 2607 public LSL_Key osOwnerSaveAppearance(string notecard)
2321 { 2608 {
2322 CheckThreatLevel(ThreatLevel.High, "osOwnerSaveAppearance"); 2609 CheckThreatLevel(ThreatLevel.High, "osOwnerSaveAppearance");
2610 m_host.AddScriptLPS(1);
2323 2611
2324 return SaveAppearanceToNotecard(m_host.OwnerID, notecard); 2612 return SaveAppearanceToNotecard(m_host.OwnerID, notecard);
2325 } 2613 }
@@ -2327,6 +2615,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2327 public LSL_Key osAgentSaveAppearance(LSL_Key avatarId, string notecard) 2615 public LSL_Key osAgentSaveAppearance(LSL_Key avatarId, string notecard)
2328 { 2616 {
2329 CheckThreatLevel(ThreatLevel.VeryHigh, "osAgentSaveAppearance"); 2617 CheckThreatLevel(ThreatLevel.VeryHigh, "osAgentSaveAppearance");
2618 m_host.AddScriptLPS(1);
2330 2619
2331 return SaveAppearanceToNotecard(avatarId, notecard); 2620 return SaveAppearanceToNotecard(avatarId, notecard);
2332 } 2621 }
@@ -2377,6 +2666,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2377 public LSL_Key osGetMapTexture() 2666 public LSL_Key osGetMapTexture()
2378 { 2667 {
2379 CheckThreatLevel(ThreatLevel.None, "osGetMapTexture"); 2668 CheckThreatLevel(ThreatLevel.None, "osGetMapTexture");
2669 m_host.AddScriptLPS(1);
2670
2380 return m_ScriptEngine.World.RegionInfo.RegionSettings.TerrainImageID.ToString(); 2671 return m_ScriptEngine.World.RegionInfo.RegionSettings.TerrainImageID.ToString();
2381 } 2672 }
2382 2673
@@ -2388,6 +2679,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2388 public LSL_Key osGetRegionMapTexture(string regionName) 2679 public LSL_Key osGetRegionMapTexture(string regionName)
2389 { 2680 {
2390 CheckThreatLevel(ThreatLevel.High, "osGetRegionMapTexture"); 2681 CheckThreatLevel(ThreatLevel.High, "osGetRegionMapTexture");
2682 m_host.AddScriptLPS(1);
2683
2391 Scene scene = m_ScriptEngine.World; 2684 Scene scene = m_ScriptEngine.World;
2392 UUID key = UUID.Zero; 2685 UUID key = UUID.Zero;
2393 GridRegion region; 2686 GridRegion region;
@@ -2453,6 +2746,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2453 public void osKickAvatar(string FirstName,string SurName,string alert) 2746 public void osKickAvatar(string FirstName,string SurName,string alert)
2454 { 2747 {
2455 CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar"); 2748 CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar");
2749 m_host.AddScriptLPS(1);
2750
2456 if (World.Permissions.CanRunConsoleCommand(m_host.OwnerID)) 2751 if (World.Permissions.CanRunConsoleCommand(m_host.OwnerID))
2457 { 2752 {
2458 World.ForEachRootScenePresence(delegate(ScenePresence sp) 2753 World.ForEachRootScenePresence(delegate(ScenePresence sp)
@@ -2587,6 +2882,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2587 public LSL_List osGetAvatarList() 2882 public LSL_List osGetAvatarList()
2588 { 2883 {
2589 CheckThreatLevel(ThreatLevel.None, "osGetAvatarList"); 2884 CheckThreatLevel(ThreatLevel.None, "osGetAvatarList");
2885 m_host.AddScriptLPS(1);
2590 2886
2591 LSL_List result = new LSL_List(); 2887 LSL_List result = new LSL_List();
2592 World.ForEachRootScenePresence(delegate (ScenePresence avatar) 2888 World.ForEachRootScenePresence(delegate (ScenePresence avatar)
@@ -2611,6 +2907,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2611 public LSL_String osUnixTimeToTimestamp(long time) 2907 public LSL_String osUnixTimeToTimestamp(long time)
2612 { 2908 {
2613 CheckThreatLevel(ThreatLevel.VeryLow, "osUnixTimeToTimestamp"); 2909 CheckThreatLevel(ThreatLevel.VeryLow, "osUnixTimeToTimestamp");
2910 m_host.AddScriptLPS(1);
2911
2614 long baseTicks = 621355968000000000; 2912 long baseTicks = 621355968000000000;
2615 long tickResolution = 10000000; 2913 long tickResolution = 10000000;
2616 long epochTicks = (time * tickResolution) + baseTicks; 2914 long epochTicks = (time * tickResolution) + baseTicks;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 3eeb23d..3e0e452 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -26,10 +26,13 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Reflection;
29using System.Collections.Generic; 30using System.Collections.Generic;
30using OpenMetaverse; 31using OpenMetaverse;
31using OpenSim.Framework; 32using OpenSim.Framework;
33using log4net;
32 34
35using OpenSim.Region.Framework.Interfaces;
33using OpenSim.Region.Framework.Scenes; 36using OpenSim.Region.Framework.Scenes;
34using OpenSim.Region.ScriptEngine.Shared; 37using OpenSim.Region.ScriptEngine.Shared;
35using OpenSim.Region.ScriptEngine.Shared.Api; 38using OpenSim.Region.ScriptEngine.Shared.Api;
@@ -51,6 +54,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
51 54
52 private const int AGENT = 1; 55 private const int AGENT = 1;
53 private const int AGENT_BY_USERNAME = 0x10; 56 private const int AGENT_BY_USERNAME = 0x10;
57 private const int NPC = 0x20;
54 private const int ACTIVE = 2; 58 private const int ACTIVE = 2;
55 private const int PASSIVE = 4; 59 private const int PASSIVE = 4;
56 private const int SCRIPTED = 8; 60 private const int SCRIPTED = 8;
@@ -203,7 +207,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
203 List<SensedEntity> sensedEntities = new List<SensedEntity>(); 207 List<SensedEntity> sensedEntities = new List<SensedEntity>();
204 208
205 // Is the sensor type is AGENT and not SCRIPTED then include agents 209 // Is the sensor type is AGENT and not SCRIPTED then include agents
206 if ((ts.type & (AGENT | AGENT_BY_USERNAME)) != 0 && (ts.type & SCRIPTED) == 0) 210 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC)) != 0 && (ts.type & SCRIPTED) == 0)
207 { 211 {
208 sensedEntities.AddRange(doAgentSensor(ts)); 212 sensedEntities.AddRange(doAgentSensor(ts));
209 } 213 }
@@ -413,6 +417,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
413 417
414 private List<SensedEntity> doAgentSensor(SenseRepeatClass ts) 418 private List<SensedEntity> doAgentSensor(SenseRepeatClass ts)
415 { 419 {
420 INPCModule npcModule = m_CmdManager.m_ScriptEngine.World.RequestModuleInterface<INPCModule>();
421
416 List<SensedEntity> sensedEntities = new List<SensedEntity>(); 422 List<SensedEntity> sensedEntities = new List<SensedEntity>();
417 423
418 // If nobody about quit fast 424 // If nobody about quit fast
@@ -441,6 +447,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
441 447
442 Action<ScenePresence> senseEntity = new Action<ScenePresence>(delegate(ScenePresence presence) 448 Action<ScenePresence> senseEntity = new Action<ScenePresence>(delegate(ScenePresence presence)
443 { 449 {
450 if ((ts.type & NPC) == 0
451 && presence.PresenceType == PresenceType.Npc
452 && !npcModule.GetNPC(presence.UUID, presence.Scene).SenseAsAgent)
453 return;
454
455 if ((ts.type & AGENT) == 0
456 && (presence.PresenceType == PresenceType.User
457 || npcModule.GetNPC(presence.UUID, presence.Scene).SenseAsAgent))
458 return;
459
444 if (presence.IsDeleted || presence.IsChildAgent || presence.GodLevel > 0.0) 460 if (presence.IsDeleted || presence.IsChildAgent || presence.GodLevel > 0.0)
445 return; 461 return;
446 462
@@ -452,6 +468,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
452 toRegionPos = presence.AbsolutePosition; 468 toRegionPos = presence.AbsolutePosition;
453 dis = Math.Abs(Util.GetDistanceTo(toRegionPos, fromRegionPos)); 469 dis = Math.Abs(Util.GetDistanceTo(toRegionPos, fromRegionPos));
454 470
471 // Disabled for now since all osNpc* methods check for appropriate ownership permission.
472 // Perhaps could be re-enabled as an NPC setting at some point since being able to make NPCs not
473 // sensed might be useful.
474// if (presence.PresenceType == PresenceType.Npc && npcModule != null)
475// {
476// UUID npcOwner = npcModule.GetOwner(presence.UUID);
477// if (npcOwner != UUID.Zero && npcOwner != SensePoint.OwnerID)
478// return;
479// }
480
455 // are they in range 481 // are they in range
456 if (dis <= ts.range) 482 if (dis <= ts.range)
457 { 483 {
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
index 62e2854..b66537f 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -161,6 +161,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
161 LSL_List llGetParcelDetails(LSL_Vector pos, LSL_List param); 161 LSL_List llGetParcelDetails(LSL_Vector pos, LSL_List param);
162 LSL_Integer llGetParcelFlags(LSL_Vector pos); 162 LSL_Integer llGetParcelFlags(LSL_Vector pos);
163 LSL_Integer llGetParcelMaxPrims(LSL_Vector pos, int sim_wide); 163 LSL_Integer llGetParcelMaxPrims(LSL_Vector pos, int sim_wide);
164 LSL_String llGetParcelMusicURL();
164 LSL_Integer llGetParcelPrimCount(LSL_Vector pos, int category, int sim_wide); 165 LSL_Integer llGetParcelPrimCount(LSL_Vector pos, int category, int sim_wide);
165 LSL_List llGetParcelPrimOwners(LSL_Vector pos); 166 LSL_List llGetParcelPrimOwners(LSL_Vector pos);
166 LSL_Integer llGetPermissions(); 167 LSL_Integer llGetPermissions();
@@ -241,6 +242,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
241 void llLoopSound(string sound, double volume); 242 void llLoopSound(string sound, double volume);
242 void llLoopSoundMaster(string sound, double volume); 243 void llLoopSoundMaster(string sound, double volume);
243 void llLoopSoundSlave(string sound, double volume); 244 void llLoopSoundSlave(string sound, double volume);
245 LSL_Integer llManageEstateAccess(int action, string avatar);
244 void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset); 246 void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset);
245 void llMakeFire(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset); 247 void llMakeFire(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset);
246 void llMakeFountain(int particles, double scale, double vel, double lifetime, double arc, int bounce, string texture, LSL_Vector offset, double bounce_offset); 248 void llMakeFountain(int particles, double scale, double vel, double lifetime, double arc, int bounce, string texture, LSL_Vector offset, double bounce_offset);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 00ca070..dbc1dfc 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -42,6 +42,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
42{ 42{
43 public enum ThreatLevel 43 public enum ThreatLevel
44 { 44 {
45 NoAccess = -1,
45 None = 0, 46 None = 0,
46 Nuisance = 1, 47 Nuisance = 1,
47 VeryLow = 2, 48 VeryLow = 2,
@@ -159,6 +160,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
159 string osGetGridNick(); 160 string osGetGridNick();
160 string osGetGridName(); 161 string osGetGridName();
161 string osGetGridLoginURI(); 162 string osGetGridLoginURI();
163 string osGetGridHomeURI();
164 string osGetGridCustom(string key);
162 165
163 LSL_String osFormatString(string str, LSL_List strings); 166 LSL_String osFormatString(string str, LSL_List strings);
164 LSL_List osMatchString(string src, string pattern, int start); 167 LSL_List osMatchString(string src, string pattern, int start);
@@ -170,22 +173,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
170 173
171 LSL_List osGetLinkPrimitiveParams(int linknumber, LSL_List rules); 174 LSL_List osGetLinkPrimitiveParams(int linknumber, LSL_List rules);
172 175
173 key osNpcCreate(string user, string name, vector position, string notecard); 176 /// <summary>
174 LSL_Key osNpcSaveAppearance(key npc, string notecard); 177 /// Check if the given key is an npc
175 void osNpcLoadAppearance(key npc, string notecard); 178 /// </summary>
176 vector osNpcGetPos(key npc); 179 /// <param name="npc"></param>
177 void osNpcMoveTo(key npc, vector position); 180 /// <returns>TRUE if the key belongs to an npc in the scene. FALSE otherwise.</returns>
178 void osNpcMoveToTarget(key npc, vector target, int options); 181 LSL_Integer osIsNpc(LSL_Key npc);
179 rotation osNpcGetRot(key npc); 182
180 void osNpcSetRot(LSL_Key npc, rotation rot); 183 key osNpcCreate(string user, string name, vector position, string notecard);
181 void osNpcStopMoveToTarget(LSL_Key npc); 184 key osNpcCreate(string user, string name, vector position, string notecard, int options);
182 void osNpcSay(key npc, string message); 185 LSL_Key osNpcSaveAppearance(key npc, string notecard);
183 void osNpcSit(key npc, key target, int options); 186 void osNpcLoadAppearance(key npc, string notecard);
184 void osNpcStand(LSL_Key npc); 187 vector osNpcGetPos(key npc);
185 void osNpcRemove(key npc); 188 void osNpcMoveTo(key npc, vector position);
186 189 void osNpcMoveToTarget(key npc, vector target, int options);
187 LSL_Key osOwnerSaveAppearance(string notecard); 190
188 LSL_Key osAgentSaveAppearance(key agentId, string notecard); 191 /// <summary>
192 /// Get the owner of the NPC
193 /// </summary>
194 /// <param name="npc"></param>
195 /// <returns>
196 /// The owner of the NPC for an owned NPC. The NPC's agent id for an unowned NPC. UUID.Zero if the key is not an npc.
197 /// </returns>
198 LSL_Key osNpcGetOwner(key npc);
199
200 rotation osNpcGetRot(key npc);
201 void osNpcSetRot(LSL_Key npc, rotation rot);
202 void osNpcStopMoveToTarget(LSL_Key npc);
203 void osNpcSay(key npc, string message);
204 void osNpcSit(key npc, key target, int options);
205 void osNpcStand(LSL_Key npc);
206 void osNpcRemove(key npc);
207 void osNpcPlayAnimation(LSL_Key npc, string animation);
208 void osNpcStopAnimation(LSL_Key npc, string animation);
209
210 LSL_Key osOwnerSaveAppearance(string notecard);
211 LSL_Key osAgentSaveAppearance(key agentId, string notecard);
189 212
190 key osGetMapTexture(); 213 key osGetMapTexture();
191 key osGetRegionMapTexture(string regionName); 214 key osGetRegionMapTexture(string regionName);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index fd08373..a69b4cb 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -52,6 +52,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
52 public const int AGENT = 1; 52 public const int AGENT = 1;
53 public const int AGENT_BY_LEGACY_NAME = 1; 53 public const int AGENT_BY_LEGACY_NAME = 1;
54 public const int AGENT_BY_USERNAME = 0x10; 54 public const int AGENT_BY_USERNAME = 0x10;
55 public const int NPC = 0x20;
55 public const int ACTIVE = 2; 56 public const int ACTIVE = 2;
56 public const int PASSIVE = 4; 57 public const int PASSIVE = 4;
57 public const int SCRIPTED = 8; 58 public const int SCRIPTED = 8;
@@ -431,6 +432,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
431 public const int REGION_FLAG_ALLOW_DIRECT_TELEPORT = 0x100000; // region allows direct teleports 432 public const int REGION_FLAG_ALLOW_DIRECT_TELEPORT = 0x100000; // region allows direct teleports
432 public const int REGION_FLAG_RESTRICT_PUSHOBJECT = 0x400000; // region restricts llPushObject 433 public const int REGION_FLAG_RESTRICT_PUSHOBJECT = 0x400000; // region restricts llPushObject
433 434
435 //llManageEstateAccess
436 public const int ESTATE_ACCESS_ALLOWED_AGENT_ADD = 0;
437 public const int ESTATE_ACCESS_ALLOWED_AGENT_REMOVE = 1;
438 public const int ESTATE_ACCESS_ALLOWED_GROUP_ADD = 2;
439 public const int ESTATE_ACCESS_ALLOWED_GROUP_REMOVE = 3;
440 public const int ESTATE_ACCESS_BANNED_AGENT_ADD = 4;
441 public const int ESTATE_ACCESS_BANNED_AGENT_REMOVE = 5;
442
434 public static readonly LSLInteger PAY_HIDE = new LSLInteger(-1); 443 public static readonly LSLInteger PAY_HIDE = new LSLInteger(-1);
435 public static readonly LSLInteger PAY_DEFAULT = new LSLInteger(-2); 444 public static readonly LSLInteger PAY_DEFAULT = new LSLInteger(-2);
436 445
@@ -605,6 +614,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
605 614
606 public const int OS_NPC_SIT_NOW = 0; 615 public const int OS_NPC_SIT_NOW = 0;
607 616
617 public const int OS_NPC_CREATOR_OWNED = 0x1;
618 public const int OS_NPC_NOT_OWNED = 0x2;
619 public const int OS_NPC_SENSE_AS_AGENT = 0x4;
620
608 public const string URL_REQUEST_GRANTED = "URL_REQUEST_GRANTED"; 621 public const string URL_REQUEST_GRANTED = "URL_REQUEST_GRANTED";
609 public const string URL_REQUEST_DENIED = "URL_REQUEST_DENIED"; 622 public const string URL_REQUEST_DENIED = "URL_REQUEST_DENIED";
610 623
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index 508f33b..840d3a4 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
@@ -649,6 +649,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
649 return m_LSL_Functions.llGetParcelMaxPrims(pos, sim_wide); 649 return m_LSL_Functions.llGetParcelMaxPrims(pos, sim_wide);
650 } 650 }
651 651
652 public LSL_String llGetParcelMusicURL()
653 {
654 return m_LSL_Functions.llGetParcelMusicURL();
655 }
656
652 public LSL_Integer llGetParcelPrimCount(LSL_Vector pos, int category, int sim_wide) 657 public LSL_Integer llGetParcelPrimCount(LSL_Vector pos, int category, int sim_wide)
653 { 658 {
654 return m_LSL_Functions.llGetParcelPrimCount(pos, category, sim_wide); 659 return m_LSL_Functions.llGetParcelPrimCount(pos, category, sim_wide);
@@ -1049,6 +1054,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1049 m_LSL_Functions.llLoopSoundSlave(sound, volume); 1054 m_LSL_Functions.llLoopSoundSlave(sound, volume);
1050 } 1055 }
1051 1056
1057 public LSL_Integer llManageEstateAccess(int action, string avatar)
1058 {
1059 return m_LSL_Functions.llManageEstateAccess(action, avatar);
1060 }
1061
1052 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) 1062 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset)
1053 { 1063 {
1054 m_LSL_Functions.llMakeExplosion(particles, scale, vel, lifetime, arc, texture, offset); 1064 m_LSL_Functions.llMakeExplosion(particles, scale, vel, lifetime, arc, texture, offset);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
index 0d7d5ea..cc8d417 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
@@ -452,6 +452,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
452 return m_OSSL_Functions.osGetGridLoginURI(); 452 return m_OSSL_Functions.osGetGridLoginURI();
453 } 453 }
454 454
455 public string osGetGridHomeURI()
456 {
457 return m_OSSL_Functions.osGetGridHomeURI();
458 }
459
460 public string osGetGridCustom(string key)
461 {
462 return m_OSSL_Functions.osGetGridCustom(key);
463 }
464
455 public LSL_String osFormatString(string str, LSL_List strings) 465 public LSL_String osFormatString(string str, LSL_List strings)
456 { 466 {
457 return m_OSSL_Functions.osFormatString(str, strings); 467 return m_OSSL_Functions.osFormatString(str, strings);
@@ -483,11 +493,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
483 return m_OSSL_Functions.osGetLinkPrimitiveParams(linknumber, rules); 493 return m_OSSL_Functions.osGetLinkPrimitiveParams(linknumber, rules);
484 } 494 }
485 495
496 public LSL_Integer osIsNpc(LSL_Key npc)
497 {
498 return m_OSSL_Functions.osIsNpc(npc);
499 }
500
486 public key osNpcCreate(string user, string name, vector position, key cloneFrom) 501 public key osNpcCreate(string user, string name, vector position, key cloneFrom)
487 { 502 {
488 return m_OSSL_Functions.osNpcCreate(user, name, position, cloneFrom); 503 return m_OSSL_Functions.osNpcCreate(user, name, position, cloneFrom);
489 } 504 }
490 505
506 public key osNpcCreate(string user, string name, vector position, key cloneFrom, int options)
507 {
508 return m_OSSL_Functions.osNpcCreate(user, name, position, cloneFrom, options);
509 }
510
491 public key osNpcSaveAppearance(key npc, string notecard) 511 public key osNpcSaveAppearance(key npc, string notecard)
492 { 512 {
493 return m_OSSL_Functions.osNpcSaveAppearance(npc, notecard); 513 return m_OSSL_Functions.osNpcSaveAppearance(npc, notecard);
@@ -498,6 +518,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
498 m_OSSL_Functions.osNpcLoadAppearance(npc, notecard); 518 m_OSSL_Functions.osNpcLoadAppearance(npc, notecard);
499 } 519 }
500 520
521 public LSL_Key osNpcGetOwner(LSL_Key npc)
522 {
523 return m_OSSL_Functions.osNpcGetOwner(npc);
524 }
525
501 public vector osNpcGetPos(LSL_Key npc) 526 public vector osNpcGetPos(LSL_Key npc)
502 { 527 {
503 return m_OSSL_Functions.osNpcGetPos(npc); 528 return m_OSSL_Functions.osNpcGetPos(npc);
@@ -548,6 +573,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
548 m_OSSL_Functions.osNpcRemove(npc); 573 m_OSSL_Functions.osNpcRemove(npc);
549 } 574 }
550 575
576 public void osNpcPlayAnimation(LSL_Key npc, string animation)
577 {
578 m_OSSL_Functions.osNpcPlayAnimation(npc, animation);
579 }
580
581 public void osNpcStopAnimation(LSL_Key npc, string animation)
582 {
583 m_OSSL_Functions.osNpcStopAnimation(npc, animation);
584 }
585
551 public LSL_Key osOwnerSaveAppearance(string notecard) 586 public LSL_Key osOwnerSaveAppearance(string notecard)
552 { 587 {
553 return m_OSSL_Functions.osOwnerSaveAppearance(notecard); 588 return m_OSSL_Functions.osOwnerSaveAppearance(notecard);
@@ -818,4 +853,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
818 return m_OSSL_Functions.osUnixTimeToTimestamp(time); 853 return m_OSSL_Functions.osUnixTimeToTimestamp(time);
819 } 854 }
820 } 855 }
821} \ No newline at end of file 856}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index f9d6eee..9b93135 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -55,7 +55,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
55{ 55{
56 public class ScriptInstance : MarshalByRefObject, IScriptInstance 56 public class ScriptInstance : MarshalByRefObject, IScriptInstance
57 { 57 {
58// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 58 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
59 59
60 private IScriptEngine m_Engine; 60 private IScriptEngine m_Engine;
61 private IScriptWorkItem m_CurrentResult = null; 61 private IScriptWorkItem m_CurrentResult = null;
@@ -109,7 +109,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
109 private Dictionary<string,IScriptApi> m_Apis = new Dictionary<string,IScriptApi>(); 109 private Dictionary<string,IScriptApi> m_Apis = new Dictionary<string,IScriptApi>();
110 110
111 // Script state 111 // Script state
112 private string m_State="default"; 112 private string m_State = "default";
113 113
114 public Object[] PluginData = new Object[0]; 114 public Object[] PluginData = new Object[0];
115 115
@@ -127,6 +127,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
127 m_minEventDelay = value; 127 m_minEventDelay = value;
128 else 128 else
129 m_minEventDelay = 0.0; 129 m_minEventDelay = 0.0;
130
130 m_eventDelayTicks = (long)(m_minEventDelay * 10000000L); 131 m_eventDelayTicks = (long)(m_minEventDelay * 10000000L);
131 m_nextEventTimeTicks = DateTime.Now.Ticks; 132 m_nextEventTimeTicks = DateTime.Now.Ticks;
132 } 133 }
@@ -296,9 +297,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
296 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); 297 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass);
297// lease.Register(this); 298// lease.Register(this);
298 } 299 }
299 catch (Exception) 300 catch (Exception e)
300 { 301 {
301 // m_log.ErrorFormat("[Script] Error loading assembly {0}\n"+e.ToString(), assembly); 302 m_log.ErrorFormat(
303 "[SCRIPT INSTANCE]: Error loading assembly {0}. Exception {1}{2}",
304 assembly, e.Message, e.StackTrace);
302 } 305 }
303 306
304 try 307 try
@@ -313,9 +316,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
313 part.SetScriptEvents(m_ItemID, 316 part.SetScriptEvents(m_ItemID,
314 (int)m_Script.GetStateEventFlags(State)); 317 (int)m_Script.GetStateEventFlags(State));
315 } 318 }
316 catch (Exception) 319 catch (Exception e)
317 { 320 {
318 // m_log.Error("[Script] Error loading script instance\n"+e.ToString()); 321 m_log.ErrorFormat(
322 "[SCRIPT INSTANCE]: Error loading script instance from assembly {0}. Exception {1}{2}",
323 assembly, e.Message, e.StackTrace);
324
319 return; 325 return;
320 } 326 }
321 327
@@ -377,12 +383,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
377 } 383 }
378 else 384 else
379 { 385 {
380 // m_log.Error("[Script] Unable to load script state: Memory limit exceeded"); 386 m_log.ErrorFormat(
387 "[SCRIPT INSTANCE]: Unable to load script state from assembly {0}: Memory limit exceeded",
388 assembly);
381 } 389 }
382 } 390 }
383 catch (Exception) 391 catch (Exception e)
384 { 392 {
385 // m_log.ErrorFormat("[Script] Unable to load script state from xml: {0}\n"+e.ToString(), xml); 393 m_log.ErrorFormat(
394 "[SCRIPT INSTANCE]: Unable to load script state from assembly {0}. XML is {1}. Exception {2}{3}",
395 assembly, xml, e.Message, e.StackTrace);
386 } 396 }
387 } 397 }
388// else 398// else
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs
index 0cbad41..3baa723 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs
@@ -75,32 +75,49 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
75 [Test] 75 [Test]
76 public void TestllAngleBetween() 76 public void TestllAngleBetween()
77 { 77 {
78 CheckllAngleBetween(new Vector3(1, 0, 0), 0); 78 CheckllAngleBetween(new Vector3(1, 0, 0), 0, 1, 1);
79 CheckllAngleBetween(new Vector3(1, 0, 0), 90); 79 CheckllAngleBetween(new Vector3(1, 0, 0), 90, 1, 1);
80 CheckllAngleBetween(new Vector3(1, 0, 0), 180); 80 CheckllAngleBetween(new Vector3(1, 0, 0), 180, 1, 1);
81 81
82 CheckllAngleBetween(new Vector3(0, 1, 0), 0); 82 CheckllAngleBetween(new Vector3(0, 1, 0), 0, 1, 1);
83 CheckllAngleBetween(new Vector3(0, 1, 0), 90); 83 CheckllAngleBetween(new Vector3(0, 1, 0), 90, 1, 1);
84 CheckllAngleBetween(new Vector3(0, 1, 0), 180); 84 CheckllAngleBetween(new Vector3(0, 1, 0), 180, 1, 1);
85 85
86 CheckllAngleBetween(new Vector3(0, 0, 1), 0); 86 CheckllAngleBetween(new Vector3(0, 0, 1), 0, 1, 1);
87 CheckllAngleBetween(new Vector3(0, 0, 1), 90); 87 CheckllAngleBetween(new Vector3(0, 0, 1), 90, 1, 1);
88 CheckllAngleBetween(new Vector3(0, 0, 1), 180); 88 CheckllAngleBetween(new Vector3(0, 0, 1), 180, 1, 1);
89 89
90 CheckllAngleBetween(new Vector3(1, 1, 1), 0); 90 CheckllAngleBetween(new Vector3(1, 1, 1), 0, 1, 1);
91 CheckllAngleBetween(new Vector3(1, 1, 1), 90); 91 CheckllAngleBetween(new Vector3(1, 1, 1), 90, 1, 1);
92 CheckllAngleBetween(new Vector3(1, 1, 1), 180); 92 CheckllAngleBetween(new Vector3(1, 1, 1), 180, 1, 1);
93
94 CheckllAngleBetween(new Vector3(1, 0, 0), 0, 1.6f, 1.8f);
95 CheckllAngleBetween(new Vector3(1, 0, 0), 90, 0.3f, 3.9f);
96 CheckllAngleBetween(new Vector3(1, 0, 0), 180, 8.8f, 7.4f);
97
98 CheckllAngleBetween(new Vector3(0, 1, 0), 0, 9.8f, -9.4f);
99 CheckllAngleBetween(new Vector3(0, 1, 0), 90, 8.4f, -8.2f);
100 CheckllAngleBetween(new Vector3(0, 1, 0), 180, 0.4f, -5.8f);
101
102 CheckllAngleBetween(new Vector3(0, 0, 1), 0, -6.8f, 3.4f);
103 CheckllAngleBetween(new Vector3(0, 0, 1), 90, -3.6f, 5.6f);
104 CheckllAngleBetween(new Vector3(0, 0, 1), 180, -3.8f, 1.1f);
105
106 CheckllAngleBetween(new Vector3(1, 1, 1), 0, -7.7f, -2.0f);
107 CheckllAngleBetween(new Vector3(1, 1, 1), 90, -3.0f, -9.1f);
108 CheckllAngleBetween(new Vector3(1, 1, 1), 180, -7.9f, -8.0f);
93 } 109 }
94 110
95 private void CheckllAngleBetween(Vector3 axis,float originalAngle) 111 private void CheckllAngleBetween(Vector3 axis,float originalAngle, float denorm1, float denorm2)
96 { 112 {
97 Quaternion rotation1 = Quaternion.CreateFromAxisAngle(axis, 0); 113 Quaternion rotation1 = Quaternion.CreateFromAxisAngle(axis, 0);
98 Quaternion rotation2 = Quaternion.CreateFromAxisAngle(axis, ToRadians(originalAngle)); 114 Quaternion rotation2 = Quaternion.CreateFromAxisAngle(axis, ToRadians(originalAngle));
115 rotation1 *= denorm1;
116 rotation2 *= denorm2;
99 117
100 double deducedAngle = FromLslFloat(m_lslApi.llAngleBetween(ToLslQuaternion(rotation2), ToLslQuaternion(rotation1))); 118 double deducedAngle = FromLslFloat(m_lslApi.llAngleBetween(ToLslQuaternion(rotation2), ToLslQuaternion(rotation1)));
101 119
102 Assert.Greater(deducedAngle, ToRadians(originalAngle) - ANGLE_ACCURACY_IN_RADIANS); 120 Assert.That(deducedAngle, Is.EqualTo(ToRadians(originalAngle)).Within(ANGLE_ACCURACY_IN_RADIANS), "TestllAngleBetween check fail");
103 Assert.Less(deducedAngle, ToRadians(originalAngle) + ANGLE_ACCURACY_IN_RADIANS);
104 } 121 }
105 122
106 #region Conversions to and from LSL_Types 123 #region Conversions to and from LSL_Types
@@ -142,30 +159,97 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
142 public void TestllRot2Euler() 159 public void TestllRot2Euler()
143 { 160 {
144 // 180, 90 and zero degree rotations. 161 // 180, 90 and zero degree rotations.
145 CheckllRot2Euler(new LSL_Types.Quaternion(1.0f, 0.0f, 0.0f, 0.0f), new LSL_Types.Vector3(Math.PI, 0.0f, 0.0f)); 162 CheckllRot2Euler(new LSL_Types.Quaternion(0.0f, 0.0f, 0.0f, 1.0f));
146 CheckllRot2Euler(new LSL_Types.Quaternion(0.0f, 1.0f, 0.0f, 0.0f), new LSL_Types.Vector3(Math.PI, 0.0f, Math.PI)); 163 CheckllRot2Euler(new LSL_Types.Quaternion(0.0f, 0.0f, 0.707107f, 0.707107f));
147 CheckllRot2Euler(new LSL_Types.Quaternion(0.0f, 0.0f, 1.0f, 0.0f), new LSL_Types.Vector3(0.0f, 0.0f, Math.PI)); 164 CheckllRot2Euler(new LSL_Types.Quaternion(0.0f, 0.0f, 1.0f, 0.0f));
148 CheckllRot2Euler(new LSL_Types.Quaternion(0.0f, 0.0f, 0.0f, 1.0f), new LSL_Types.Vector3(0.0f, 0.0f, 0.0f)); 165 CheckllRot2Euler(new LSL_Types.Quaternion(0.0f, 0.0f, 0.707107f, -0.707107f));
149 CheckllRot2Euler(new LSL_Types.Quaternion(-0.5f, -0.5f, 0.5f, 0.5f), new LSL_Types.Vector3(0, -Math.PI / 2.0f, Math.PI / 2.0f)); 166 CheckllRot2Euler(new LSL_Types.Quaternion(0.707107f, 0.0f, 0.0f, 0.707107f));
150 CheckllRot2Euler(new LSL_Types.Quaternion(-0.707107f, 0.0f, 0.0f, -0.707107f), new LSL_Types.Vector3(Math.PI / 2.0f, 0.0f, 0.0f)); 167 CheckllRot2Euler(new LSL_Types.Quaternion(0.5f, -0.5f, 0.5f, 0.5f));
168 CheckllRot2Euler(new LSL_Types.Quaternion(0.0f, -0.707107f, 0.707107f, 0.0f));
169 CheckllRot2Euler(new LSL_Types.Quaternion(-0.5f, -0.5f, 0.5f, -0.5f));
170 CheckllRot2Euler(new LSL_Types.Quaternion(1.0f, 0.0f, 0.0f, 0.0f));
171 CheckllRot2Euler(new LSL_Types.Quaternion(0.707107f, -0.707107f, 0.0f, 0.0f));
172 CheckllRot2Euler(new LSL_Types.Quaternion(0.0f, -1.0f, 0.0f, 0.0f));
173 CheckllRot2Euler(new LSL_Types.Quaternion(-0.707107f, -0.707107f, 0.0f, 0.0f));
174 CheckllRot2Euler(new LSL_Types.Quaternion(0.707107f, 0.0f, 0.0f, -0.707107f));
175 CheckllRot2Euler(new LSL_Types.Quaternion(0.5f, -0.5f, -0.5f, -0.5f));
176 CheckllRot2Euler(new LSL_Types.Quaternion(0.0f, -0.707107f, -0.707107f, 0.0f));
177 CheckllRot2Euler(new LSL_Types.Quaternion(-0.5f, -0.5f, -0.5f, 0.5f));
178 CheckllRot2Euler(new LSL_Types.Quaternion(0.0f, -0.707107f, 0.0f, 0.707107f));
179 CheckllRot2Euler(new LSL_Types.Quaternion(-0.5f, -0.5f, 0.5f, 0.5f));
180 CheckllRot2Euler(new LSL_Types.Quaternion(-0.707107f, 0.0f, 0.707107f, 0.0f));
181 CheckllRot2Euler(new LSL_Types.Quaternion(-0.5f, 0.5f, 0.5f, -0.5f));
182 CheckllRot2Euler(new LSL_Types.Quaternion(0.0f, -0.707107f, 0.0f, -0.707107f));
183 CheckllRot2Euler(new LSL_Types.Quaternion(-0.5f, -0.5f, -0.5f, -0.5f));
184 CheckllRot2Euler(new LSL_Types.Quaternion(-0.707107f, 0.0f, -0.707107f, 0.0f));
185 CheckllRot2Euler(new LSL_Types.Quaternion(-0.5f, 0.5f, -0.5f, 0.5f));
186
151 // A couple of messy rotations. 187 // A couple of messy rotations.
152 CheckllRot2Euler(new LSL_Types.Quaternion(1.0f, 5.651f, -3.1f, 67.023f), new LSL_Types.Vector3(0.037818f, 0.166447f, -0.095595f)); 188 CheckllRot2Euler(new LSL_Types.Quaternion(1.0f, 5.651f, -3.1f, 67.023f));
153 CheckllRot2Euler(new LSL_Types.Quaternion(0.719188f, -0.408934f, -0.363998f, -0.427841f), new LSL_Types.Vector3(-1.954769f, -0.174533f, 1.151917f)); 189 CheckllRot2Euler(new LSL_Types.Quaternion(0.719188f, -0.408934f, -0.363998f, -0.427841f));
190
191 // Some deliberately malicious rotations (intended on provoking singularity errors)
192 // The "f" suffexes are deliberately omitted.
193 CheckllRot2Euler(new LSL_Types.Quaternion(0.50001f, 0.50001f, 0.50001f, 0.50001f));
194 // More malice. The "f" suffixes are deliberately omitted.
195 CheckllRot2Euler(new LSL_Types.Quaternion(-0.701055, 0.092296, 0.701055, -0.092296));
196 CheckllRot2Euler(new LSL_Types.Quaternion(-0.183005, -0.683010, 0.183005, 0.683010));
197 CheckllRot2Euler(new LSL_Types.Quaternion(-0.430460, -0.560982, 0.430460, 0.560982));
198 CheckllRot2Euler(new LSL_Types.Quaternion(-0.701066, 0.092301, -0.701066, 0.092301));
199 CheckllRot2Euler(new LSL_Types.Quaternion(-0.183013, -0.683010, 0.183013, 0.683010));
200 CheckllRot2Euler(new LSL_Types.Quaternion(-0.183005, -0.683014, -0.183005, -0.683014));
201 CheckllRot2Euler(new LSL_Types.Quaternion(-0.353556, 0.612375, 0.353556, -0.612375));
202 CheckllRot2Euler(new LSL_Types.Quaternion(0.353554, -0.612385, -0.353554, 0.612385));
203 CheckllRot2Euler(new LSL_Types.Quaternion(-0.560989, 0.430450, 0.560989, -0.430450));
204 CheckllRot2Euler(new LSL_Types.Quaternion(-0.183013, 0.683009, -0.183013, 0.683009));
205 CheckllRot2Euler(new LSL_Types.Quaternion(0.430457, -0.560985, -0.430457, 0.560985));
206 CheckllRot2Euler(new LSL_Types.Quaternion(0.353552, 0.612360, -0.353552, -0.612360));
207 CheckllRot2Euler(new LSL_Types.Quaternion(-0.499991, 0.500003, 0.499991, -0.500003));
208 CheckllRot2Euler(new LSL_Types.Quaternion(-0.353555, -0.612385, -0.353555, -0.612385));
209 CheckllRot2Euler(new LSL_Types.Quaternion(0.701066, -0.092301, -0.701066, 0.092301));
210 CheckllRot2Euler(new LSL_Types.Quaternion(-0.499991, 0.500007, 0.499991, -0.500007));
211 CheckllRot2Euler(new LSL_Types.Quaternion(-0.683002, 0.183016, -0.683002, 0.183016));
212 CheckllRot2Euler(new LSL_Types.Quaternion(0.430458, 0.560982, 0.430458, 0.560982));
213 CheckllRot2Euler(new LSL_Types.Quaternion(0.499991, -0.500003, -0.499991, 0.500003));
214 CheckllRot2Euler(new LSL_Types.Quaternion(-0.183009, 0.683011, -0.183009, 0.683011));
215 CheckllRot2Euler(new LSL_Types.Quaternion(0.560975, -0.430457, 0.560975, -0.430457));
216 CheckllRot2Euler(new LSL_Types.Quaternion(0.701055, 0.092300, 0.701055, 0.092300));
217 CheckllRot2Euler(new LSL_Types.Quaternion(-0.560990, 0.430459, -0.560990, 0.430459));
218 CheckllRot2Euler(new LSL_Types.Quaternion(-0.092302, -0.701059, -0.092302, -0.701059));
154 } 219 }
155 220
156 private void CheckllRot2Euler(LSL_Types.Quaternion rot, LSL_Types.Vector3 eulerCheck) 221 /// <summary>
222 /// Check an llRot2Euler conversion.
223 /// </summary>
224 /// <remarks>
225 /// Testing Rot2Euler this way instead of comparing against expected angles because
226 /// 1. There are several ways to get to the original Quaternion. For example a rotation
227 /// of PI and -PI will give the same result. But PI and -PI aren't equal.
228 /// 2. This method checks to see if the calculated angles from a quaternion can be used
229 /// to create a new quaternion to produce the same rotation.
230 /// However, can't compare the newly calculated quaternion against the original because
231 /// once again, there are multiple quaternions that give the same result. For instance
232 /// <X, Y, Z, S> == <-X, -Y, -Z, -S>. Additionally, the magnitude of S can be changed
233 /// and will still result in the same rotation if the values for X, Y, Z are also changed
234 /// to compensate.
235 /// However, if two quaternions represent the same rotation, then multiplying the first
236 /// quaternion by the conjugate of the second, will give a third quaternion representing
237 /// a zero rotation. This can be tested for by looking at the X, Y, Z values which should
238 /// be zero.
239 /// </remarks>
240 /// <param name="rot"></param>
241 private void CheckllRot2Euler(LSL_Types.Quaternion rot)
157 { 242 {
158 // Call LSL function to convert quaternion rotaion to euler radians. 243 // Call LSL function to convert quaternion rotaion to euler radians.
159 LSL_Types.Vector3 eulerCalc = m_lslApi.llRot2Euler(rot); 244 LSL_Types.Vector3 eulerCalc = m_lslApi.llRot2Euler(rot);
160 // Check upper and lower bounds of x, y and z. 245 // Now use the euler radians to recalculate a new quaternion rotation
161 // This type of check is performed as opposed to comparing for equal numbers, in order to allow slight 246 LSL_Types.Quaternion newRot = m_lslApi.llEuler2Rot(eulerCalc);
162 // differences in accuracy. 247 // Multiple original quaternion by conjugate of quaternion calculated with angles.
163 Assert.Greater(eulerCalc.x, eulerCheck.x - ANGLE_ACCURACY_IN_RADIANS, "TestllRot2Euler X lower bounds check fail"); 248 LSL_Types.Quaternion check = rot * new LSL_Types.Quaternion(-newRot.x, -newRot.y, -newRot.z, newRot.s);
164 Assert.Less(eulerCalc.x, eulerCheck.x + ANGLE_ACCURACY_IN_RADIANS, "TestllRot2Euler X upper bounds check fail"); 249
165 Assert.Greater(eulerCalc.y, eulerCheck.y - ANGLE_ACCURACY_IN_RADIANS, "TestllRot2Euler Y lower bounds check fail"); 250 Assert.AreEqual(0.0, check.x, VECTOR_COMPONENT_ACCURACY, "TestllRot2Euler X bounds check fail");
166 Assert.Less(eulerCalc.y, eulerCheck.y + ANGLE_ACCURACY_IN_RADIANS, "TestllRot2Euler Y upper bounds check fail"); 251 Assert.AreEqual(0.0, check.y, VECTOR_COMPONENT_ACCURACY, "TestllRot2Euler Y bounds check fail");
167 Assert.Greater(eulerCalc.z, eulerCheck.z - ANGLE_ACCURACY_IN_RADIANS, "TestllRot2Euler Z lower bounds check fail"); 252 Assert.AreEqual(0.0, check.z, VECTOR_COMPONENT_ACCURACY, "TestllRot2Euler Z bounds check fail");
168 Assert.Less(eulerCalc.z, eulerCheck.z + ANGLE_ACCURACY_IN_RADIANS, "TestllRot2Euler Z upper bounds check fail");
169 } 253 }
170 254
171 [Test] 255 [Test]
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs
new file mode 100644
index 0000000..9d9fc51
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs
@@ -0,0 +1,170 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using System.Text;
32using log4net;
33using Nini.Config;
34using NUnit.Framework;
35using OpenMetaverse;
36using OpenMetaverse.Assets;
37using OpenMetaverse.StructuredData;
38using OpenSim.Framework;
39using OpenSim.Region.CoreModules.Avatar.AvatarFactory;
40using OpenSim.Region.OptionalModules.World.NPC;
41using OpenSim.Region.Framework.Scenes;
42using OpenSim.Region.ScriptEngine.Shared;
43using OpenSim.Region.ScriptEngine.Shared.Api;
44using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
45using OpenSim.Services.Interfaces;
46using OpenSim.Tests.Common;
47using OpenSim.Tests.Common.Mock;
48
49namespace OpenSim.Region.ScriptEngine.Shared.Tests
50{
51 /// <summary>
52 /// Tests for OSSL NPC API
53 /// </summary>
54 [TestFixture]
55 public class OSSL_NpcApiAppearanceTest
56 {
57 protected Scene m_scene;
58 protected XEngine.XEngine m_engine;
59
60 [SetUp]
61 public void SetUp()
62 {
63 IConfigSource initConfigSource = new IniConfigSource();
64 IConfig config = initConfigSource.AddConfig("XEngine");
65 config.Set("Enabled", "true");
66 config.Set("AllowOSFunctions", "true");
67 config.Set("OSFunctionThreatLevel", "Severe");
68 config = initConfigSource.AddConfig("NPC");
69 config.Set("Enabled", "true");
70
71 m_scene = SceneHelpers.SetupScene();
72 SceneHelpers.SetupSceneModules(m_scene, initConfigSource, new AvatarFactoryModule(), new NPCModule());
73
74 m_engine = new XEngine.XEngine();
75 m_engine.Initialise(initConfigSource);
76 m_engine.AddRegion(m_scene);
77 }
78
79 /// <summary>
80 /// Test removal of an owned NPC.
81 /// </summary>
82 [Test]
83 public void TestOsNpcRemoveOwned()
84 {
85 TestHelpers.InMethod();
86// log4net.Config.XmlConfigurator.Configure();
87
88 // Store an avatar with a different height from default in a notecard.
89 UUID userId = TestHelpers.ParseTail(0x1);
90 UUID otherUserId = TestHelpers.ParseTail(0x2);
91 float newHeight = 1.9f;
92
93 SceneHelpers.AddScenePresence(m_scene, otherUserId);
94
95 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
96 sp.Appearance.AvatarHeight = newHeight;
97
98 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId);
99 SceneObjectPart part = so.RootPart;
100 m_scene.AddSceneObject(so);
101
102 SceneObjectGroup otherSo = SceneHelpers.CreateSceneObject(1, otherUserId);
103 SceneObjectPart otherPart = otherSo.RootPart;
104 m_scene.AddSceneObject(otherSo);
105
106 OSSL_Api osslApi = new OSSL_Api();
107 osslApi.Initialize(m_engine, part, part.LocalId, part.UUID);
108
109 OSSL_Api otherOsslApi = new OSSL_Api();
110 otherOsslApi.Initialize(m_engine, otherPart, otherPart.LocalId, otherPart.UUID);
111
112 string notecardName = "appearanceNc";
113 osslApi.osOwnerSaveAppearance(notecardName);
114
115 string npcRaw
116 = osslApi.osNpcCreate(
117 "Jane", "Doe", new LSL_Types.Vector3(128, 128, 128), notecardName, ScriptBaseClass.OS_NPC_CREATOR_OWNED);
118
119 otherOsslApi.osNpcRemove(npcRaw);
120
121 // Should still be around
122 UUID npcId = new UUID(npcRaw);
123 ScenePresence npc = m_scene.GetScenePresence(npcId);
124 Assert.That(npc, Is.Not.Null);
125
126 osslApi.osNpcRemove(npcRaw);
127
128 npc = m_scene.GetScenePresence(npcId);
129
130 // Now the owner deleted it and it's gone
131 Assert.That(npc, Is.Null);
132 }
133
134 /// <summary>
135 /// Test removal of an unowned NPC.
136 /// </summary>
137 [Test]
138 public void TestOsNpcRemoveUnowned()
139 {
140 TestHelpers.InMethod();
141// log4net.Config.XmlConfigurator.Configure();
142
143 // Store an avatar with a different height from default in a notecard.
144 UUID userId = TestHelpers.ParseTail(0x1);
145 float newHeight = 1.9f;
146
147 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
148 sp.Appearance.AvatarHeight = newHeight;
149 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId);
150 SceneObjectPart part = so.RootPart;
151 m_scene.AddSceneObject(so);
152
153 OSSL_Api osslApi = new OSSL_Api();
154 osslApi.Initialize(m_engine, part, part.LocalId, part.UUID);
155
156 string notecardName = "appearanceNc";
157 osslApi.osOwnerSaveAppearance(notecardName);
158
159 string npcRaw
160 = osslApi.osNpcCreate(
161 "Jane", "Doe", new LSL_Types.Vector3(128, 128, 128), notecardName, ScriptBaseClass.OS_NPC_NOT_OWNED);
162
163 osslApi.osNpcRemove(npcRaw);
164
165 UUID npcId = new UUID(npcRaw);
166 ScenePresence npc = m_scene.GetScenePresence(npcId);
167 Assert.That(npc, Is.Null);
168 }
169 }
170} \ No newline at end of file
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 12e1a78..f11987e 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -26,14 +26,15 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.IO;
30using System.Threading;
31using System.Collections; 29using System.Collections;
32using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Globalization;
32using System.IO;
33using System.Reflection;
33using System.Security; 34using System.Security;
34using System.Security.Policy; 35using System.Security.Policy;
35using System.Reflection; 36using System.Text;
36using System.Globalization; 37using System.Threading;
37using System.Xml; 38using System.Xml;
38using OpenMetaverse; 39using OpenMetaverse;
39using OpenMetaverse.StructuredData; 40using OpenMetaverse.StructuredData;
@@ -273,11 +274,18 @@ namespace OpenSim.Region.ScriptEngine.XEngine
273 } 274 }
274 275
275 MainConsole.Instance.Commands.AddCommand( 276 MainConsole.Instance.Commands.AddCommand(
276 "scripts", false, "scripts show", "scripts show", "Show script information", 277 "scripts", false, "xengine status", "xengine status", "Show status information",
277 "Show information on all scripts known to the script engine", HandleShowScripts); 278 "Show status information on the script engine.",
279 HandleShowStatus);
280
281 MainConsole.Instance.Commands.AddCommand(
282 "scripts", false, "scripts show", "scripts show [<script-item-uuid>]", "Show script information",
283 "Show information on all scripts known to the script engine."
284 + "If a <script-item-uuid> is given then only information on that script will be shown.",
285 HandleShowScripts);
278 286
279 MainConsole.Instance.Commands.AddCommand( 287 MainConsole.Instance.Commands.AddCommand(
280 "scripts", false, "show scripts", "show scripts", "Show script information", 288 "scripts", false, "show scripts", "show scripts [<script-item-uuid>]", "Show script information",
281 "Synonym for scripts show command", HandleShowScripts); 289 "Synonym for scripts show command", HandleShowScripts);
282 290
283 MainConsole.Instance.Commands.AddCommand( 291 MainConsole.Instance.Commands.AddCommand(
@@ -308,43 +316,6 @@ namespace OpenSim.Region.ScriptEngine.XEngine
308 (module, cmdparams) => HandleScriptsAction(cmdparams, HandleStartScript)); 316 (module, cmdparams) => HandleScriptsAction(cmdparams, HandleStartScript));
309 } 317 }
310 318
311 public void HandleShowScripts(string module, string[] cmdparams)
312 {
313 lock (m_Scripts)
314 {
315 MainConsole.Instance.OutputFormat(
316 "Showing {0} scripts in {1}", m_Scripts.Count, m_Scene.RegionInfo.RegionName);
317
318 foreach (IScriptInstance instance in m_Scripts.Values)
319 {
320 SceneObjectPart sop = m_Scene.GetSceneObjectPart(instance.ObjectID);
321 string status;
322
323 if (instance.ShuttingDown)
324 {
325 status = "shutting down";
326 }
327 else if (instance.Suspended)
328 {
329 status = "suspended";
330 }
331 else if (!instance.Running)
332 {
333 status = "stopped";
334 }
335 else
336 {
337 status = "running";
338 }
339
340 MainConsole.Instance.OutputFormat(
341 "{0}.{1}, item UUID {2}, prim UUID {3} @ {4} ({5})",
342 instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID,
343 sop.AbsolutePosition, status);
344 }
345 }
346 }
347
348 /// <summary> 319 /// <summary>
349 /// Parse the raw item id into a script instance from the command params if it's present. 320 /// Parse the raw item id into a script instance from the command params if it's present.
350 /// </summary> 321 /// </summary>
@@ -353,6 +324,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
353 /// <returns>true if we're okay to proceed, false if not.</returns> 324 /// <returns>true if we're okay to proceed, false if not.</returns>
354 private void HandleScriptsAction(string[] cmdparams, Action<IScriptInstance> action) 325 private void HandleScriptsAction(string[] cmdparams, Action<IScriptInstance> action)
355 { 326 {
327 if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_Scene))
328 return;
329
356 lock (m_Scripts) 330 lock (m_Scripts)
357 { 331 {
358 string rawItemId; 332 string rawItemId;
@@ -394,6 +368,83 @@ namespace OpenSim.Region.ScriptEngine.XEngine
394 } 368 }
395 } 369 }
396 370
371 private void HandleShowStatus(string module, string[] cmdparams)
372 {
373 if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_Scene))
374 return;
375
376 StringBuilder sb = new StringBuilder();
377 sb.AppendFormat("Status of XEngine instance for {0}\n", m_Scene.RegionInfo.RegionName);
378
379 lock (m_Scripts)
380 sb.AppendFormat("Scripts loaded : {0}\n", m_Scripts.Count);
381
382 sb.AppendFormat("Unique scripts : {0}\n", m_uniqueScripts.Count);
383 sb.AppendFormat("Scripts waiting for load : {0}\n", m_CompileQueue.Count);
384 sb.AppendFormat("Allocated threads : {0}\n", m_ThreadPool.ActiveThreads);
385 sb.AppendFormat("In use threads : {0}\n", m_ThreadPool.InUseThreads);
386 sb.AppendFormat("Work items waiting : {0}\n", m_ThreadPool.WaitingCallbacks);
387// sb.AppendFormat("Assemblies loaded : {0}\n", m_Assemblies.Count);
388
389 MainConsole.Instance.OutputFormat(sb.ToString());
390 }
391
392 public void HandleShowScripts(string module, string[] cmdparams)
393 {
394 if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_Scene))
395 return;
396
397 if (cmdparams.Length == 2)
398 {
399 lock (m_Scripts)
400 {
401 MainConsole.Instance.OutputFormat(
402 "Showing {0} scripts in {1}", m_Scripts.Count, m_Scene.RegionInfo.RegionName);
403 }
404 }
405
406 HandleScriptsAction(cmdparams, HandleShowScript);
407 }
408
409 private void HandleShowScript(IScriptInstance instance)
410 {
411 SceneObjectPart sop = m_Scene.GetSceneObjectPart(instance.ObjectID);
412 string status;
413
414 if (instance.ShuttingDown)
415 {
416 status = "shutting down";
417 }
418 else if (instance.Suspended)
419 {
420 status = "suspended";
421 }
422 else if (!instance.Running)
423 {
424 status = "stopped";
425 }
426 else
427 {
428 status = "running";
429 }
430
431 StringBuilder sb = new StringBuilder();
432 Queue eq = instance.EventQueue;
433
434 sb.AppendFormat("Script name : {0}\n", instance.ScriptName);
435 sb.AppendFormat("Status : {0}\n", status);
436
437 lock (eq)
438 sb.AppendFormat("Queued events : {0}\n", eq.Count);
439
440 sb.AppendFormat("Item UUID : {0}\n", instance.ItemID);
441 sb.AppendFormat("Containing part name: {0}\n", instance.PrimName);
442 sb.AppendFormat("Containing part UUID: {0}\n", instance.ObjectID);
443 sb.AppendFormat("Position : {0}\n", sop.AbsolutePosition);
444
445 MainConsole.Instance.OutputFormat(sb.ToString());
446 }
447
397 private void HandleSuspendScript(IScriptInstance instance) 448 private void HandleSuspendScript(IScriptInstance instance)
398 { 449 {
399 if (!instance.Suspended) 450 if (!instance.Suspended)
diff --git a/OpenSim/Region/UserStatistics/WebStatsModule.cs b/OpenSim/Region/UserStatistics/WebStatsModule.cs
index fca9fd0..24a9418 100644
--- a/OpenSim/Region/UserStatistics/WebStatsModule.cs
+++ b/OpenSim/Region/UserStatistics/WebStatsModule.cs
@@ -442,7 +442,7 @@ namespace OpenSim.Region.UserStatistics
442 public string ViewerStatsReport(string request, string path, string param, 442 public string ViewerStatsReport(string request, string path, string param,
443 UUID agentID, Caps caps) 443 UUID agentID, Caps caps)
444 { 444 {
445 //m_log.Debug(request); 445// m_log.DebugFormat("[WEB STATS MODULE]: Received viewer starts report from {0}", agentID);
446 446
447 UpdateUserStats(ParseViewerStats(request,agentID), dbConn); 447 UpdateUserStats(ParseViewerStats(request,agentID), dbConn);
448 448
@@ -655,13 +655,13 @@ namespace OpenSim.Region.UserStatistics
655 updatecmd.Parameters.Add(new SqliteParameter(":session_key", uid.session_data.session_id.ToString())); 655 updatecmd.Parameters.Add(new SqliteParameter(":session_key", uid.session_data.session_id.ToString()));
656 updatecmd.Parameters.Add(new SqliteParameter(":agent_key", uid.session_data.agent_id.ToString())); 656 updatecmd.Parameters.Add(new SqliteParameter(":agent_key", uid.session_data.agent_id.ToString()));
657 updatecmd.Parameters.Add(new SqliteParameter(":region_key", uid.session_data.region_id.ToString())); 657 updatecmd.Parameters.Add(new SqliteParameter(":region_key", uid.session_data.region_id.ToString()));
658 m_log.Debug("UPDATE"); 658// m_log.Debug("UPDATE");
659 659
660 int result = updatecmd.ExecuteNonQuery(); 660 int result = updatecmd.ExecuteNonQuery();
661 661
662 if (result == 0) 662 if (result == 0)
663 { 663 {
664 m_log.Debug("INSERT"); 664// m_log.Debug("INSERT");
665 updatecmd.CommandText = SQL_STATS_TABLE_INSERT; 665 updatecmd.CommandText = SQL_STATS_TABLE_INSERT;
666 try 666 try
667 { 667 {