aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--.gitignore6
-rw-r--r--.nant/local.include19
-rw-r--r--BUILDING.md (renamed from BUILDING.txt)23
-rw-r--r--CONTRIBUTORS.txt1
-rw-r--r--OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs7
-rw-r--r--OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs18
-rw-r--r--OpenSim/Data/IXInventoryData.cs10
-rw-r--r--OpenSim/Data/MySQL/MySQLSimulationData.cs457
-rw-r--r--OpenSim/Framework/Cache.cs83
-rw-r--r--OpenSim/Framework/Constants.cs1
-rw-r--r--OpenSim/Framework/IClientAPI.cs15
-rw-r--r--OpenSim/Framework/InventoryFolderBase.cs18
-rw-r--r--OpenSim/Framework/Monitoring/Watchdog.cs15
-rw-r--r--OpenSim/Framework/RegionInfo.cs68
-rw-r--r--OpenSim/Framework/Serialization/ArchiveConstants.cs5
-rw-r--r--OpenSim/Framework/Serialization/External/OspResolver.cs14
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs68
-rw-r--r--OpenSim/Framework/Servers/MainServer.cs55
-rw-r--r--OpenSim/Framework/Servers/VersionInfo.cs2
-rw-r--r--OpenSim/Framework/Util.cs38
-rw-r--r--OpenSim/Region/Application/OpenSim.cs59
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs2
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs15
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs2
-rw-r--r--OpenSim/Region/ClientStack/RegionApplicationBase.cs2
-rw-r--r--OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs39
-rw-r--r--OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs1
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs6
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs64
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs21
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs156
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTexture.cs61
-rw-r--r--OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs277
-rw-r--r--OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs17
-rw-r--r--OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs49
-rw-r--r--OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs281
-rw-r--r--OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs142
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs7
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/Tests/AssetConnectorTests.cs136
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs2
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs6
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs434
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveScenesGroup.cs176
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs634
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestExecution.cs153
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs438
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs5
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs6
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/DearchiveScenesGroup.cs232
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs399
-rw-r--r--OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/World/Sound/SoundModule.cs8
-rw-r--r--OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs61
-rw-r--r--OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs7
-rw-r--r--OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs69
-rw-r--r--OpenSim/Region/Framework/Interfaces/IEstateModule.cs4
-rw-r--r--OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs2
-rw-r--r--OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs29
-rw-r--r--OpenSim/Region/Framework/Interfaces/IUrlModule.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/EventManager.cs137
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs5
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs86
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs11
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneManager.cs6
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs79
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs109
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs32
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs36
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs4
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs2
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs2
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs14
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs2
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs2
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs50
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs6
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs166
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs19
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs434
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs150
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs64
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs450
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs621
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs480
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs592
-rw-r--r--OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs3
-rw-r--r--OpenSim/Region/RegionCombinerModule/Resources/RegionCombinerModule.addin.xml14
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs1329
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs8
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs24
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs254
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs13
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs4
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs91
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs53
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs26
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Helpers.cs28
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs77
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/EventManager.cs24
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs57
-rw-r--r--OpenSim/Server/Base/ServicesServerBase.cs41
-rw-r--r--OpenSim/Server/Handlers/Avatar/AvatarServerPostHandler.cs18
-rw-r--r--OpenSim/Services/AssetService/AssetServiceBase.cs4
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs4
-rw-r--r--OpenSim/Services/GridService/GridService.cs53
-rw-r--r--OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs61
-rw-r--r--OpenSim/Services/InventoryService/XInventoryService.cs65
-rw-r--r--OpenSim/Tests/Common/Helpers/SceneHelpers.cs2
-rw-r--r--OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs4
-rw-r--r--OpenSim/Tests/Common/Mock/TestClient.cs6
-rw-r--r--OpenSim/Tests/Common/Mock/TestXInventoryDataPlugin.cs131
-rw-r--r--OpenSim/Tests/Common/TestHelpers.cs1
-rw-r--r--OpenSim/Tests/Performance/NPCPerformanceTests.cs (renamed from OpenSim/Tests/Torture/NPCTortureTests.cs)6
-rw-r--r--OpenSim/Tests/Performance/ObjectPerformanceTests.cs (renamed from OpenSim/Tests/Torture/ObjectTortureTests.cs)6
-rw-r--r--OpenSim/Tests/Performance/ScriptPerformanceTests.cs (renamed from OpenSim/Tests/Torture/ScriptTortureTests.cs)6
-rw-r--r--OpenSim/Tests/Stress/VectorRenderModuleStressTests.cs132
-rw-r--r--README.md (renamed from README.txt)42
-rw-r--r--ThirdPartyLicenses/Newtonsoft-JsonDotNet.txt23
-rwxr-xr-xbin/Newtonsoft.Json.Net20.dllbin356352 -> 0 bytes
-rw-r--r--bin/Newtonsoft.Json.XML5827
-rw-r--r--bin/Newtonsoft.Json.pdbbin742912 -> 0 bytes
-rw-r--r--bin/OpenSim.ini.example17
-rw-r--r--bin/OpenSimDefaults.ini25
-rw-r--r--bin/Robust.HG.ini.example6
-rw-r--r--bin/config-include/FlotsamCache.ini.example7
-rw-r--r--bin/config-include/StandaloneHypergrid.ini7
-rw-r--r--bin/config-include/storage/SQLiteStandalone.ini10
-rwxr-xr-xbin/lib32/BulletSim.dllbin550400 -> 569856 bytes
-rwxr-xr-xbin/lib32/libBulletSim.sobin2387345 -> 2510105 bytes
-rwxr-xr-xbin/lib64/BulletSim.dllbin706048 -> 731136 bytes
-rwxr-xr-xbin/lib64/libBulletSim.sobin2599320 -> 2750288 bytes
-rw-r--r--prebuild.xml45
137 files changed, 7922 insertions, 9130 deletions
diff --git a/.gitignore b/.gitignore
index e04c219..fae7509 100644
--- a/.gitignore
+++ b/.gitignore
@@ -29,9 +29,14 @@ addon-modules/
29bin/Debug/*.dll 29bin/Debug/*.dll
30bin/*.dll.mdb 30bin/*.dll.mdb
31bin/*.db 31bin/*.db
32bin/*.db-journal
32bin/addin-db-* 33bin/addin-db-*
33bin/*.dll 34bin/*.dll
34bin/OpenSim.vshost.exe.config 35bin/OpenSim.vshost.exe.config
36bin/OpenSim.32BitLaunch.vshost.exe.config
37bin/OpenSim.32BitLaunch.log
38UpgradeLog.XML
39_UpgradeReport_Files/
35bin/ScriptEngines/*-*-*-*-* 40bin/ScriptEngines/*-*-*-*-*
36bin/ScriptEngines/*.dll 41bin/ScriptEngines/*.dll
37bin/ScriptEngines/*/*.dll 42bin/ScriptEngines/*/*.dll
@@ -64,6 +69,7 @@ Examples/*.dll
64OpenSim.build 69OpenSim.build
65OpenSim.sln 70OpenSim.sln
66OpenSim.suo 71OpenSim.suo
72OpenSim.userprefs
67Prebuild/Prebuild.build 73Prebuild/Prebuild.build
68Prebuild/Prebuild.sln 74Prebuild/Prebuild.sln
69TestResult.xml 75TestResult.xml
diff --git a/.nant/local.include b/.nant/local.include
index 6d3e972..35f0058 100644
--- a/.nant/local.include
+++ b/.nant/local.include
@@ -135,14 +135,25 @@
135 <delete dir="%temp%"/> 135 <delete dir="%temp%"/>
136</target> 136</target>
137 137
138<target name="torture" depends="build, find-nunit"> 138<target name="test-stress" depends="build, find-nunit">
139 <setenv name="MONO_THREADS_PER_CPU" value="100" /> 139 <setenv name="MONO_THREADS_PER_CPU" value="100" />
140 140
141 <exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.tests.torture"> 141 <exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.tests.stress">
142 <arg value="./bin/OpenSim.Tests.Torture.dll" /> 142 <arg value="./bin/OpenSim.Tests.Stress.dll" />
143 </exec> 143 </exec>
144 144
145 <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.tests.torture)==0}" /> 145 <fail message="Failures reported in stress tests." unless="${int::parse(testresult.opensim.tests.stress)==0}" />
146 <delete dir="%temp%"/>
147</target>
148
149<target name="test-perf" depends="build, find-nunit">
150 <setenv name="MONO_THREADS_PER_CPU" value="100" />
151
152 <exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.tests.performance">
153 <arg value="./bin/OpenSim.Tests.Performance.dll" />
154 </exec>
155
156 <fail message="Failures reported in performance tests." unless="${int::parse(testresult.opensim.tests.performance)==0}" />
146 <delete dir="%temp%"/> 157 <delete dir="%temp%"/>
147</target> 158</target>
148 159
diff --git a/BUILDING.txt b/BUILDING.md
index 12e5ea5..5210b58 100644
--- a/BUILDING.txt
+++ b/BUILDING.md
@@ -1,6 +1,4 @@
1==== Building OpenSim ==== 1# Building on Windows
2
3=== Building on Windows ===
4 2
5Steps: 3Steps:
6 * runprebuild.bat 4 * runprebuild.bat
@@ -9,16 +7,15 @@ Steps:
9 * copy OpenSim.ini.example to OpenSim.ini and other appropriate files in bin/config-include 7 * copy OpenSim.ini.example to OpenSim.ini and other appropriate files in bin/config-include
10 * run OpenSim.exe 8 * run OpenSim.exe
11 9
12=== Building on Linux === 10# Building on Linux
13 11
14Prereqs: 12Prereqs:
15 * Mono >= 2.4.3 13* Mono >= 2.4.3
16 * Nant >= 0.85 14* Nant >= 0.85
17 * On some Linux distributions you may need to install additional packages. 15* On some Linux distributions you may need to install additional packages.
18 See http://opensimulator.org/wiki/Dependencies for more information. 16 See http://opensimulator.org/wiki/Dependencies for more information.
19 17* May also use xbuild (included in mono distributions)
20 * May also use xbuild (included in mono distributions) 18* May use Monodevelop, a cross-platform IDE
21 * May use Monodevelop, a cross-platform IDE
22 19
23From the distribution type: 20From the distribution type:
24 * ./runprebuild.sh 21 * ./runprebuild.sh
@@ -27,13 +24,13 @@ From the distribution type:
27 * copy OpenSim.ini.example to OpenSim.ini and other appropriate files in bin/config-include 24 * copy OpenSim.ini.example to OpenSim.ini and other appropriate files in bin/config-include
28 * run mono OpenSim.exe 25 * run mono OpenSim.exe
29 26
30=== Using Monodevelop === 27# Using Monodevelop
31 28
32From the distribution type: 29From the distribution type:
33 * ./runprebuild.sh 30 * ./runprebuild.sh
34 * type monodevelop OpenSim.sln 31 * type monodevelop OpenSim.sln
35 32
36=== References === 33# References
37 34
38Helpful resources: 35Helpful resources:
39* http://opensimulator.org/wiki/Build_Instructions 36* http://opensimulator.org/wiki/Build_Instructions
diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt
index 9dd0797..7c07a2a 100644
--- a/CONTRIBUTORS.txt
+++ b/CONTRIBUTORS.txt
@@ -92,6 +92,7 @@ what it is today.
92* Flyte Xevious 92* Flyte Xevious
93* Garmin Kawaguichi 93* Garmin Kawaguichi
94* Gryc Ueusp 94* Gryc Ueusp
95* Hiro Lecker
95* Imaze Rhiano 96* Imaze Rhiano
96* Intimidated 97* Intimidated
97* Jeremy Bongio (IBM) 98* Jeremy Bongio (IBM)
diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs
index 437d150..202d199 100644
--- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs
+++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs
@@ -1493,6 +1493,8 @@ namespace OpenSim.ApplicationPlugins.RemoteController
1493 /// <description>profile url</description></item> 1493 /// <description>profile url</description></item>
1494 /// <item><term>noassets</term> 1494 /// <item><term>noassets</term>
1495 /// <description>true if no assets should be saved</description></item> 1495 /// <description>true if no assets should be saved</description></item>
1496 /// <item><term>all</term>
1497 /// <description>true to save all the regions in the simulator</description></item>
1496 /// <item><term>perm</term> 1498 /// <item><term>perm</term>
1497 /// <description>C and/or T</description></item> 1499 /// <description>C and/or T</description></item>
1498 /// </list> 1500 /// </list>
@@ -1549,6 +1551,11 @@ namespace OpenSim.ApplicationPlugins.RemoteController
1549 options["checkPermissions"] = (string)requestData["perm"]; 1551 options["checkPermissions"] = (string)requestData["perm"];
1550 } 1552 }
1551 1553
1554 if ((string)requestData["all"] == "true")
1555 {
1556 options["all"] = (string)requestData["all"];
1557 }
1558
1552 IRegionArchiverModule archiver = scene.RequestModuleInterface<IRegionArchiverModule>(); 1559 IRegionArchiverModule archiver = scene.RequestModuleInterface<IRegionArchiverModule>();
1553 1560
1554 if (archiver != null) 1561 if (archiver != null)
diff --git a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs
index 4e755aa..7b4e957 100644
--- a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs
+++ b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs
@@ -196,11 +196,25 @@ namespace OpenSim.Capabilities.Handlers
196 int start, end; 196 int start, end;
197 if (TryParseRange(range, out start, out end)) 197 if (TryParseRange(range, out start, out end))
198 { 198 {
199
200 // Before clamping start make sure we can satisfy it in order to avoid 199 // Before clamping start make sure we can satisfy it in order to avoid
201 // sending back the last byte instead of an error status 200 // sending back the last byte instead of an error status
202 if (start >= texture.Data.Length) 201 if (start >= texture.Data.Length)
203 { 202 {
203// m_log.DebugFormat(
204// "[GETTEXTURE]: Client requested range for texture {0} starting at {1} but texture has end of {2}",
205// texture.ID, start, texture.Data.Length);
206
207 // Stricly speaking, as per http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html, we should be sending back
208 // Requested Range Not Satisfiable (416) here. However, it appears that at least recent implementations
209 // of the Linden Lab viewer (3.2.1 and 3.3.4 and probably earlier), a viewer that has previously
210 // received a very small texture may attempt to fetch bytes from the server past the
211 // range of data that it received originally. Whether this happens appears to depend on whether
212 // the viewer's estimation of how large a request it needs to make for certain discard levels
213 // (http://wiki.secondlife.com/wiki/Image_System#Discard_Level_and_Mip_Mapping), chiefly discard
214 // level 2. If this estimate is greater than the total texture size, returning a RequestedRangeNotSatisfiable
215 // here will cause the viewer to treat the texture as bad and never display the full resolution
216 // However, if we return PartialContent (or OK) instead, the viewer will display that resolution.
217
204// response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable; 218// response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable;
205 // viewers don't seem to handle RequestedRangeNotSatisfiable and keep retrying with same parameters 219 // viewers don't seem to handle RequestedRangeNotSatisfiable and keep retrying with same parameters
206 response["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound; 220 response["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound;
@@ -211,7 +225,7 @@ namespace OpenSim.Capabilities.Handlers
211 start = Utils.Clamp(start, 0, end); 225 start = Utils.Clamp(start, 0, end);
212 int len = end - start + 1; 226 int len = end - start + 1;
213 227
214 //m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID); 228// m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);
215 229
216 // Always return PartialContent, even if the range covered the entire data length 230 // Always return PartialContent, even if the range covered the entire data length
217 // We were accidentally sending back 404 before in this situation 231 // We were accidentally sending back 404 before in this situation
diff --git a/OpenSim/Data/IXInventoryData.cs b/OpenSim/Data/IXInventoryData.cs
index 85a5c08..e64a828 100644
--- a/OpenSim/Data/IXInventoryData.cs
+++ b/OpenSim/Data/IXInventoryData.cs
@@ -40,6 +40,11 @@ namespace OpenSim.Data
40 public UUID folderID; 40 public UUID folderID;
41 public UUID agentID; 41 public UUID agentID;
42 public UUID parentFolderID; 42 public UUID parentFolderID;
43
44 public XInventoryFolder Clone()
45 {
46 return (XInventoryFolder)MemberwiseClone();
47 }
43 } 48 }
44 49
45 public class XInventoryItem 50 public class XInventoryItem
@@ -64,6 +69,11 @@ namespace OpenSim.Data
64 public UUID avatarID; 69 public UUID avatarID;
65 public UUID parentFolderID; 70 public UUID parentFolderID;
66 public int inventoryGroupPermissions; 71 public int inventoryGroupPermissions;
72
73 public XInventoryItem Clone()
74 {
75 return (XInventoryItem)MemberwiseClone();
76 }
67 } 77 }
68 78
69 public interface IXInventoryData 79 public interface IXInventoryData
diff --git a/OpenSim/Data/MySQL/MySQLSimulationData.cs b/OpenSim/Data/MySQL/MySQLSimulationData.cs
index 4d7c0c9..12c979a 100644
--- a/OpenSim/Data/MySQL/MySQLSimulationData.cs
+++ b/OpenSim/Data/MySQL/MySQLSimulationData.cs
@@ -747,95 +747,99 @@ namespace OpenSim.Data.MySQL
747 RegionLightShareData nWP = new RegionLightShareData(); 747 RegionLightShareData nWP = new RegionLightShareData();
748 nWP.OnSave += StoreRegionWindlightSettings; 748 nWP.OnSave += StoreRegionWindlightSettings;
749 749
750 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) 750 lock (m_dbLock)
751 { 751 {
752 dbcon.Open(); 752 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
753
754 string command = "select * from `regionwindlight` where region_id = ?regionID";
755
756 using (MySqlCommand cmd = new MySqlCommand(command))
757 { 753 {
758 cmd.Connection = dbcon; 754 dbcon.Open();
759 755
760 cmd.Parameters.AddWithValue("?regionID", regionUUID.ToString()); 756 string command = "select * from `regionwindlight` where region_id = ?regionID";
761 757
762 IDataReader result = ExecuteReader(cmd); 758 using (MySqlCommand cmd = new MySqlCommand(command))
763 if (!result.Read())
764 {
765 //No result, so store our default windlight profile and return it
766 nWP.regionID = regionUUID;
767 // StoreRegionWindlightSettings(nWP);
768 return nWP;
769 }
770 else
771 { 759 {
772 nWP.regionID = DBGuid.FromDB(result["region_id"]); 760 cmd.Connection = dbcon;
773 nWP.waterColor.X = Convert.ToSingle(result["water_color_r"]); 761
774 nWP.waterColor.Y = Convert.ToSingle(result["water_color_g"]); 762 cmd.Parameters.AddWithValue("?regionID", regionUUID.ToString());
775 nWP.waterColor.Z = Convert.ToSingle(result["water_color_b"]); 763
776 nWP.waterFogDensityExponent = Convert.ToSingle(result["water_fog_density_exponent"]); 764 IDataReader result = ExecuteReader(cmd);
777 nWP.underwaterFogModifier = Convert.ToSingle(result["underwater_fog_modifier"]); 765 if (!result.Read())
778 nWP.reflectionWaveletScale.X = Convert.ToSingle(result["reflection_wavelet_scale_1"]); 766 {
779 nWP.reflectionWaveletScale.Y = Convert.ToSingle(result["reflection_wavelet_scale_2"]); 767 //No result, so store our default windlight profile and return it
780 nWP.reflectionWaveletScale.Z = Convert.ToSingle(result["reflection_wavelet_scale_3"]); 768 nWP.regionID = regionUUID;
781 nWP.fresnelScale = Convert.ToSingle(result["fresnel_scale"]); 769// StoreRegionWindlightSettings(nWP);
782 nWP.fresnelOffset = Convert.ToSingle(result["fresnel_offset"]); 770 return nWP;
783 nWP.refractScaleAbove = Convert.ToSingle(result["refract_scale_above"]); 771 }
784 nWP.refractScaleBelow = Convert.ToSingle(result["refract_scale_below"]); 772 else
785 nWP.blurMultiplier = Convert.ToSingle(result["blur_multiplier"]); 773 {
786 nWP.bigWaveDirection.X = Convert.ToSingle(result["big_wave_direction_x"]); 774 nWP.regionID = DBGuid.FromDB(result["region_id"]);
787 nWP.bigWaveDirection.Y = Convert.ToSingle(result["big_wave_direction_y"]); 775 nWP.waterColor.X = Convert.ToSingle(result["water_color_r"]);
788 nWP.littleWaveDirection.X = Convert.ToSingle(result["little_wave_direction_x"]); 776 nWP.waterColor.Y = Convert.ToSingle(result["water_color_g"]);
789 nWP.littleWaveDirection.Y = Convert.ToSingle(result["little_wave_direction_y"]); 777 nWP.waterColor.Z = Convert.ToSingle(result["water_color_b"]);
790 UUID.TryParse(result["normal_map_texture"].ToString(), out nWP.normalMapTexture); 778 nWP.waterFogDensityExponent = Convert.ToSingle(result["water_fog_density_exponent"]);
791 nWP.horizon.X = Convert.ToSingle(result["horizon_r"]); 779 nWP.underwaterFogModifier = Convert.ToSingle(result["underwater_fog_modifier"]);
792 nWP.horizon.Y = Convert.ToSingle(result["horizon_g"]); 780 nWP.reflectionWaveletScale.X = Convert.ToSingle(result["reflection_wavelet_scale_1"]);
793 nWP.horizon.Z = Convert.ToSingle(result["horizon_b"]); 781 nWP.reflectionWaveletScale.Y = Convert.ToSingle(result["reflection_wavelet_scale_2"]);
794 nWP.horizon.W = Convert.ToSingle(result["horizon_i"]); 782 nWP.reflectionWaveletScale.Z = Convert.ToSingle(result["reflection_wavelet_scale_3"]);
795 nWP.hazeHorizon = Convert.ToSingle(result["haze_horizon"]); 783 nWP.fresnelScale = Convert.ToSingle(result["fresnel_scale"]);
796 nWP.blueDensity.X = Convert.ToSingle(result["blue_density_r"]); 784 nWP.fresnelOffset = Convert.ToSingle(result["fresnel_offset"]);
797 nWP.blueDensity.Y = Convert.ToSingle(result["blue_density_g"]); 785 nWP.refractScaleAbove = Convert.ToSingle(result["refract_scale_above"]);
798 nWP.blueDensity.Z = Convert.ToSingle(result["blue_density_b"]); 786 nWP.refractScaleBelow = Convert.ToSingle(result["refract_scale_below"]);
799 nWP.blueDensity.W = Convert.ToSingle(result["blue_density_i"]); 787 nWP.blurMultiplier = Convert.ToSingle(result["blur_multiplier"]);
800 nWP.hazeDensity = Convert.ToSingle(result["haze_density"]); 788 nWP.bigWaveDirection.X = Convert.ToSingle(result["big_wave_direction_x"]);
801 nWP.densityMultiplier = Convert.ToSingle(result["density_multiplier"]); 789 nWP.bigWaveDirection.Y = Convert.ToSingle(result["big_wave_direction_y"]);
802 nWP.distanceMultiplier = Convert.ToSingle(result["distance_multiplier"]); 790 nWP.littleWaveDirection.X = Convert.ToSingle(result["little_wave_direction_x"]);
803 nWP.maxAltitude = Convert.ToUInt16(result["max_altitude"]); 791 nWP.littleWaveDirection.Y = Convert.ToSingle(result["little_wave_direction_y"]);
804 nWP.sunMoonColor.X = Convert.ToSingle(result["sun_moon_color_r"]); 792 UUID.TryParse(result["normal_map_texture"].ToString(), out nWP.normalMapTexture);
805 nWP.sunMoonColor.Y = Convert.ToSingle(result["sun_moon_color_g"]); 793 nWP.horizon.X = Convert.ToSingle(result["horizon_r"]);
806 nWP.sunMoonColor.Z = Convert.ToSingle(result["sun_moon_color_b"]); 794 nWP.horizon.Y = Convert.ToSingle(result["horizon_g"]);
807 nWP.sunMoonColor.W = Convert.ToSingle(result["sun_moon_color_i"]); 795 nWP.horizon.Z = Convert.ToSingle(result["horizon_b"]);
808 nWP.sunMoonPosition = Convert.ToSingle(result["sun_moon_position"]); 796 nWP.horizon.W = Convert.ToSingle(result["horizon_i"]);
809 nWP.ambient.X = Convert.ToSingle(result["ambient_r"]); 797 nWP.hazeHorizon = Convert.ToSingle(result["haze_horizon"]);
810 nWP.ambient.Y = Convert.ToSingle(result["ambient_g"]); 798 nWP.blueDensity.X = Convert.ToSingle(result["blue_density_r"]);
811 nWP.ambient.Z = Convert.ToSingle(result["ambient_b"]); 799 nWP.blueDensity.Y = Convert.ToSingle(result["blue_density_g"]);
812 nWP.ambient.W = Convert.ToSingle(result["ambient_i"]); 800 nWP.blueDensity.Z = Convert.ToSingle(result["blue_density_b"]);
813 nWP.eastAngle = Convert.ToSingle(result["east_angle"]); 801 nWP.blueDensity.W = Convert.ToSingle(result["blue_density_i"]);
814 nWP.sunGlowFocus = Convert.ToSingle(result["sun_glow_focus"]); 802 nWP.hazeDensity = Convert.ToSingle(result["haze_density"]);
815 nWP.sunGlowSize = Convert.ToSingle(result["sun_glow_size"]); 803 nWP.densityMultiplier = Convert.ToSingle(result["density_multiplier"]);
816 nWP.sceneGamma = Convert.ToSingle(result["scene_gamma"]); 804 nWP.distanceMultiplier = Convert.ToSingle(result["distance_multiplier"]);
817 nWP.starBrightness = Convert.ToSingle(result["star_brightness"]); 805 nWP.maxAltitude = Convert.ToUInt16(result["max_altitude"]);
818 nWP.cloudColor.X = Convert.ToSingle(result["cloud_color_r"]); 806 nWP.sunMoonColor.X = Convert.ToSingle(result["sun_moon_color_r"]);
819 nWP.cloudColor.Y = Convert.ToSingle(result["cloud_color_g"]); 807 nWP.sunMoonColor.Y = Convert.ToSingle(result["sun_moon_color_g"]);
820 nWP.cloudColor.Z = Convert.ToSingle(result["cloud_color_b"]); 808 nWP.sunMoonColor.Z = Convert.ToSingle(result["sun_moon_color_b"]);
821 nWP.cloudColor.W = Convert.ToSingle(result["cloud_color_i"]); 809 nWP.sunMoonColor.W = Convert.ToSingle(result["sun_moon_color_i"]);
822 nWP.cloudXYDensity.X = Convert.ToSingle(result["cloud_x"]); 810 nWP.sunMoonPosition = Convert.ToSingle(result["sun_moon_position"]);
823 nWP.cloudXYDensity.Y = Convert.ToSingle(result["cloud_y"]); 811 nWP.ambient.X = Convert.ToSingle(result["ambient_r"]);
824 nWP.cloudXYDensity.Z = Convert.ToSingle(result["cloud_density"]); 812 nWP.ambient.Y = Convert.ToSingle(result["ambient_g"]);
825 nWP.cloudCoverage = Convert.ToSingle(result["cloud_coverage"]); 813 nWP.ambient.Z = Convert.ToSingle(result["ambient_b"]);
826 nWP.cloudScale = Convert.ToSingle(result["cloud_scale"]); 814 nWP.ambient.W = Convert.ToSingle(result["ambient_i"]);
827 nWP.cloudDetailXYDensity.X = Convert.ToSingle(result["cloud_detail_x"]); 815 nWP.eastAngle = Convert.ToSingle(result["east_angle"]);
828 nWP.cloudDetailXYDensity.Y = Convert.ToSingle(result["cloud_detail_y"]); 816 nWP.sunGlowFocus = Convert.ToSingle(result["sun_glow_focus"]);
829 nWP.cloudDetailXYDensity.Z = Convert.ToSingle(result["cloud_detail_density"]); 817 nWP.sunGlowSize = Convert.ToSingle(result["sun_glow_size"]);
830 nWP.cloudScrollX = Convert.ToSingle(result["cloud_scroll_x"]); 818 nWP.sceneGamma = Convert.ToSingle(result["scene_gamma"]);
831 nWP.cloudScrollXLock = Convert.ToBoolean(result["cloud_scroll_x_lock"]); 819 nWP.starBrightness = Convert.ToSingle(result["star_brightness"]);
832 nWP.cloudScrollY = Convert.ToSingle(result["cloud_scroll_y"]); 820 nWP.cloudColor.X = Convert.ToSingle(result["cloud_color_r"]);
833 nWP.cloudScrollYLock = Convert.ToBoolean(result["cloud_scroll_y_lock"]); 821 nWP.cloudColor.Y = Convert.ToSingle(result["cloud_color_g"]);
834 nWP.drawClassicClouds = Convert.ToBoolean(result["draw_classic_clouds"]); 822 nWP.cloudColor.Z = Convert.ToSingle(result["cloud_color_b"]);
835 nWP.valid = true; 823 nWP.cloudColor.W = Convert.ToSingle(result["cloud_color_i"]);
824 nWP.cloudXYDensity.X = Convert.ToSingle(result["cloud_x"]);
825 nWP.cloudXYDensity.Y = Convert.ToSingle(result["cloud_y"]);
826 nWP.cloudXYDensity.Z = Convert.ToSingle(result["cloud_density"]);
827 nWP.cloudCoverage = Convert.ToSingle(result["cloud_coverage"]);
828 nWP.cloudScale = Convert.ToSingle(result["cloud_scale"]);
829 nWP.cloudDetailXYDensity.X = Convert.ToSingle(result["cloud_detail_x"]);
830 nWP.cloudDetailXYDensity.Y = Convert.ToSingle(result["cloud_detail_y"]);
831 nWP.cloudDetailXYDensity.Z = Convert.ToSingle(result["cloud_detail_density"]);
832 nWP.cloudScrollX = Convert.ToSingle(result["cloud_scroll_x"]);
833 nWP.cloudScrollXLock = Convert.ToBoolean(result["cloud_scroll_x_lock"]);
834 nWP.cloudScrollY = Convert.ToSingle(result["cloud_scroll_y"]);
835 nWP.cloudScrollYLock = Convert.ToBoolean(result["cloud_scroll_y_lock"]);
836 nWP.drawClassicClouds = Convert.ToBoolean(result["draw_classic_clouds"]);
837 nWP.valid = true;
838 }
836 } 839 }
837 } 840 }
838 } 841 }
842
839 return nWP; 843 return nWP;
840 } 844 }
841 845
@@ -881,118 +885,124 @@ namespace OpenSim.Data.MySQL
881 885
882 public virtual void StoreRegionWindlightSettings(RegionLightShareData wl) 886 public virtual void StoreRegionWindlightSettings(RegionLightShareData wl)
883 { 887 {
884 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) 888 lock (m_dbLock)
885 { 889 {
886 dbcon.Open(); 890 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
887
888 using (MySqlCommand cmd = dbcon.CreateCommand())
889 { 891 {
890 cmd.CommandText = "REPLACE INTO `regionwindlight` (`region_id`, `water_color_r`, `water_color_g`, "; 892 dbcon.Open();
891 cmd.CommandText += "`water_color_b`, `water_fog_density_exponent`, `underwater_fog_modifier`, "; 893
892 cmd.CommandText += "`reflection_wavelet_scale_1`, `reflection_wavelet_scale_2`, `reflection_wavelet_scale_3`, "; 894 using (MySqlCommand cmd = dbcon.CreateCommand())
893 cmd.CommandText += "`fresnel_scale`, `fresnel_offset`, `refract_scale_above`, `refract_scale_below`, "; 895 {
894 cmd.CommandText += "`blur_multiplier`, `big_wave_direction_x`, `big_wave_direction_y`, `little_wave_direction_x`, "; 896 cmd.CommandText = "REPLACE INTO `regionwindlight` (`region_id`, `water_color_r`, `water_color_g`, ";
895 cmd.CommandText += "`little_wave_direction_y`, `normal_map_texture`, `horizon_r`, `horizon_g`, `horizon_b`, "; 897 cmd.CommandText += "`water_color_b`, `water_fog_density_exponent`, `underwater_fog_modifier`, ";
896 cmd.CommandText += "`horizon_i`, `haze_horizon`, `blue_density_r`, `blue_density_g`, `blue_density_b`, "; 898 cmd.CommandText += "`reflection_wavelet_scale_1`, `reflection_wavelet_scale_2`, `reflection_wavelet_scale_3`, ";
897 cmd.CommandText += "`blue_density_i`, `haze_density`, `density_multiplier`, `distance_multiplier`, `max_altitude`, "; 899 cmd.CommandText += "`fresnel_scale`, `fresnel_offset`, `refract_scale_above`, `refract_scale_below`, ";
898 cmd.CommandText += "`sun_moon_color_r`, `sun_moon_color_g`, `sun_moon_color_b`, `sun_moon_color_i`, `sun_moon_position`, "; 900 cmd.CommandText += "`blur_multiplier`, `big_wave_direction_x`, `big_wave_direction_y`, `little_wave_direction_x`, ";
899 cmd.CommandText += "`ambient_r`, `ambient_g`, `ambient_b`, `ambient_i`, `east_angle`, `sun_glow_focus`, `sun_glow_size`, "; 901 cmd.CommandText += "`little_wave_direction_y`, `normal_map_texture`, `horizon_r`, `horizon_g`, `horizon_b`, ";
900 cmd.CommandText += "`scene_gamma`, `star_brightness`, `cloud_color_r`, `cloud_color_g`, `cloud_color_b`, `cloud_color_i`, "; 902 cmd.CommandText += "`horizon_i`, `haze_horizon`, `blue_density_r`, `blue_density_g`, `blue_density_b`, ";
901 cmd.CommandText += "`cloud_x`, `cloud_y`, `cloud_density`, `cloud_coverage`, `cloud_scale`, `cloud_detail_x`, "; 903 cmd.CommandText += "`blue_density_i`, `haze_density`, `density_multiplier`, `distance_multiplier`, `max_altitude`, ";
902 cmd.CommandText += "`cloud_detail_y`, `cloud_detail_density`, `cloud_scroll_x`, `cloud_scroll_x_lock`, `cloud_scroll_y`, "; 904 cmd.CommandText += "`sun_moon_color_r`, `sun_moon_color_g`, `sun_moon_color_b`, `sun_moon_color_i`, `sun_moon_position`, ";
903 cmd.CommandText += "`cloud_scroll_y_lock`, `draw_classic_clouds`) VALUES (?region_id, ?water_color_r, "; 905 cmd.CommandText += "`ambient_r`, `ambient_g`, `ambient_b`, `ambient_i`, `east_angle`, `sun_glow_focus`, `sun_glow_size`, ";
904 cmd.CommandText += "?water_color_g, ?water_color_b, ?water_fog_density_exponent, ?underwater_fog_modifier, ?reflection_wavelet_scale_1, "; 906 cmd.CommandText += "`scene_gamma`, `star_brightness`, `cloud_color_r`, `cloud_color_g`, `cloud_color_b`, `cloud_color_i`, ";
905 cmd.CommandText += "?reflection_wavelet_scale_2, ?reflection_wavelet_scale_3, ?fresnel_scale, ?fresnel_offset, ?refract_scale_above, "; 907 cmd.CommandText += "`cloud_x`, `cloud_y`, `cloud_density`, `cloud_coverage`, `cloud_scale`, `cloud_detail_x`, ";
906 cmd.CommandText += "?refract_scale_below, ?blur_multiplier, ?big_wave_direction_x, ?big_wave_direction_y, ?little_wave_direction_x, "; 908 cmd.CommandText += "`cloud_detail_y`, `cloud_detail_density`, `cloud_scroll_x`, `cloud_scroll_x_lock`, `cloud_scroll_y`, ";
907 cmd.CommandText += "?little_wave_direction_y, ?normal_map_texture, ?horizon_r, ?horizon_g, ?horizon_b, ?horizon_i, ?haze_horizon, "; 909 cmd.CommandText += "`cloud_scroll_y_lock`, `draw_classic_clouds`) VALUES (?region_id, ?water_color_r, ";
908 cmd.CommandText += "?blue_density_r, ?blue_density_g, ?blue_density_b, ?blue_density_i, ?haze_density, ?density_multiplier, "; 910 cmd.CommandText += "?water_color_g, ?water_color_b, ?water_fog_density_exponent, ?underwater_fog_modifier, ?reflection_wavelet_scale_1, ";
909 cmd.CommandText += "?distance_multiplier, ?max_altitude, ?sun_moon_color_r, ?sun_moon_color_g, ?sun_moon_color_b, "; 911 cmd.CommandText += "?reflection_wavelet_scale_2, ?reflection_wavelet_scale_3, ?fresnel_scale, ?fresnel_offset, ?refract_scale_above, ";
910 cmd.CommandText += "?sun_moon_color_i, ?sun_moon_position, ?ambient_r, ?ambient_g, ?ambient_b, ?ambient_i, ?east_angle, "; 912 cmd.CommandText += "?refract_scale_below, ?blur_multiplier, ?big_wave_direction_x, ?big_wave_direction_y, ?little_wave_direction_x, ";
911 cmd.CommandText += "?sun_glow_focus, ?sun_glow_size, ?scene_gamma, ?star_brightness, ?cloud_color_r, ?cloud_color_g, "; 913 cmd.CommandText += "?little_wave_direction_y, ?normal_map_texture, ?horizon_r, ?horizon_g, ?horizon_b, ?horizon_i, ?haze_horizon, ";
912 cmd.CommandText += "?cloud_color_b, ?cloud_color_i, ?cloud_x, ?cloud_y, ?cloud_density, ?cloud_coverage, ?cloud_scale, "; 914 cmd.CommandText += "?blue_density_r, ?blue_density_g, ?blue_density_b, ?blue_density_i, ?haze_density, ?density_multiplier, ";
913 cmd.CommandText += "?cloud_detail_x, ?cloud_detail_y, ?cloud_detail_density, ?cloud_scroll_x, ?cloud_scroll_x_lock, "; 915 cmd.CommandText += "?distance_multiplier, ?max_altitude, ?sun_moon_color_r, ?sun_moon_color_g, ?sun_moon_color_b, ";
914 cmd.CommandText += "?cloud_scroll_y, ?cloud_scroll_y_lock, ?draw_classic_clouds)"; 916 cmd.CommandText += "?sun_moon_color_i, ?sun_moon_position, ?ambient_r, ?ambient_g, ?ambient_b, ?ambient_i, ?east_angle, ";
915 917 cmd.CommandText += "?sun_glow_focus, ?sun_glow_size, ?scene_gamma, ?star_brightness, ?cloud_color_r, ?cloud_color_g, ";
916 cmd.Parameters.AddWithValue("region_id", wl.regionID); 918 cmd.CommandText += "?cloud_color_b, ?cloud_color_i, ?cloud_x, ?cloud_y, ?cloud_density, ?cloud_coverage, ?cloud_scale, ";
917 cmd.Parameters.AddWithValue("water_color_r", wl.waterColor.X); 919 cmd.CommandText += "?cloud_detail_x, ?cloud_detail_y, ?cloud_detail_density, ?cloud_scroll_x, ?cloud_scroll_x_lock, ";
918 cmd.Parameters.AddWithValue("water_color_g", wl.waterColor.Y); 920 cmd.CommandText += "?cloud_scroll_y, ?cloud_scroll_y_lock, ?draw_classic_clouds)";
919 cmd.Parameters.AddWithValue("water_color_b", wl.waterColor.Z); 921
920 cmd.Parameters.AddWithValue("water_fog_density_exponent", wl.waterFogDensityExponent); 922 cmd.Parameters.AddWithValue("region_id", wl.regionID);
921 cmd.Parameters.AddWithValue("underwater_fog_modifier", wl.underwaterFogModifier); 923 cmd.Parameters.AddWithValue("water_color_r", wl.waterColor.X);
922 cmd.Parameters.AddWithValue("reflection_wavelet_scale_1", wl.reflectionWaveletScale.X); 924 cmd.Parameters.AddWithValue("water_color_g", wl.waterColor.Y);
923 cmd.Parameters.AddWithValue("reflection_wavelet_scale_2", wl.reflectionWaveletScale.Y); 925 cmd.Parameters.AddWithValue("water_color_b", wl.waterColor.Z);
924 cmd.Parameters.AddWithValue("reflection_wavelet_scale_3", wl.reflectionWaveletScale.Z); 926 cmd.Parameters.AddWithValue("water_fog_density_exponent", wl.waterFogDensityExponent);
925 cmd.Parameters.AddWithValue("fresnel_scale", wl.fresnelScale); 927 cmd.Parameters.AddWithValue("underwater_fog_modifier", wl.underwaterFogModifier);
926 cmd.Parameters.AddWithValue("fresnel_offset", wl.fresnelOffset); 928 cmd.Parameters.AddWithValue("reflection_wavelet_scale_1", wl.reflectionWaveletScale.X);
927 cmd.Parameters.AddWithValue("refract_scale_above", wl.refractScaleAbove); 929 cmd.Parameters.AddWithValue("reflection_wavelet_scale_2", wl.reflectionWaveletScale.Y);
928 cmd.Parameters.AddWithValue("refract_scale_below", wl.refractScaleBelow); 930 cmd.Parameters.AddWithValue("reflection_wavelet_scale_3", wl.reflectionWaveletScale.Z);
929 cmd.Parameters.AddWithValue("blur_multiplier", wl.blurMultiplier); 931 cmd.Parameters.AddWithValue("fresnel_scale", wl.fresnelScale);
930 cmd.Parameters.AddWithValue("big_wave_direction_x", wl.bigWaveDirection.X); 932 cmd.Parameters.AddWithValue("fresnel_offset", wl.fresnelOffset);
931 cmd.Parameters.AddWithValue("big_wave_direction_y", wl.bigWaveDirection.Y); 933 cmd.Parameters.AddWithValue("refract_scale_above", wl.refractScaleAbove);
932 cmd.Parameters.AddWithValue("little_wave_direction_x", wl.littleWaveDirection.X); 934 cmd.Parameters.AddWithValue("refract_scale_below", wl.refractScaleBelow);
933 cmd.Parameters.AddWithValue("little_wave_direction_y", wl.littleWaveDirection.Y); 935 cmd.Parameters.AddWithValue("blur_multiplier", wl.blurMultiplier);
934 cmd.Parameters.AddWithValue("normal_map_texture", wl.normalMapTexture); 936 cmd.Parameters.AddWithValue("big_wave_direction_x", wl.bigWaveDirection.X);
935 cmd.Parameters.AddWithValue("horizon_r", wl.horizon.X); 937 cmd.Parameters.AddWithValue("big_wave_direction_y", wl.bigWaveDirection.Y);
936 cmd.Parameters.AddWithValue("horizon_g", wl.horizon.Y); 938 cmd.Parameters.AddWithValue("little_wave_direction_x", wl.littleWaveDirection.X);
937 cmd.Parameters.AddWithValue("horizon_b", wl.horizon.Z); 939 cmd.Parameters.AddWithValue("little_wave_direction_y", wl.littleWaveDirection.Y);
938 cmd.Parameters.AddWithValue("horizon_i", wl.horizon.W); 940 cmd.Parameters.AddWithValue("normal_map_texture", wl.normalMapTexture);
939 cmd.Parameters.AddWithValue("haze_horizon", wl.hazeHorizon); 941 cmd.Parameters.AddWithValue("horizon_r", wl.horizon.X);
940 cmd.Parameters.AddWithValue("blue_density_r", wl.blueDensity.X); 942 cmd.Parameters.AddWithValue("horizon_g", wl.horizon.Y);
941 cmd.Parameters.AddWithValue("blue_density_g", wl.blueDensity.Y); 943 cmd.Parameters.AddWithValue("horizon_b", wl.horizon.Z);
942 cmd.Parameters.AddWithValue("blue_density_b", wl.blueDensity.Z); 944 cmd.Parameters.AddWithValue("horizon_i", wl.horizon.W);
943 cmd.Parameters.AddWithValue("blue_density_i", wl.blueDensity.W); 945 cmd.Parameters.AddWithValue("haze_horizon", wl.hazeHorizon);
944 cmd.Parameters.AddWithValue("haze_density", wl.hazeDensity); 946 cmd.Parameters.AddWithValue("blue_density_r", wl.blueDensity.X);
945 cmd.Parameters.AddWithValue("density_multiplier", wl.densityMultiplier); 947 cmd.Parameters.AddWithValue("blue_density_g", wl.blueDensity.Y);
946 cmd.Parameters.AddWithValue("distance_multiplier", wl.distanceMultiplier); 948 cmd.Parameters.AddWithValue("blue_density_b", wl.blueDensity.Z);
947 cmd.Parameters.AddWithValue("max_altitude", wl.maxAltitude); 949 cmd.Parameters.AddWithValue("blue_density_i", wl.blueDensity.W);
948 cmd.Parameters.AddWithValue("sun_moon_color_r", wl.sunMoonColor.X); 950 cmd.Parameters.AddWithValue("haze_density", wl.hazeDensity);
949 cmd.Parameters.AddWithValue("sun_moon_color_g", wl.sunMoonColor.Y); 951 cmd.Parameters.AddWithValue("density_multiplier", wl.densityMultiplier);
950 cmd.Parameters.AddWithValue("sun_moon_color_b", wl.sunMoonColor.Z); 952 cmd.Parameters.AddWithValue("distance_multiplier", wl.distanceMultiplier);
951 cmd.Parameters.AddWithValue("sun_moon_color_i", wl.sunMoonColor.W); 953 cmd.Parameters.AddWithValue("max_altitude", wl.maxAltitude);
952 cmd.Parameters.AddWithValue("sun_moon_position", wl.sunMoonPosition); 954 cmd.Parameters.AddWithValue("sun_moon_color_r", wl.sunMoonColor.X);
953 cmd.Parameters.AddWithValue("ambient_r", wl.ambient.X); 955 cmd.Parameters.AddWithValue("sun_moon_color_g", wl.sunMoonColor.Y);
954 cmd.Parameters.AddWithValue("ambient_g", wl.ambient.Y); 956 cmd.Parameters.AddWithValue("sun_moon_color_b", wl.sunMoonColor.Z);
955 cmd.Parameters.AddWithValue("ambient_b", wl.ambient.Z); 957 cmd.Parameters.AddWithValue("sun_moon_color_i", wl.sunMoonColor.W);
956 cmd.Parameters.AddWithValue("ambient_i", wl.ambient.W); 958 cmd.Parameters.AddWithValue("sun_moon_position", wl.sunMoonPosition);
957 cmd.Parameters.AddWithValue("east_angle", wl.eastAngle); 959 cmd.Parameters.AddWithValue("ambient_r", wl.ambient.X);
958 cmd.Parameters.AddWithValue("sun_glow_focus", wl.sunGlowFocus); 960 cmd.Parameters.AddWithValue("ambient_g", wl.ambient.Y);
959 cmd.Parameters.AddWithValue("sun_glow_size", wl.sunGlowSize); 961 cmd.Parameters.AddWithValue("ambient_b", wl.ambient.Z);
960 cmd.Parameters.AddWithValue("scene_gamma", wl.sceneGamma); 962 cmd.Parameters.AddWithValue("ambient_i", wl.ambient.W);
961 cmd.Parameters.AddWithValue("star_brightness", wl.starBrightness); 963 cmd.Parameters.AddWithValue("east_angle", wl.eastAngle);
962 cmd.Parameters.AddWithValue("cloud_color_r", wl.cloudColor.X); 964 cmd.Parameters.AddWithValue("sun_glow_focus", wl.sunGlowFocus);
963 cmd.Parameters.AddWithValue("cloud_color_g", wl.cloudColor.Y); 965 cmd.Parameters.AddWithValue("sun_glow_size", wl.sunGlowSize);
964 cmd.Parameters.AddWithValue("cloud_color_b", wl.cloudColor.Z); 966 cmd.Parameters.AddWithValue("scene_gamma", wl.sceneGamma);
965 cmd.Parameters.AddWithValue("cloud_color_i", wl.cloudColor.W); 967 cmd.Parameters.AddWithValue("star_brightness", wl.starBrightness);
966 cmd.Parameters.AddWithValue("cloud_x", wl.cloudXYDensity.X); 968 cmd.Parameters.AddWithValue("cloud_color_r", wl.cloudColor.X);
967 cmd.Parameters.AddWithValue("cloud_y", wl.cloudXYDensity.Y); 969 cmd.Parameters.AddWithValue("cloud_color_g", wl.cloudColor.Y);
968 cmd.Parameters.AddWithValue("cloud_density", wl.cloudXYDensity.Z); 970 cmd.Parameters.AddWithValue("cloud_color_b", wl.cloudColor.Z);
969 cmd.Parameters.AddWithValue("cloud_coverage", wl.cloudCoverage); 971 cmd.Parameters.AddWithValue("cloud_color_i", wl.cloudColor.W);
970 cmd.Parameters.AddWithValue("cloud_scale", wl.cloudScale); 972 cmd.Parameters.AddWithValue("cloud_x", wl.cloudXYDensity.X);
971 cmd.Parameters.AddWithValue("cloud_detail_x", wl.cloudDetailXYDensity.X); 973 cmd.Parameters.AddWithValue("cloud_y", wl.cloudXYDensity.Y);
972 cmd.Parameters.AddWithValue("cloud_detail_y", wl.cloudDetailXYDensity.Y); 974 cmd.Parameters.AddWithValue("cloud_density", wl.cloudXYDensity.Z);
973 cmd.Parameters.AddWithValue("cloud_detail_density", wl.cloudDetailXYDensity.Z); 975 cmd.Parameters.AddWithValue("cloud_coverage", wl.cloudCoverage);
974 cmd.Parameters.AddWithValue("cloud_scroll_x", wl.cloudScrollX); 976 cmd.Parameters.AddWithValue("cloud_scale", wl.cloudScale);
975 cmd.Parameters.AddWithValue("cloud_scroll_x_lock", wl.cloudScrollXLock); 977 cmd.Parameters.AddWithValue("cloud_detail_x", wl.cloudDetailXYDensity.X);
976 cmd.Parameters.AddWithValue("cloud_scroll_y", wl.cloudScrollY); 978 cmd.Parameters.AddWithValue("cloud_detail_y", wl.cloudDetailXYDensity.Y);
977 cmd.Parameters.AddWithValue("cloud_scroll_y_lock", wl.cloudScrollYLock); 979 cmd.Parameters.AddWithValue("cloud_detail_density", wl.cloudDetailXYDensity.Z);
978 cmd.Parameters.AddWithValue("draw_classic_clouds", wl.drawClassicClouds); 980 cmd.Parameters.AddWithValue("cloud_scroll_x", wl.cloudScrollX);
979 981 cmd.Parameters.AddWithValue("cloud_scroll_x_lock", wl.cloudScrollXLock);
980 ExecuteNonQuery(cmd); 982 cmd.Parameters.AddWithValue("cloud_scroll_y", wl.cloudScrollY);
983 cmd.Parameters.AddWithValue("cloud_scroll_y_lock", wl.cloudScrollYLock);
984 cmd.Parameters.AddWithValue("draw_classic_clouds", wl.drawClassicClouds);
985
986 ExecuteNonQuery(cmd);
987 }
981 } 988 }
982 } 989 }
983 } 990 }
984 991
985 public virtual void RemoveRegionWindlightSettings(UUID regionID) 992 public virtual void RemoveRegionWindlightSettings(UUID regionID)
986 { 993 {
987 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) 994 lock (m_dbLock)
988 { 995 {
989 dbcon.Open(); 996 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
990
991 using (MySqlCommand cmd = dbcon.CreateCommand())
992 { 997 {
993 cmd.CommandText = "delete from `regionwindlight` where `region_id`=?regionID"; 998 dbcon.Open();
994 cmd.Parameters.AddWithValue("?regionID", regionID.ToString()); 999
995 ExecuteNonQuery(cmd); 1000 using (MySqlCommand cmd = dbcon.CreateCommand())
1001 {
1002 cmd.CommandText = "delete from `regionwindlight` where `region_id`=?regionID";
1003 cmd.Parameters.AddWithValue("?regionID", regionID.ToString());
1004 ExecuteNonQuery(cmd);
1005 }
996 } 1006 }
997 } 1007 }
998 } 1008 }
@@ -1000,26 +1010,29 @@ namespace OpenSim.Data.MySQL
1000 #region RegionEnvironmentSettings 1010 #region RegionEnvironmentSettings
1001 public string LoadRegionEnvironmentSettings(UUID regionUUID) 1011 public string LoadRegionEnvironmentSettings(UUID regionUUID)
1002 { 1012 {
1003 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) 1013 lock (m_dbLock)
1004 { 1014 {
1005 dbcon.Open(); 1015 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
1006
1007 string command = "select * from `regionenvironment` where region_id = ?region_id";
1008
1009 using (MySqlCommand cmd = new MySqlCommand(command))
1010 { 1016 {
1011 cmd.Connection = dbcon; 1017 dbcon.Open();
1012 1018
1013 cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString()); 1019 string command = "select * from `regionenvironment` where region_id = ?region_id";
1014 1020
1015 IDataReader result = ExecuteReader(cmd); 1021 using (MySqlCommand cmd = new MySqlCommand(command))
1016 if (!result.Read())
1017 {
1018 return String.Empty;
1019 }
1020 else
1021 { 1022 {
1022 return Convert.ToString(result["llsd_settings"]); 1023 cmd.Connection = dbcon;
1024
1025 cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString());
1026
1027 IDataReader result = ExecuteReader(cmd);
1028 if (!result.Read())
1029 {
1030 return String.Empty;
1031 }
1032 else
1033 {
1034 return Convert.ToString(result["llsd_settings"]);
1035 }
1023 } 1036 }
1024 } 1037 }
1025 } 1038 }
@@ -1027,33 +1040,39 @@ namespace OpenSim.Data.MySQL
1027 1040
1028 public void StoreRegionEnvironmentSettings(UUID regionUUID, string settings) 1041 public void StoreRegionEnvironmentSettings(UUID regionUUID, string settings)
1029 { 1042 {
1030 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) 1043 lock (m_dbLock)
1031 { 1044 {
1032 dbcon.Open(); 1045 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
1033
1034 using (MySqlCommand cmd = dbcon.CreateCommand())
1035 { 1046 {
1036 cmd.CommandText = "REPLACE INTO `regionenvironment` (`region_id`, `llsd_settings`) VALUES (?region_id, ?llsd_settings)"; 1047 dbcon.Open();
1037 1048
1038 cmd.Parameters.AddWithValue("region_id", regionUUID); 1049 using (MySqlCommand cmd = dbcon.CreateCommand())
1039 cmd.Parameters.AddWithValue("llsd_settings", settings); 1050 {
1040 1051 cmd.CommandText = "REPLACE INTO `regionenvironment` (`region_id`, `llsd_settings`) VALUES (?region_id, ?llsd_settings)";
1041 ExecuteNonQuery(cmd); 1052
1053 cmd.Parameters.AddWithValue("region_id", regionUUID);
1054 cmd.Parameters.AddWithValue("llsd_settings", settings);
1055
1056 ExecuteNonQuery(cmd);
1057 }
1042 } 1058 }
1043 } 1059 }
1044 } 1060 }
1045 1061
1046 public void RemoveRegionEnvironmentSettings(UUID regionUUID) 1062 public void RemoveRegionEnvironmentSettings(UUID regionUUID)
1047 { 1063 {
1048 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) 1064 lock (m_dbLock)
1049 { 1065 {
1050 dbcon.Open(); 1066 using (MySqlConnection dbcon = new MySqlConnection(m_connectionString))
1051
1052 using (MySqlCommand cmd = dbcon.CreateCommand())
1053 { 1067 {
1054 cmd.CommandText = "delete from `regionenvironment` where region_id = ?region_id"; 1068 dbcon.Open();
1055 cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString()); 1069
1056 ExecuteNonQuery(cmd); 1070 using (MySqlCommand cmd = dbcon.CreateCommand())
1071 {
1072 cmd.CommandText = "delete from `regionenvironment` where region_id = ?region_id";
1073 cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString());
1074 ExecuteNonQuery(cmd);
1075 }
1057 } 1076 }
1058 } 1077 }
1059 } 1078 }
diff --git a/OpenSim/Framework/Cache.cs b/OpenSim/Framework/Cache.cs
index 79e20fc..31cab4a 100644
--- a/OpenSim/Framework/Cache.cs
+++ b/OpenSim/Framework/Cache.cs
@@ -199,7 +199,14 @@ namespace OpenSim.Framework
199 // 199 //
200 public class Cache 200 public class Cache
201 { 201 {
202 /// <summary>
203 /// Must only be accessed under lock.
204 /// </summary>
202 private List<CacheItemBase> m_Index = new List<CacheItemBase>(); 205 private List<CacheItemBase> m_Index = new List<CacheItemBase>();
206
207 /// <summary>
208 /// Must only be accessed under m_Index lock.
209 /// </summary>
203 private Dictionary<string, CacheItemBase> m_Lookup = 210 private Dictionary<string, CacheItemBase> m_Lookup =
204 new Dictionary<string, CacheItemBase>(); 211 new Dictionary<string, CacheItemBase>();
205 212
@@ -320,19 +327,19 @@ namespace OpenSim.Framework
320 { 327 {
321 if (m_Lookup.ContainsKey(index)) 328 if (m_Lookup.ContainsKey(index))
322 item = m_Lookup[index]; 329 item = m_Lookup[index];
323 }
324 330
325 if (item == null) 331 if (item == null)
326 { 332 {
333 Expire(true);
334 return null;
335 }
336
337 item.hits++;
338 item.lastUsed = DateTime.Now;
339
327 Expire(true); 340 Expire(true);
328 return null;
329 } 341 }
330 342
331 item.hits++;
332 item.lastUsed = DateTime.Now;
333
334 Expire(true);
335
336 return item; 343 return item;
337 } 344 }
338 345
@@ -385,7 +392,10 @@ namespace OpenSim.Framework
385 // 392 //
386 public Object Find(Predicate<CacheItemBase> d) 393 public Object Find(Predicate<CacheItemBase> d)
387 { 394 {
388 CacheItemBase item = m_Index.Find(d); 395 CacheItemBase item;
396
397 lock (m_Index)
398 item = m_Index.Find(d);
389 399
390 if (item == null) 400 if (item == null)
391 return null; 401 return null;
@@ -419,12 +429,12 @@ namespace OpenSim.Framework
419 public virtual void Store(string index, Object data, Type container, 429 public virtual void Store(string index, Object data, Type container,
420 Object[] parameters) 430 Object[] parameters)
421 { 431 {
422 Expire(false);
423
424 CacheItemBase item; 432 CacheItemBase item;
425 433
426 lock (m_Index) 434 lock (m_Index)
427 { 435 {
436 Expire(false);
437
428 if (m_Index.Contains(new CacheItemBase(index))) 438 if (m_Index.Contains(new CacheItemBase(index)))
429 { 439 {
430 if ((m_Flags & CacheFlags.AllowUpdate) != 0) 440 if ((m_Flags & CacheFlags.AllowUpdate) != 0)
@@ -450,9 +460,17 @@ namespace OpenSim.Framework
450 m_Index.Add(item); 460 m_Index.Add(item);
451 m_Lookup[index] = item; 461 m_Lookup[index] = item;
452 } 462 }
463
453 item.Store(data); 464 item.Store(data);
454 } 465 }
455 466
467 /// <summary>
468 /// Expire items as appropriate.
469 /// </summary>
470 /// <remarks>
471 /// Callers must lock m_Index.
472 /// </remarks>
473 /// <param name='getting'></param>
456 protected virtual void Expire(bool getting) 474 protected virtual void Expire(bool getting)
457 { 475 {
458 if (getting && (m_Strategy == CacheStrategy.Aggressive)) 476 if (getting && (m_Strategy == CacheStrategy.Aggressive))
@@ -475,12 +493,10 @@ namespace OpenSim.Framework
475 493
476 switch (m_Strategy) 494 switch (m_Strategy)
477 { 495 {
478 case CacheStrategy.Aggressive: 496 case CacheStrategy.Aggressive:
479 if (Count < Size) 497 if (Count < Size)
480 return; 498 return;
481 499
482 lock (m_Index)
483 {
484 m_Index.Sort(new SortLRU()); 500 m_Index.Sort(new SortLRU());
485 m_Index.Reverse(); 501 m_Index.Reverse();
486 502
@@ -490,7 +506,7 @@ namespace OpenSim.Framework
490 506
491 ExpireDelegate doExpire = OnExpire; 507 ExpireDelegate doExpire = OnExpire;
492 508
493 if (doExpire != null) 509 if (doExpire != null)
494 { 510 {
495 List<CacheItemBase> candidates = 511 List<CacheItemBase> candidates =
496 m_Index.GetRange(target, Count - target); 512 m_Index.GetRange(target, Count - target);
@@ -513,27 +529,34 @@ namespace OpenSim.Framework
513 foreach (CacheItemBase item in m_Index) 529 foreach (CacheItemBase item in m_Index)
514 m_Lookup[item.uuid] = item; 530 m_Lookup[item.uuid] = item;
515 } 531 }
516 } 532
517 break; 533 break;
518 default: 534
519 break; 535 default:
536 break;
520 } 537 }
521 } 538 }
522 539
523 public void Invalidate(string uuid) 540 public void Invalidate(string uuid)
524 { 541 {
525 if (!m_Lookup.ContainsKey(uuid)) 542 lock (m_Index)
526 return; 543 {
544 if (!m_Lookup.ContainsKey(uuid))
545 return;
527 546
528 CacheItemBase item = m_Lookup[uuid]; 547 CacheItemBase item = m_Lookup[uuid];
529 m_Lookup.Remove(uuid); 548 m_Lookup.Remove(uuid);
530 m_Index.Remove(item); 549 m_Index.Remove(item);
550 }
531 } 551 }
532 552
533 public void Clear() 553 public void Clear()
534 { 554 {
535 m_Index.Clear(); 555 lock (m_Index)
536 m_Lookup.Clear(); 556 {
557 m_Index.Clear();
558 m_Lookup.Clear();
559 }
537 } 560 }
538 } 561 }
539} 562} \ No newline at end of file
diff --git a/OpenSim/Framework/Constants.cs b/OpenSim/Framework/Constants.cs
index 1b1aaf2..a2eb5ee 100644
--- a/OpenSim/Framework/Constants.cs
+++ b/OpenSim/Framework/Constants.cs
@@ -31,6 +31,7 @@ namespace OpenSim.Framework
31 public class Constants 31 public class Constants
32 { 32 {
33 public const uint RegionSize = 256; 33 public const uint RegionSize = 256;
34 public const uint RegionHeight = 4096;
34 public const byte TerrainPatchSize = 16; 35 public const byte TerrainPatchSize = 16;
35 public const string DefaultTexture = "89556747-24cb-43ed-920b-47caed15465f"; 36 public const string DefaultTexture = "89556747-24cb-43ed-920b-47caed15465f";
36 37
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs
index 6be2bd7..91f36a5 100644
--- a/OpenSim/Framework/IClientAPI.cs
+++ b/OpenSim/Framework/IClientAPI.cs
@@ -1046,8 +1046,21 @@ namespace OpenSim.Framework
1046 1046
1047 void InPacket(object NewPack); 1047 void InPacket(object NewPack);
1048 void ProcessInPacket(Packet NewPack); 1048 void ProcessInPacket(Packet NewPack);
1049
1050 /// <summary>
1051 /// Close this client
1052 /// </summary>
1049 void Close(); 1053 void Close();
1050 void Close(bool sendStop); 1054
1055 /// <summary>
1056 /// Close this client
1057 /// </summary>
1058 /// <param name='force'>
1059 /// If true, attempts the close without checking active status. You do not want to try this except as a last
1060 /// ditch attempt where Active == false but the ScenePresence still exists.
1061 /// </param>
1062 void Close(bool sendStop, bool force);
1063
1051 void Kick(string message); 1064 void Kick(string message);
1052 1065
1053 /// <summary> 1066 /// <summary>
diff --git a/OpenSim/Framework/InventoryFolderBase.cs b/OpenSim/Framework/InventoryFolderBase.cs
index a12183c..b3457a6 100644
--- a/OpenSim/Framework/InventoryFolderBase.cs
+++ b/OpenSim/Framework/InventoryFolderBase.cs
@@ -73,33 +73,27 @@ namespace OpenSim.Framework
73 { 73 {
74 } 74 }
75 75
76 public InventoryFolderBase(UUID id) 76 public InventoryFolderBase(UUID id) : this()
77 { 77 {
78 ID = id; 78 ID = id;
79 } 79 }
80 80
81 public InventoryFolderBase(UUID id, UUID owner) 81 public InventoryFolderBase(UUID id, UUID owner) : this(id)
82 { 82 {
83 ID = id;
84 Owner = owner; 83 Owner = owner;
85 } 84 }
86 85
87 public InventoryFolderBase(UUID id, string name, UUID owner, UUID parent) 86 public InventoryFolderBase(UUID id, string name, UUID owner, UUID parent) : this(id, owner)
88 { 87 {
89 ID = id;
90 Name = name; 88 Name = name;
91 Owner = owner;
92 ParentID = parent; 89 ParentID = parent;
93 } 90 }
94 91
95 public InventoryFolderBase(UUID id, string name, UUID owner, short type, UUID parent, ushort version) 92 public InventoryFolderBase(
93 UUID id, string name, UUID owner, short type, UUID parent, ushort version) : this(id, name, owner, parent)
96 { 94 {
97 ID = id;
98 Name = name;
99 Owner = owner;
100 Type = type; 95 Type = type;
101 ParentID = parent;
102 Version = version; 96 Version = version;
103 } 97 }
104 } 98 }
105} 99} \ No newline at end of file
diff --git a/OpenSim/Framework/Monitoring/Watchdog.cs b/OpenSim/Framework/Monitoring/Watchdog.cs
index b709baa..eaddb8c 100644
--- a/OpenSim/Framework/Monitoring/Watchdog.cs
+++ b/OpenSim/Framework/Monitoring/Watchdog.cs
@@ -89,6 +89,17 @@ namespace OpenSim.Framework.Monitoring
89 FirstTick = Environment.TickCount & Int32.MaxValue; 89 FirstTick = Environment.TickCount & Int32.MaxValue;
90 LastTick = FirstTick; 90 LastTick = FirstTick;
91 } 91 }
92
93 public ThreadWatchdogInfo(ThreadWatchdogInfo previousTwi)
94 {
95 Thread = previousTwi.Thread;
96 FirstTick = previousTwi.FirstTick;
97 LastTick = previousTwi.LastTick;
98 Timeout = previousTwi.Timeout;
99 IsTimedOut = previousTwi.IsTimedOut;
100 AlarmIfTimeout = previousTwi.AlarmIfTimeout;
101 AlarmMethod = previousTwi.AlarmMethod;
102 }
92 } 103 }
93 104
94 /// <summary> 105 /// <summary>
@@ -335,7 +346,9 @@ namespace OpenSim.Framework.Monitoring
335 if (callbackInfos == null) 346 if (callbackInfos == null)
336 callbackInfos = new List<ThreadWatchdogInfo>(); 347 callbackInfos = new List<ThreadWatchdogInfo>();
337 348
338 callbackInfos.Add(threadInfo); 349 // Send a copy of the watchdog info to prevent race conditions where the watchdog
350 // thread updates the monitoring info after an alarm has been sent out.
351 callbackInfos.Add(new ThreadWatchdogInfo(threadInfo));
339 } 352 }
340 } 353 }
341 } 354 }
diff --git a/OpenSim/Framework/RegionInfo.cs b/OpenSim/Framework/RegionInfo.cs
index 4bde7be..fc64ff9 100644
--- a/OpenSim/Framework/RegionInfo.cs
+++ b/OpenSim/Framework/RegionInfo.cs
@@ -122,10 +122,13 @@ namespace OpenSim.Framework
122 public UUID lastMapUUID = UUID.Zero; 122 public UUID lastMapUUID = UUID.Zero;
123 public string lastMapRefresh = "0"; 123 public string lastMapRefresh = "0";
124 124
125 private float m_nonphysPrimMin = 0;
125 private int m_nonphysPrimMax = 0; 126 private int m_nonphysPrimMax = 0;
127 private float m_physPrimMin = 0;
126 private int m_physPrimMax = 0; 128 private int m_physPrimMax = 0;
127 private bool m_clampPrimSize = false; 129 private bool m_clampPrimSize = false;
128 private int m_objectCapacity = 0; 130 private int m_objectCapacity = 0;
131 private int m_linksetCapacity = 0;
129 private int m_agentCapacity = 0; 132 private int m_agentCapacity = 0;
130 private string m_regionType = String.Empty; 133 private string m_regionType = String.Empty;
131 private RegionLightShareData m_windlight = new RegionLightShareData(); 134 private RegionLightShareData m_windlight = new RegionLightShareData();
@@ -287,11 +290,21 @@ namespace OpenSim.Framework
287 set { m_windlight = value; } 290 set { m_windlight = value; }
288 } 291 }
289 292
293 public float NonphysPrimMin
294 {
295 get { return m_nonphysPrimMin; }
296 }
297
290 public int NonphysPrimMax 298 public int NonphysPrimMax
291 { 299 {
292 get { return m_nonphysPrimMax; } 300 get { return m_nonphysPrimMax; }
293 } 301 }
294 302
303 public float PhysPrimMin
304 {
305 get { return m_physPrimMin; }
306 }
307
295 public int PhysPrimMax 308 public int PhysPrimMax
296 { 309 {
297 get { return m_physPrimMax; } 310 get { return m_physPrimMax; }
@@ -307,6 +320,11 @@ namespace OpenSim.Framework
307 get { return m_objectCapacity; } 320 get { return m_objectCapacity; }
308 } 321 }
309 322
323 public int LinksetCapacity
324 {
325 get { return m_linksetCapacity; }
326 }
327
310 public int AgentCapacity 328 public int AgentCapacity
311 { 329 {
312 get { return m_agentCapacity; } 330 get { return m_agentCapacity; }
@@ -625,16 +643,31 @@ namespace OpenSim.Framework
625 m_regionType = config.GetString("RegionType", String.Empty); 643 m_regionType = config.GetString("RegionType", String.Empty);
626 allKeys.Remove("RegionType"); 644 allKeys.Remove("RegionType");
627 645
628 // Prim stuff 646 #region Prim stuff
629 // 647
648 m_nonphysPrimMin = config.GetFloat("NonphysicalPrimMin", 0);
649 allKeys.Remove("NonphysicalPrimMin");
650
630 m_nonphysPrimMax = config.GetInt("NonphysicalPrimMax", 0); 651 m_nonphysPrimMax = config.GetInt("NonphysicalPrimMax", 0);
631 allKeys.Remove("NonphysicalPrimMax"); 652 allKeys.Remove("NonphysicalPrimMax");
653
654 m_physPrimMin = config.GetFloat("PhysicalPrimMin", 0);
655 allKeys.Remove("PhysicalPrimMin");
656
632 m_physPrimMax = config.GetInt("PhysicalPrimMax", 0); 657 m_physPrimMax = config.GetInt("PhysicalPrimMax", 0);
633 allKeys.Remove("PhysicalPrimMax"); 658 allKeys.Remove("PhysicalPrimMax");
659
634 m_clampPrimSize = config.GetBoolean("ClampPrimSize", false); 660 m_clampPrimSize = config.GetBoolean("ClampPrimSize", false);
635 allKeys.Remove("ClampPrimSize"); 661 allKeys.Remove("ClampPrimSize");
662
636 m_objectCapacity = config.GetInt("MaxPrims", 15000); 663 m_objectCapacity = config.GetInt("MaxPrims", 15000);
637 allKeys.Remove("MaxPrims"); 664 allKeys.Remove("MaxPrims");
665
666 m_linksetCapacity = config.GetInt("LinksetPrims", 0);
667 allKeys.Remove("LinksetPrims");
668
669 #endregion
670
638 m_agentCapacity = config.GetInt("MaxAgents", 100); 671 m_agentCapacity = config.GetInt("MaxAgents", 100);
639 allKeys.Remove("MaxAgents"); 672 allKeys.Remove("MaxAgents");
640 673
@@ -673,16 +706,27 @@ namespace OpenSim.Framework
673 706
674 config.Set("ExternalHostName", m_externalHostName); 707 config.Set("ExternalHostName", m_externalHostName);
675 708
676 if (m_nonphysPrimMax != 0) 709 if (m_nonphysPrimMin > 0)
710 config.Set("NonphysicalPrimMax", m_nonphysPrimMin);
711
712 if (m_nonphysPrimMax > 0)
677 config.Set("NonphysicalPrimMax", m_nonphysPrimMax); 713 config.Set("NonphysicalPrimMax", m_nonphysPrimMax);
678 if (m_physPrimMax != 0) 714
715 if (m_physPrimMin > 0)
716 config.Set("PhysicalPrimMax", m_physPrimMin);
717
718 if (m_physPrimMax > 0)
679 config.Set("PhysicalPrimMax", m_physPrimMax); 719 config.Set("PhysicalPrimMax", m_physPrimMax);
720
680 config.Set("ClampPrimSize", m_clampPrimSize.ToString()); 721 config.Set("ClampPrimSize", m_clampPrimSize.ToString());
681 722
682 if (m_objectCapacity != 0) 723 if (m_objectCapacity > 0)
683 config.Set("MaxPrims", m_objectCapacity); 724 config.Set("MaxPrims", m_objectCapacity);
684 725
685 if (m_agentCapacity != 0) 726 if (m_linksetCapacity > 0)
727 config.Set("LinksetPrims", m_linksetCapacity);
728
729 if (m_agentCapacity > 0)
686 config.Set("MaxAgents", m_agentCapacity); 730 config.Set("MaxAgents", m_agentCapacity);
687 731
688 if (ScopeID != UUID.Zero) 732 if (ScopeID != UUID.Zero)
@@ -759,9 +803,15 @@ namespace OpenSim.Framework
759 configMember.addConfigurationOption("lastmap_refresh", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, 803 configMember.addConfigurationOption("lastmap_refresh", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY,
760 "Last Map Refresh", Util.UnixTimeSinceEpoch().ToString(), true); 804 "Last Map Refresh", Util.UnixTimeSinceEpoch().ToString(), true);
761 805
806 configMember.addConfigurationOption("nonphysical_prim_min", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT,
807 "Minimum size for nonphysical prims", m_nonphysPrimMin.ToString(), true);
808
762 configMember.addConfigurationOption("nonphysical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32, 809 configMember.addConfigurationOption("nonphysical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
763 "Maximum size for nonphysical prims", m_nonphysPrimMax.ToString(), true); 810 "Maximum size for nonphysical prims", m_nonphysPrimMax.ToString(), true);
764 811
812 configMember.addConfigurationOption("physical_prim_min", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT,
813 "Minimum size for nonphysical prims", m_physPrimMin.ToString(), true);
814
765 configMember.addConfigurationOption("physical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32, 815 configMember.addConfigurationOption("physical_prim_max", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
766 "Maximum size for physical prims", m_physPrimMax.ToString(), true); 816 "Maximum size for physical prims", m_physPrimMax.ToString(), true);
767 817
@@ -771,6 +821,9 @@ namespace OpenSim.Framework
771 configMember.addConfigurationOption("object_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32, 821 configMember.addConfigurationOption("object_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
772 "Max objects this sim will hold", m_objectCapacity.ToString(), true); 822 "Max objects this sim will hold", m_objectCapacity.ToString(), true);
773 823
824 configMember.addConfigurationOption("linkset_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
825 "Max prims an object will hold", m_linksetCapacity.ToString(), true);
826
774 configMember.addConfigurationOption("agent_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32, 827 configMember.addConfigurationOption("agent_capacity", ConfigurationOption.ConfigurationTypes.TYPE_INT32,
775 "Max avatars this sim will hold", m_agentCapacity.ToString(), true); 828 "Max avatars this sim will hold", m_agentCapacity.ToString(), true);
776 829
@@ -892,6 +945,9 @@ namespace OpenSim.Framework
892 case "object_capacity": 945 case "object_capacity":
893 m_objectCapacity = (int)configuration_result; 946 m_objectCapacity = (int)configuration_result;
894 break; 947 break;
948 case "linkset_capacity":
949 m_linksetCapacity = (int)configuration_result;
950 break;
895 case "agent_capacity": 951 case "agent_capacity":
896 m_agentCapacity = (int)configuration_result; 952 m_agentCapacity = (int)configuration_result;
897 break; 953 break;
diff --git a/OpenSim/Framework/Serialization/ArchiveConstants.cs b/OpenSim/Framework/Serialization/ArchiveConstants.cs
index 2c5e001..48f1c4f 100644
--- a/OpenSim/Framework/Serialization/ArchiveConstants.cs
+++ b/OpenSim/Framework/Serialization/ArchiveConstants.cs
@@ -53,6 +53,11 @@ namespace OpenSim.Framework.Serialization
53 public const string INVENTORY_PATH = "inventory/"; 53 public const string INVENTORY_PATH = "inventory/";
54 54
55 /// <value> 55 /// <value>
56 /// Path for regions in a multi-region archive
57 /// </value>
58 public const string REGIONS_PATH = "regions/";
59
60 /// <value>
56 /// Path for the prims file 61 /// Path for the prims file
57 /// </value> 62 /// </value>
58 public const string OBJECTS_PATH = "objects/"; 63 public const string OBJECTS_PATH = "objects/";
diff --git a/OpenSim/Framework/Serialization/External/OspResolver.cs b/OpenSim/Framework/Serialization/External/OspResolver.cs
index d31d27c..fa7160f 100644
--- a/OpenSim/Framework/Serialization/External/OspResolver.cs
+++ b/OpenSim/Framework/Serialization/External/OspResolver.cs
@@ -65,9 +65,14 @@ namespace OpenSim.Framework.Serialization
65 65
66 UserAccount account = userService.GetUserAccount(UUID.Zero, userId); 66 UserAccount account = userService.GetUserAccount(UUID.Zero, userId);
67 if (account != null) 67 if (account != null)
68 {
68 return MakeOspa(account.FirstName, account.LastName); 69 return MakeOspa(account.FirstName, account.LastName);
70 }
69// else 71// else
72// {
70// m_log.WarnFormat("[OSP RESOLVER]: No user account for {0}", userId); 73// m_log.WarnFormat("[OSP RESOLVER]: No user account for {0}", userId);
74// System.Console.WriteLine("[OSP RESOLVER]: No user account for {0}", userId);
75// }
71 76
72 return null; 77 return null;
73 } 78 }
@@ -79,10 +84,13 @@ namespace OpenSim.Framework.Serialization
79 /// <returns></returns> 84 /// <returns></returns>
80 public static string MakeOspa(string firstName, string lastName) 85 public static string MakeOspa(string firstName, string lastName)
81 { 86 {
82// m_log.DebugFormat("[OSP RESOLVER]: Making OSPA for {0} {1}", firstName, lastName); 87 string ospa
88 = OSPA_PREFIX + OSPA_NAME_KEY + OSPA_PAIR_SEPARATOR + firstName + OSPA_NAME_VALUE_SEPARATOR + lastName;
89
90// m_log.DebugFormat("[OSP RESOLVER]: Made OSPA {0} for {1} {2}", ospa, firstName, lastName);
91// System.Console.WriteLine("[OSP RESOLVER]: Made OSPA {0} for {1} {2}", ospa, firstName, lastName);
83 92
84 return 93 return ospa;
85 OSPA_PREFIX + OSPA_NAME_KEY + OSPA_PAIR_SEPARATOR + firstName + OSPA_NAME_VALUE_SEPARATOR + lastName;
86 } 94 }
87 95
88 /// <summary> 96 /// <summary>
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
index 6121371..691b45a 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
@@ -449,9 +449,7 @@ namespace OpenSim.Framework.Servers.HttpServer
449 if (TryGetStreamHandler(handlerKey, out requestHandler)) 449 if (TryGetStreamHandler(handlerKey, out requestHandler))
450 { 450 {
451 if (DebugLevel >= 3) 451 if (DebugLevel >= 3)
452 m_log.DebugFormat( 452 LogIncomingToStreamHandler(request, requestHandler);
453 "[BASE HTTP SERVER]: Found stream handler for {0} {1} {2} {3}",
454 request.HttpMethod, request.Url.PathAndQuery, requestHandler.Name, requestHandler.Description);
455 453
456 response.ContentType = requestHandler.ContentType; // Lets do this defaulting before in case handler has varying content type. 454 response.ContentType = requestHandler.ContentType; // Lets do this defaulting before in case handler has varying content type.
457 455
@@ -563,9 +561,7 @@ namespace OpenSim.Framework.Servers.HttpServer
563 if (DoWeHaveALLSDHandler(request.RawUrl)) 561 if (DoWeHaveALLSDHandler(request.RawUrl))
564 { 562 {
565 if (DebugLevel >= 3) 563 if (DebugLevel >= 3)
566 m_log.DebugFormat( 564 LogIncomingToContentTypeHandler(request);
567 "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
568 request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
569 565
570 buffer = HandleLLSDRequests(request, response); 566 buffer = HandleLLSDRequests(request, response);
571 } 567 }
@@ -573,18 +569,14 @@ namespace OpenSim.Framework.Servers.HttpServer
573 else if (DoWeHaveAHTTPHandler(request.RawUrl)) 569 else if (DoWeHaveAHTTPHandler(request.RawUrl))
574 { 570 {
575 if (DebugLevel >= 3) 571 if (DebugLevel >= 3)
576 m_log.DebugFormat( 572 LogIncomingToContentTypeHandler(request);
577 "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
578 request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
579 573
580 buffer = HandleHTTPRequest(request, response); 574 buffer = HandleHTTPRequest(request, response);
581 } 575 }
582 else 576 else
583 { 577 {
584 if (DebugLevel >= 3) 578 if (DebugLevel >= 3)
585 m_log.DebugFormat( 579 LogIncomingToXmlRpcHandler(request);
586 "[BASE HTTP SERVER]: Assuming a generic XMLRPC request for {0} {1}",
587 request.HttpMethod, request.Url.PathAndQuery);
588 580
589 // generic login request. 581 // generic login request.
590 buffer = HandleXmlRpcRequests(request, response); 582 buffer = HandleXmlRpcRequests(request, response);
@@ -654,6 +646,58 @@ namespace OpenSim.Framework.Servers.HttpServer
654 } 646 }
655 } 647 }
656 648
649 private void LogIncomingToStreamHandler(OSHttpRequest request, IRequestHandler requestHandler)
650 {
651 m_log.DebugFormat(
652 "[BASE HTTP SERVER]: Found stream handler for {0} {1} {2} {3}",
653 request.HttpMethod, request.Url.PathAndQuery, requestHandler.Name, requestHandler.Description);
654
655 if (DebugLevel >= 4)
656 LogIncomingInDetail(request);
657 }
658
659 private void LogIncomingToContentTypeHandler(OSHttpRequest request)
660 {
661 m_log.DebugFormat(
662 "[BASE HTTP SERVER]: Found a {0} content type handler for {1} {2}",
663 request.ContentType, request.HttpMethod, request.Url.PathAndQuery);
664
665 if (DebugLevel >= 4)
666 LogIncomingInDetail(request);
667 }
668
669 private void LogIncomingToXmlRpcHandler(OSHttpRequest request)
670 {
671 m_log.DebugFormat(
672 "[BASE HTTP SERVER]: Assuming a generic XMLRPC request for {0} {1}",
673 request.HttpMethod, request.Url.PathAndQuery);
674
675 if (DebugLevel >= 4)
676 LogIncomingInDetail(request);
677 }
678
679 private void LogIncomingInDetail(OSHttpRequest request)
680 {
681 using (StreamReader reader = new StreamReader(Util.Copy(request.InputStream), Encoding.UTF8))
682 {
683 string output;
684
685 if (DebugLevel == 4)
686 {
687 const int sampleLength = 80;
688 char[] sampleChars = new char[sampleLength];
689 reader.Read(sampleChars, 0, sampleLength);
690 output = string.Format("[BASE HTTP SERVER]: {0}...", new string(sampleChars).Replace("\n", @"\n"));
691 }
692 else
693 {
694 output = string.Format("[BASE HTTP SERVER]: {0}", reader.ReadToEnd());
695 }
696
697 m_log.Debug(output);
698 }
699 }
700
657 private bool TryGetStreamHandler(string handlerKey, out IRequestHandler streamHandler) 701 private bool TryGetStreamHandler(string handlerKey, out IRequestHandler streamHandler)
658 { 702 {
659 string bestMatch = null; 703 string bestMatch = null;
diff --git a/OpenSim/Framework/Servers/MainServer.cs b/OpenSim/Framework/Servers/MainServer.cs
index 8dc0e3a..7402c73 100644
--- a/OpenSim/Framework/Servers/MainServer.cs
+++ b/OpenSim/Framework/Servers/MainServer.cs
@@ -29,6 +29,7 @@ using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection; 30using System.Reflection;
31using System.Net; 31using System.Net;
32using System.Text;
32using log4net; 33using log4net;
33using OpenSim.Framework; 34using OpenSim.Framework;
34using OpenSim.Framework.Console; 35using OpenSim.Framework.Console;
@@ -105,12 +106,19 @@ namespace OpenSim.Framework.Servers
105 public static void RegisterHttpConsoleCommands(ICommandConsole console) 106 public static void RegisterHttpConsoleCommands(ICommandConsole console)
106 { 107 {
107 console.Commands.AddCommand( 108 console.Commands.AddCommand(
109 "Comms", false, "show http-handlers",
110 "show http-handlers",
111 "Show all registered http handlers", HandleShowHttpHandlersCommand);
112
113 console.Commands.AddCommand(
108 "Debug", false, "debug http", "debug http [<level>]", 114 "Debug", false, "debug http", "debug http [<level>]",
109 "Turn on inbound non-poll http request debugging.", 115 "Turn on inbound non-poll http request debugging.",
110 "If level <= 0, then no extra logging is done.\n" 116 "If level <= 0, then no extra logging is done.\n"
111 + "If level >= 1, then short warnings are logged when receiving bad input data.\n" 117 + "If level >= 1, then short warnings are logged when receiving bad input data.\n"
112 + "If level >= 2, then long warnings are logged when receiving bad input data.\n" 118 + "If level >= 2, then long warnings are logged when receiving bad input data.\n"
113 + "If level >= 3, then short notices about all incoming non-poll HTTP requests are logged.\n" 119 + "If level >= 3, then short notices about all incoming non-poll HTTP requests are logged.\n"
120 + "If level >= 4, then a sample from the beginning of the incoming data is logged.\n"
121 + "If level >= 5, then the entire incoming data is logged.\n"
114 + "If no level is specified then the current level is returned.", 122 + "If no level is specified then the current level is returned.",
115 HandleDebugHttpCommand); 123 HandleDebugHttpCommand);
116 } 124 }
@@ -136,8 +144,53 @@ namespace OpenSim.Framework.Servers
136 } 144 }
137 else 145 else
138 { 146 {
139 MainConsole.Instance.Output("Usage: debug http 0..3"); 147 MainConsole.Instance.Output("Usage: debug http 0..5");
148 }
149 }
150
151 private static void HandleShowHttpHandlersCommand(string module, string[] args)
152 {
153 if (args.Length != 2)
154 {
155 MainConsole.Instance.Output("Usage: show http-handlers");
156 return;
157 }
158
159 StringBuilder handlers = new StringBuilder();
160
161 lock (m_Servers)
162 {
163 foreach (BaseHttpServer httpServer in m_Servers.Values)
164 {
165 handlers.AppendFormat(
166 "Registered HTTP Handlers for server at {0}:{1}\n", httpServer.ListenIPAddress, httpServer.Port);
167
168 handlers.AppendFormat("* XMLRPC:\n");
169 foreach (String s in httpServer.GetXmlRpcHandlerKeys())
170 handlers.AppendFormat("\t{0}\n", s);
171
172 handlers.AppendFormat("* HTTP:\n");
173 List<String> poll = httpServer.GetPollServiceHandlerKeys();
174 foreach (String s in httpServer.GetHTTPHandlerKeys())
175 handlers.AppendFormat("\t{0} {1}\n", s, (poll.Contains(s) ? "(poll service)" : string.Empty));
176
177 handlers.AppendFormat("* Agent:\n");
178 foreach (String s in httpServer.GetAgentHandlerKeys())
179 handlers.AppendFormat("\t{0}\n", s);
180
181 handlers.AppendFormat("* LLSD:\n");
182 foreach (String s in httpServer.GetLLSDHandlerKeys())
183 handlers.AppendFormat("\t{0}\n", s);
184
185 handlers.AppendFormat("* StreamHandlers ({0}):\n", httpServer.GetStreamHandlerKeys().Count);
186 foreach (String s in httpServer.GetStreamHandlerKeys())
187 handlers.AppendFormat("\t{0}\n", s);
188
189 handlers.Append("\n");
190 }
140 } 191 }
192
193 MainConsole.Instance.Output(handlers.ToString());
141 } 194 }
142 195
143 /// <summary> 196 /// <summary>
diff --git a/OpenSim/Framework/Servers/VersionInfo.cs b/OpenSim/Framework/Servers/VersionInfo.cs
index 016a174..bb094ed 100644
--- a/OpenSim/Framework/Servers/VersionInfo.cs
+++ b/OpenSim/Framework/Servers/VersionInfo.cs
@@ -29,7 +29,7 @@ namespace OpenSim
29{ 29{
30 public class VersionInfo 30 public class VersionInfo
31 { 31 {
32 private const string VERSION_NUMBER = "0.7.4CM"; 32 private const string VERSION_NUMBER = "0.7.5CM";
33 private const Flavour VERSION_FLAVOUR = Flavour.Dev; 33 private const Flavour VERSION_FLAVOUR = Flavour.Dev;
34 34
35 public enum Flavour 35 public enum Flavour
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs
index 384f716..a26e930 100644
--- a/OpenSim/Framework/Util.cs
+++ b/OpenSim/Framework/Util.cs
@@ -862,6 +862,12 @@ namespace OpenSim.Framework
862 return Math.Min(Math.Max(x, min), max); 862 return Math.Min(Math.Max(x, min), max);
863 } 863 }
864 864
865 public static Vector3 Clip(Vector3 vec, float min, float max)
866 {
867 return new Vector3(Clip(vec.X, min, max), Clip(vec.Y, min, max),
868 Clip(vec.Z, min, max));
869 }
870
865 /// <summary> 871 /// <summary>
866 /// Convert an UUID to a raw uuid string. Right now this is a string without hyphens. 872 /// Convert an UUID to a raw uuid string. Right now this is a string without hyphens.
867 /// </summary> 873 /// </summary>
@@ -1013,6 +1019,38 @@ namespace OpenSim.Framework
1013 } 1019 }
1014 } 1020 }
1015 1021
1022 /// <summary>
1023 /// Copy data from one stream to another, leaving the read position of both streams at the beginning.
1024 /// </summary>
1025 /// <param name='inputStream'>
1026 /// Input stream. Must be seekable.
1027 /// </param>
1028 /// <exception cref='ArgumentException'>
1029 /// Thrown if the input stream is not seekable.
1030 /// </exception>
1031 public static Stream Copy(Stream inputStream)
1032 {
1033 if (!inputStream.CanSeek)
1034 throw new ArgumentException("Util.Copy(Stream inputStream) must receive an inputStream that can seek");
1035
1036 const int readSize = 256;
1037 byte[] buffer = new byte[readSize];
1038 MemoryStream ms = new MemoryStream();
1039
1040 int count = inputStream.Read(buffer, 0, readSize);
1041
1042 while (count > 0)
1043 {
1044 ms.Write(buffer, 0, count);
1045 count = inputStream.Read(buffer, 0, readSize);
1046 }
1047
1048 ms.Position = 0;
1049 inputStream.Position = 0;
1050
1051 return ms;
1052 }
1053
1016 public static XmlRpcResponse XmlRpcCommand(string url, string methodName, params object[] args) 1054 public static XmlRpcResponse XmlRpcCommand(string url, string methodName, params object[] args)
1017 { 1055 {
1018 return SendXmlRpcCommand(url, methodName, args); 1056 return SendXmlRpcCommand(url, methodName, args);
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs
index 6255515..a9b2745 100644
--- a/OpenSim/Region/Application/OpenSim.cs
+++ b/OpenSim/Region/Application/OpenSim.cs
@@ -35,6 +35,7 @@ using System.Text;
35using System.Text.RegularExpressions; 35using System.Text.RegularExpressions;
36using System.Timers; 36using System.Timers;
37using log4net; 37using log4net;
38using NDesk.Options;
38using Nini.Config; 39using Nini.Config;
39using OpenMetaverse; 40using OpenMetaverse;
40using OpenSim.Framework; 41using OpenSim.Framework;
@@ -291,7 +292,7 @@ namespace OpenSim
291 292
292 m_console.Commands.AddCommand("Archiving", false, "save oar", 293 m_console.Commands.AddCommand("Archiving", false, "save oar",
293 //"save oar [-v|--version=<N>] [-p|--profile=<url>] [<OAR path>]", 294 //"save oar [-v|--version=<N>] [-p|--profile=<url>] [<OAR path>]",
294 "save oar [-h|--home=<url>] [--noassets] [--publish] [--perm=<permissions>] [<OAR path>]", 295 "save oar [-h|--home=<url>] [--noassets] [--publish] [--perm=<permissions>] [--all] [<OAR path>]",
295 "Save a region's data to an OAR archive.", 296 "Save a region's data to an OAR archive.",
296// "-v|--version=<N> generates scene objects as per older versions of the serialization (e.g. -v=0)" + Environment.NewLine 297// "-v|--version=<N> generates scene objects as per older versions of the serialization (e.g. -v=0)" + Environment.NewLine
297 "-h|--home=<url> adds the url of the profile service to the saved user information.\n" 298 "-h|--home=<url> adds the url of the profile service to the saved user information.\n"
@@ -301,6 +302,7 @@ namespace OpenSim
301 + " this is useful if you're making oars generally available that might be reloaded to the same grid from which you published\n" 302 + " this is useful if you're making oars generally available that might be reloaded to the same grid from which you published\n"
302 + "--perm=<permissions> stops objects with insufficient permissions from being saved to the OAR.\n" 303 + "--perm=<permissions> stops objects with insufficient permissions from being saved to the OAR.\n"
303 + " <permissions> can contain one or more of these characters: \"C\" = Copy, \"T\" = Transfer\n" 304 + " <permissions> can contain one or more of these characters: \"C\" = Copy, \"T\" = Transfer\n"
305 + "--all saves all the regions in the simulator, instead of just the current region.\n"
304 + "The OAR path must be a filesystem path." 306 + "The OAR path must be a filesystem path."
305 + " If this is not given then the oar is saved to region.oar in the current directory.", 307 + " If this is not given then the oar is saved to region.oar in the current directory.",
306 SaveOar); 308 SaveOar);
@@ -310,8 +312,11 @@ namespace OpenSim
310 "Change the scale of a named prim", HandleEditScale); 312 "Change the scale of a named prim", HandleEditScale);
311 313
312 m_console.Commands.AddCommand("Users", false, "kick user", 314 m_console.Commands.AddCommand("Users", false, "kick user",
313 "kick user <first> <last> [message]", 315 "kick user <first> <last> [--force] [message]",
314 "Kick a user off the simulator", KickUserCommand); 316 "Kick a user off the simulator",
317 "The --force option will kick the user without any checks to see whether it's already in the process of closing\n"
318 + "Only use this option if you are sure the avatar is inactive and a normal kick user operation does not removed them",
319 KickUserCommand);
315 320
316 m_console.Commands.AddCommand("Users", false, "show users", 321 m_console.Commands.AddCommand("Users", false, "show users",
317 "show users [full]", 322 "show users [full]",
@@ -328,10 +333,6 @@ namespace OpenSim
328 "show circuits", 333 "show circuits",
329 "Show agent circuit data", HandleShow); 334 "Show agent circuit data", HandleShow);
330 335
331 m_console.Commands.AddCommand("Comms", false, "show http-handlers",
332 "show http-handlers",
333 "Show all registered http handlers", HandleShow);
334
335 m_console.Commands.AddCommand("Comms", false, "show pending-objects", 336 m_console.Commands.AddCommand("Comms", false, "show pending-objects",
336 "show pending-objects", 337 "show pending-objects",
337 "Show # of objects on the pending queues of all scene viewers", HandleShow); 338 "Show # of objects on the pending queues of all scene viewers", HandleShow);
@@ -416,6 +417,7 @@ namespace OpenSim
416 { 417 {
417 RunCommandScript(m_shutdownCommandsFile); 418 RunCommandScript(m_shutdownCommandsFile);
418 } 419 }
420
419 base.ShutdownSpecific(); 421 base.ShutdownSpecific();
420 } 422 }
421 423
@@ -453,11 +455,17 @@ namespace OpenSim
453 /// <param name="cmdparams">name of avatar to kick</param> 455 /// <param name="cmdparams">name of avatar to kick</param>
454 private void KickUserCommand(string module, string[] cmdparams) 456 private void KickUserCommand(string module, string[] cmdparams)
455 { 457 {
456 if (cmdparams.Length < 4) 458 bool force = false;
459
460 OptionSet options = new OptionSet().Add("f|force", delegate (string v) { force = v != null; });
461
462 List<string> mainParams = options.Parse(cmdparams);
463
464 if (mainParams.Count < 4)
457 return; 465 return;
458 466
459 string alert = null; 467 string alert = null;
460 if (cmdparams.Length > 4) 468 if (mainParams.Count > 4)
461 alert = String.Format("\n{0}\n", String.Join(" ", cmdparams, 4, cmdparams.Length - 4)); 469 alert = String.Format("\n{0}\n", String.Join(" ", cmdparams, 4, cmdparams.Length - 4));
462 470
463 IList agents = SceneManager.GetCurrentSceneAvatars(); 471 IList agents = SceneManager.GetCurrentSceneAvatars();
@@ -466,8 +474,8 @@ namespace OpenSim
466 { 474 {
467 RegionInfo regionInfo = presence.Scene.RegionInfo; 475 RegionInfo regionInfo = presence.Scene.RegionInfo;
468 476
469 if (presence.Firstname.ToLower().Contains(cmdparams[2].ToLower()) && 477 if (presence.Firstname.ToLower().Contains(mainParams[2].ToLower()) &&
470 presence.Lastname.ToLower().Contains(cmdparams[3].ToLower())) 478 presence.Lastname.ToLower().Contains(mainParams[3].ToLower()))
471 { 479 {
472 MainConsole.Instance.Output( 480 MainConsole.Instance.Output(
473 String.Format( 481 String.Format(
@@ -480,7 +488,7 @@ namespace OpenSim
480 else 488 else
481 presence.ControllingClient.Kick("\nYou have been logged out by an administrator.\n"); 489 presence.ControllingClient.Kick("\nYou have been logged out by an administrator.\n");
482 490
483 presence.Scene.IncomingCloseAgent(presence.UUID); 491 presence.Scene.IncomingCloseAgent(presence.UUID, force);
484 } 492 }
485 } 493 }
486 494
@@ -1002,33 +1010,6 @@ namespace OpenSim
1002 HandleShowCircuits(); 1010 HandleShowCircuits();
1003 break; 1011 break;
1004 1012
1005 case "http-handlers":
1006 System.Text.StringBuilder handlers = new System.Text.StringBuilder("Registered HTTP Handlers:\n");
1007
1008 handlers.AppendFormat("* XMLRPC:\n");
1009 foreach (String s in HttpServer.GetXmlRpcHandlerKeys())
1010 handlers.AppendFormat("\t{0}\n", s);
1011
1012 handlers.AppendFormat("* HTTP:\n");
1013 List<String> poll = HttpServer.GetPollServiceHandlerKeys();
1014 foreach (String s in HttpServer.GetHTTPHandlerKeys())
1015 handlers.AppendFormat("\t{0} {1}\n", s, (poll.Contains(s) ? "(poll service)" : string.Empty));
1016
1017 handlers.AppendFormat("* Agent:\n");
1018 foreach (String s in HttpServer.GetAgentHandlerKeys())
1019 handlers.AppendFormat("\t{0}\n", s);
1020
1021 handlers.AppendFormat("* LLSD:\n");
1022 foreach (String s in HttpServer.GetLLSDHandlerKeys())
1023 handlers.AppendFormat("\t{0}\n", s);
1024
1025 handlers.AppendFormat("* StreamHandlers ({0}):\n", HttpServer.GetStreamHandlerKeys().Count);
1026 foreach (String s in HttpServer.GetStreamHandlerKeys())
1027 handlers.AppendFormat("\t{0}\n", s);
1028
1029 MainConsole.Instance.Output(handlers.ToString());
1030 break;
1031
1032 case "modules": 1013 case "modules":
1033 MainConsole.Instance.Output("The currently loaded shared modules are:"); 1014 MainConsole.Instance.Output("The currently loaded shared modules are:");
1034 foreach (IRegionModule module in m_moduleLoader.GetLoadedSharedModules) 1015 foreach (IRegionModule module in m_moduleLoader.GetLoadedSharedModules)
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
index cd70410..d604cf6 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
@@ -94,7 +94,7 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
94 UUID spId = TestHelpers.ParseTail(0x1); 94 UUID spId = TestHelpers.ParseTail(0x1);
95 95
96 SceneHelpers.AddScenePresence(m_scene, spId); 96 SceneHelpers.AddScenePresence(m_scene, spId);
97 m_scene.IncomingCloseAgent(spId); 97 m_scene.IncomingCloseAgent(spId, false);
98 98
99 // TODO: Add more assertions for the other aspects of event queues 99 // TODO: Add more assertions for the other aspects of event queues
100 Assert.That(MainServer.Instance.GetPollServiceHandlerKeys().Count, Is.EqualTo(0)); 100 Assert.That(MainServer.Instance.GetPollServiceHandlerKeys().Count, Is.EqualTo(0));
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 7749ef3..74b27d7 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -509,19 +509,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
509 /// </summary> 509 /// </summary>
510 public void Close() 510 public void Close()
511 { 511 {
512 Close(true); 512 Close(true, false);
513 } 513 }
514 514
515 /// <summary> 515 public void Close(bool sendStop, bool force)
516 /// Shut down the client view
517 /// </summary>
518 public void Close(bool sendStop)
519 { 516 {
520 // We lock here to prevent race conditions between two threads calling close simultaneously (e.g. 517 // We lock here to prevent race conditions between two threads calling close simultaneously (e.g.
521 // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection. 518 // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection.
522 lock (CloseSyncLock) 519 lock (CloseSyncLock)
523 { 520 {
524 if (!IsActive) 521 // We still perform a force close inside the sync lock since this is intended to attempt close where
522 // there is some unidentified connection problem, not where we have issues due to deadlock
523 if (!IsActive && !force)
525 return; 524 return;
526 525
527 IsActive = false; 526 IsActive = false;
@@ -4528,7 +4527,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4528 { 4527 {
4529 returnblock[j] = new EstateOwnerMessagePacket.ParamListBlock(); 4528 returnblock[j] = new EstateOwnerMessagePacket.ParamListBlock();
4530 } 4529 }
4531 j = 0; 4530 j = 0;
4532 4531
4533 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++; 4532 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++;
4534 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++; 4533 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++;
@@ -12187,7 +12186,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12187 { 12186 {
12188 Kick(reason); 12187 Kick(reason);
12189 Thread.Sleep(1000); 12188 Thread.Sleep(1000);
12190 Close(); 12189 Disconnect();
12191 } 12190 }
12192 12191
12193 public void Disconnect() 12192 public void Disconnect()
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index d6513c5..60ab70e 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -1523,7 +1523,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1523 if (!client.IsLoggingOut) 1523 if (!client.IsLoggingOut)
1524 { 1524 {
1525 client.IsLoggingOut = true; 1525 client.IsLoggingOut = true;
1526 client.Close(false); 1526 client.Close(false, false);
1527 } 1527 }
1528 } 1528 }
1529 } 1529 }
diff --git a/OpenSim/Region/ClientStack/RegionApplicationBase.cs b/OpenSim/Region/ClientStack/RegionApplicationBase.cs
index 4672f8a..853b72d 100644
--- a/OpenSim/Region/ClientStack/RegionApplicationBase.cs
+++ b/OpenSim/Region/ClientStack/RegionApplicationBase.cs
@@ -76,7 +76,7 @@ namespace OpenSim.Region.ClientStack
76 76
77 protected override void StartupSpecific() 77 protected override void StartupSpecific()
78 { 78 {
79 SceneManager = new SceneManager(); 79 SceneManager = SceneManager.Instance;
80 m_clientStackManager = CreateClientStackManager(); 80 m_clientStackManager = CreateClientStackManager();
81 81
82 Initialize(); 82 Initialize();
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
index 7d7176f..d1a563c 100644
--- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
@@ -52,7 +52,7 @@ using OpenSim.Services.Interfaces;
52[assembly: Addin("FlotsamAssetCache", "1.1")] 52[assembly: Addin("FlotsamAssetCache", "1.1")]
53[assembly: AddinDependency("OpenSim", "0.5")] 53[assembly: AddinDependency("OpenSim", "0.5")]
54 54
55namespace Flotsam.RegionModules.AssetCache 55namespace OpenSim.Region.CoreModules.Asset
56{ 56{
57 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] 57 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
58 public class FlotsamAssetCache : ISharedRegionModule, IImprovedAssetCache, IAssetService 58 public class FlotsamAssetCache : ISharedRegionModule, IImprovedAssetCache, IAssetService
@@ -107,8 +107,6 @@ namespace Flotsam.RegionModules.AssetCache
107 private IAssetService m_AssetService; 107 private IAssetService m_AssetService;
108 private List<Scene> m_Scenes = new List<Scene>(); 108 private List<Scene> m_Scenes = new List<Scene>();
109 109
110 private bool m_DeepScanBeforePurge;
111
112 public FlotsamAssetCache() 110 public FlotsamAssetCache()
113 { 111 {
114 m_InvalidChars.AddRange(Path.GetInvalidPathChars()); 112 m_InvalidChars.AddRange(Path.GetInvalidPathChars());
@@ -170,8 +168,6 @@ namespace Flotsam.RegionModules.AssetCache
170 m_CacheDirectoryTierLen = assetConfig.GetInt("CacheDirectoryTierLength", m_CacheDirectoryTierLen); 168 m_CacheDirectoryTierLen = assetConfig.GetInt("CacheDirectoryTierLength", m_CacheDirectoryTierLen);
171 169
172 m_CacheWarnAt = assetConfig.GetInt("CacheWarnAt", m_CacheWarnAt); 170 m_CacheWarnAt = assetConfig.GetInt("CacheWarnAt", m_CacheWarnAt);
173
174 m_DeepScanBeforePurge = assetConfig.GetBoolean("DeepScanBeforePurge", m_DeepScanBeforePurge);
175 } 171 }
176 172
177 m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Cache Directory {0}", m_CacheDirectory); 173 m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Cache Directory {0}", m_CacheDirectory);
@@ -519,13 +515,10 @@ namespace Flotsam.RegionModules.AssetCache
519 // Purge all files last accessed prior to this point 515 // Purge all files last accessed prior to this point
520 DateTime purgeLine = DateTime.Now - m_FileExpiration; 516 DateTime purgeLine = DateTime.Now - m_FileExpiration;
521 517
522 // An optional deep scan at this point will ensure assets present in scenes, 518 // An asset cache may contain local non-temporary assets that are not in the asset service. Therefore,
523 // or referenced by objects in the scene, but not recently accessed 519 // before cleaning up expired files we must scan the objects in the scene to make sure that we retain
524 // are not purged. 520 // such local assets if they have not been recently accessed.
525 if (m_DeepScanBeforePurge) 521 TouchAllSceneAssets(false);
526 {
527 CacheScenes();
528 }
529 522
530 foreach (string dir in Directory.GetDirectories(m_CacheDirectory)) 523 foreach (string dir in Directory.GetDirectories(m_CacheDirectory))
531 { 524 {
@@ -718,11 +711,14 @@ namespace Flotsam.RegionModules.AssetCache
718 711
719 /// <summary> 712 /// <summary>
720 /// Iterates through all Scenes, doing a deep scan through assets 713 /// Iterates through all Scenes, doing a deep scan through assets
721 /// to cache all assets present in the scene or referenced by assets 714 /// to update the access time of all assets present in the scene or referenced by assets
722 /// in the scene 715 /// in the scene.
723 /// </summary> 716 /// </summary>
724 /// <returns></returns> 717 /// <param name="storeUncached">
725 private int CacheScenes() 718 /// If true, then assets scanned which are not found in cache are added to the cache.
719 /// </param>
720 /// <returns>Number of distinct asset references found in the scene.</returns>
721 private int TouchAllSceneAssets(bool storeUncached)
726 { 722 {
727 UuidGatherer gatherer = new UuidGatherer(m_AssetService); 723 UuidGatherer gatherer = new UuidGatherer(m_AssetService);
728 724
@@ -745,7 +741,7 @@ namespace Flotsam.RegionModules.AssetCache
745 { 741 {
746 File.SetLastAccessTime(filename, DateTime.Now); 742 File.SetLastAccessTime(filename, DateTime.Now);
747 } 743 }
748 else 744 else if (storeUncached)
749 { 745 {
750 m_AssetService.Get(assetID.ToString()); 746 m_AssetService.Get(assetID.ToString());
751 } 747 }
@@ -873,13 +869,14 @@ namespace Flotsam.RegionModules.AssetCache
873 869
874 break; 870 break;
875 871
876
877 case "assets": 872 case "assets":
878 m_log.Info("[FLOTSAM ASSET CACHE]: Caching all assets, in all scenes."); 873 m_log.Info("[FLOTSAM ASSET CACHE]: Ensuring assets are cached for all scenes.");
879 874
880 Util.FireAndForget(delegate { 875 Util.FireAndForget(delegate {
881 int assetsCached = CacheScenes(); 876 int assetReferenceTotal = TouchAllSceneAssets(true);
882 m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Completed Scene Caching, {0} assets found.", assetsCached); 877 m_log.InfoFormat(
878 "[FLOTSAM ASSET CACHE]: Completed check with {0} assets.",
879 assetReferenceTotal);
883 }); 880 });
884 881
885 break; 882 break;
diff --git a/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs b/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs
index c91b25f..1c2bfd0 100644
--- a/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs
+++ b/OpenSim/Region/CoreModules/Asset/Tests/FlotsamAssetCacheTests.cs
@@ -35,7 +35,6 @@ using Nini.Config;
35using NUnit.Framework; 35using NUnit.Framework;
36using OpenMetaverse; 36using OpenMetaverse;
37using OpenMetaverse.Assets; 37using OpenMetaverse.Assets;
38using Flotsam.RegionModules.AssetCache;
39using OpenSim.Framework; 38using OpenSim.Framework;
40using OpenSim.Region.Framework.Scenes; 39using OpenSim.Region.Framework.Scenes;
41using OpenSim.Region.Framework.Scenes.Serialization; 40using OpenSim.Region.Framework.Scenes.Serialization;
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
index d9a619d..48f3a23 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
@@ -461,7 +461,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
461 461
462 SceneObjectGroup rezzedAtt = presence.GetAttachments()[0]; 462 SceneObjectGroup rezzedAtt = presence.GetAttachments()[0];
463 463
464 scene.IncomingCloseAgent(presence.UUID); 464 scene.IncomingCloseAgent(presence.UUID, false);
465 465
466 // Check that we can't retrieve this attachment from the scene. 466 // Check that we can't retrieve this attachment from the scene.
467 Assert.That(scene.GetSceneObjectGroup(rezzedAtt.UUID), Is.Null); 467 Assert.That(scene.GetSceneObjectGroup(rezzedAtt.UUID), Is.Null);
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
index 24ec435..11db18a 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
@@ -482,9 +482,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
482 Util.FireAndForget( 482 Util.FireAndForget(
483 delegate 483 delegate
484 { 484 {
485 m_log.DebugFormat( 485// m_log.DebugFormat(
486 "[FRIENDS MODULE]: Notifying {0} friends of {1} of online status {2}", 486// "[FRIENDS MODULE]: Notifying {0} friends of {1} of online status {2}",
487 friendList.Count, agentID, online); 487// friendList.Count, agentID, online);
488 488
489 // Notify about this user status 489 // Notify about this user status
490 StatusNotify(friendList, agentID, online); 490 StatusNotify(friendList, agentID, online);
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
index b112b6d..12a05b3 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
@@ -350,38 +350,38 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
350 Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL1.PrincipalID)); 350 Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL1.PrincipalID));
351 } 351 }
352 352
353 /// <summary> 353// /// <summary>
354 /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where 354// /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where
355 /// an account exists with the same name as the creator, though not the same id. 355// /// an account exists with the same name as the creator, though not the same id.
356 /// </summary> 356// /// </summary>
357 [Test] 357// [Test]
358 public void TestLoadIarV0_1SameNameCreator() 358// public void TestLoadIarV0_1SameNameCreator()
359 { 359// {
360 TestHelpers.InMethod(); 360// TestHelpers.InMethod();
361// log4net.Config.XmlConfigurator.Configure(); 361// TestHelpers.EnableLogging();
362 362//
363 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "meowfood"); 363// UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "meowfood");
364 UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL2, "hampshire"); 364// UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL2, "hampshire");
365 365//
366 m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream); 366// m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream);
367 InventoryItemBase foundItem1 367// InventoryItemBase foundItem1
368 = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name); 368// = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name);
369 369//
370 Assert.That( 370// Assert.That(
371 foundItem1.CreatorId, Is.EqualTo(m_uaLL2.PrincipalID.ToString()), 371// foundItem1.CreatorId, Is.EqualTo(m_uaLL2.PrincipalID.ToString()),
372 "Loaded item non-uuid creator doesn't match original"); 372// "Loaded item non-uuid creator doesn't match original");
373 Assert.That( 373// Assert.That(
374 foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaLL2.PrincipalID), 374// foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaLL2.PrincipalID),
375 "Loaded item uuid creator doesn't match original"); 375// "Loaded item uuid creator doesn't match original");
376 Assert.That(foundItem1.Owner, Is.EqualTo(m_uaMT.PrincipalID), 376// Assert.That(foundItem1.Owner, Is.EqualTo(m_uaMT.PrincipalID),
377 "Loaded item owner doesn't match inventory reciever"); 377// "Loaded item owner doesn't match inventory reciever");
378 378//
379 AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString()); 379// AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString());
380 string xmlData = Utils.BytesToString(asset1.Data); 380// string xmlData = Utils.BytesToString(asset1.Data);
381 SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); 381// SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
382 382//
383 Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL2.PrincipalID)); 383// Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL2.PrincipalID));
384 } 384// }
385 385
386 /// <summary> 386 /// <summary>
387 /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where 387 /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index 9090f64..1f62743 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -327,6 +327,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
327 return; 327 return;
328 } 328 }
329 329
330 // Validate assorted conditions
331 string reason = string.Empty;
332 if (!ValidateGenericConditions(sp, reg, finalDestination, teleportFlags, out reason))
333 {
334 sp.ControllingClient.SendTeleportFailed(reason);
335 return;
336 }
337
330 // 338 //
331 // This is it 339 // This is it
332 // 340 //
@@ -358,6 +366,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
358 } 366 }
359 } 367 }
360 368
369 // Nothing to validate here
370 protected virtual bool ValidateGenericConditions(ScenePresence sp, GridRegion reg, GridRegion finalDestination, uint teleportFlags, out string reason)
371 {
372 reason = String.Empty;
373 return true;
374 }
375
361 /// <summary> 376 /// <summary>
362 /// Determines whether this instance is within the max transfer distance. 377 /// Determines whether this instance is within the max transfer distance.
363 /// </summary> 378 /// </summary>
@@ -574,7 +589,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
574 589
575 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent..."); 590 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent...");
576 591
577 if (!UpdateAgent(reg, finalDestination, agent)) 592 if (!UpdateAgent(reg, finalDestination, agent, sp))
578 { 593 {
579 // Region doesn't take it 594 // Region doesn't take it
580 m_log.WarnFormat( 595 m_log.WarnFormat(
@@ -650,7 +665,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
650 // an agent cannot teleport back to this region if it has teleported away. 665 // an agent cannot teleport back to this region if it has teleported away.
651 Thread.Sleep(2000); 666 Thread.Sleep(2000);
652 667
653 sp.Scene.IncomingCloseAgent(sp.UUID); 668 sp.Scene.IncomingCloseAgent(sp.UUID, false);
654 } 669 }
655 else 670 else
656 { 671 {
@@ -701,7 +716,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
701 return success; 716 return success;
702 } 717 }
703 718
704 protected virtual bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agent) 719 protected virtual bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agent, ScenePresence sp)
705 { 720 {
706 return Scene.SimulationService.UpdateAgent(finalDestination, agent); 721 return Scene.SimulationService.UpdateAgent(finalDestination, agent);
707 } 722 }
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
index 3010b59..0f1a381 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
@@ -54,6 +54,47 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
54 54
55 private GatekeeperServiceConnector m_GatekeeperConnector; 55 private GatekeeperServiceConnector m_GatekeeperConnector;
56 56
57 protected bool m_RestrictAppearanceAbroad;
58 protected string m_AccountName;
59 protected AvatarAppearance m_ExportedAppearance;
60
61 protected AvatarAppearance ExportedAppearance
62 {
63 get
64 {
65 if (m_ExportedAppearance != null)
66 return m_ExportedAppearance;
67
68 string[] parts = m_AccountName.Split();
69 if (parts.Length != 2)
70 {
71 m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: Wrong user account name format {0}. Specify 'First Last'", m_AccountName);
72 return null;
73 }
74 UserAccount account = Scene.UserAccountService.GetUserAccount(UUID.Zero, parts[0], parts[1]);
75 if (account == null)
76 {
77 m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: Unknown account {0}", m_AccountName);
78 return null;
79 }
80 m_ExportedAppearance = Scene.AvatarService.GetAppearance(account.PrincipalID);
81 if (m_ExportedAppearance != null)
82 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Successfully retrieved appearance for {0}", m_AccountName);
83
84 foreach (AvatarAttachment att in m_ExportedAppearance.GetAttachments())
85 {
86 InventoryItemBase item = new InventoryItemBase(att.ItemID, account.PrincipalID);
87 item = Scene.InventoryService.GetItem(item);
88 if (item != null)
89 m_ExportedAppearance.SetAttachment(att.AttachPoint, att.ItemID, item.AssetID);
90 else
91 m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: Unable to retrieve item {0} from inventory", att.ItemID);
92 }
93 return m_ExportedAppearance;
94 }
95 }
96
97
57 #region ISharedRegionModule 98 #region ISharedRegionModule
58 99
59 public override string Name 100 public override string Name
@@ -72,8 +113,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
72 { 113 {
73 IConfig transferConfig = source.Configs["EntityTransfer"]; 114 IConfig transferConfig = source.Configs["EntityTransfer"];
74 if (transferConfig != null) 115 if (transferConfig != null)
116 {
75 m_levelHGTeleport = transferConfig.GetInt("LevelHGTeleport", 0); 117 m_levelHGTeleport = transferConfig.GetInt("LevelHGTeleport", 0);
76 118
119 m_RestrictAppearanceAbroad = transferConfig.GetBoolean("RestrictAppearanceAbroad", false);
120 if (m_RestrictAppearanceAbroad)
121 {
122 m_AccountName = transferConfig.GetString("AccountForAppearance", string.Empty);
123 if (m_AccountName == string.Empty)
124 m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: RestrictAppearanceAbroad is on, but no account has been given for avatar appearance!");
125 }
126 }
127
77 InitialiseCommon(source); 128 InitialiseCommon(source);
78 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: {0} enabled.", Name); 129 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: {0} enabled.", Name);
79 } 130 }
@@ -200,6 +251,109 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
200 TeleportHome(id, client); 251 TeleportHome(id, client);
201 } 252 }
202 253
254 protected override bool ValidateGenericConditions(ScenePresence sp, GridRegion reg, GridRegion finalDestination, uint teleportFlags, out string reason)
255 {
256 reason = "Please wear your grid's allowed appearance before teleporting to another grid";
257 if (!m_RestrictAppearanceAbroad)
258 return true;
259
260 // The rest is only needed for controlling appearance
261
262 int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, reg.RegionID);
263 if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0)
264 {
265 // this user is going to another grid
266 if (Scene.UserManagementModule.IsLocalGridUser(sp.UUID))
267 {
268 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: RestrictAppearanceAbroad is ON. Checking generic appearance");
269
270 // Check wearables
271 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
272 {
273 for (int j = 0; j < sp.Appearance.Wearables[i].Count; j++)
274 {
275 if (sp.Appearance.Wearables[i] == null)
276 continue;
277
278 if (ExportedAppearance.Wearables[i] == null)
279 {
280 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Wearable not allowed to go outside {0}", i);
281 return false;
282 }
283
284 if (sp.Appearance.Wearables[i][j].AssetID != ExportedAppearance.Wearables[i][j].AssetID)
285 {
286 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Wearable not allowed to go outside {0}", i);
287 return false;
288 }
289 }
290 }
291
292 // Check attachments
293
294 foreach (AvatarAttachment att in sp.Appearance.GetAttachments())
295 {
296 bool found = false;
297 foreach (AvatarAttachment att2 in ExportedAppearance.GetAttachments())
298 {
299 if (att2.AssetID == att.AssetID)
300 {
301 found = true;
302 break;
303 }
304 }
305 if (!found)
306 {
307 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Attachment not allowed to go outside {0}", att.AttachPoint);
308 return false;
309 }
310 }
311 }
312 }
313
314 reason = string.Empty;
315 return true;
316 }
317
318
319 //protected override bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agentData, ScenePresence sp)
320 //{
321 // int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, reg.RegionID);
322 // if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0)
323 // {
324 // // this user is going to another grid
325 // if (m_RestrictAppearanceAbroad && Scene.UserManagementModule.IsLocalGridUser(agentData.AgentID))
326 // {
327 // // We need to strip the agent off its appearance
328 // m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: RestrictAppearanceAbroad is ON. Sending generic appearance");
329
330 // // Delete existing npc attachments
331 // Scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, false);
332
333 // // XXX: We can't just use IAvatarFactoryModule.SetAppearance() yet since it doesn't transfer attachments
334 // AvatarAppearance newAppearance = new AvatarAppearance(ExportedAppearance, true);
335 // sp.Appearance = newAppearance;
336
337 // // Rez needed npc attachments
338 // Scene.AttachmentsModule.RezAttachments(sp);
339
340
341 // IAvatarFactoryModule module = Scene.RequestModuleInterface<IAvatarFactoryModule>();
342 // //module.SendAppearance(sp.UUID);
343 // module.RequestRebake(sp, false);
344
345 // Scene.AttachmentsModule.CopyAttachments(sp, agentData);
346 // agentData.Appearance = sp.Appearance;
347 // }
348 // }
349
350 // foreach (AvatarAttachment a in agentData.Appearance.GetAttachments())
351 // m_log.DebugFormat("[XXX]: {0}-{1}", a.ItemID, a.AssetID);
352
353
354 // return base.UpdateAgent(reg, finalDestination, agentData, sp);
355 //}
356
203 public override bool TeleportHome(UUID id, IClientAPI client) 357 public override bool TeleportHome(UUID id, IClientAPI client)
204 { 358 {
205 m_log.DebugFormat( 359 m_log.DebugFormat(
@@ -375,4 +529,4 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
375 return region; 529 return region;
376 } 530 }
377 } 531 }
378} \ No newline at end of file 532}
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
index cf72b58..a0cad40 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
@@ -308,6 +308,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
308 protected override InventoryItemBase GetItem(UUID agentID, UUID itemID) 308 protected override InventoryItemBase GetItem(UUID agentID, UUID itemID)
309 { 309 {
310 InventoryItemBase item = base.GetItem(agentID, itemID); 310 InventoryItemBase item = base.GetItem(agentID, itemID);
311 if (item == null)
312 return null;
311 313
312 string userAssetServer = string.Empty; 314 string userAssetServer = string.Empty;
313 if (IsForeignUser(agentID, out userAssetServer)) 315 if (IsForeignUser(agentID, out userAssetServer))
diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTexture.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTexture.cs
new file mode 100644
index 0000000..fce9490
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTexture.cs
@@ -0,0 +1,61 @@
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.Drawing;
30using OpenSim.Region.Framework.Interfaces;
31
32namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
33{
34 public class DynamicTexture : IDynamicTexture
35 {
36 public string InputCommands { get; private set; }
37 public Uri InputUri { get; private set; }
38 public string InputParams { get; private set; }
39 public byte[] Data { get; private set; }
40 public Size Size { get; private set; }
41 public bool IsReuseable { get; private set; }
42
43 public DynamicTexture(string inputCommands, string inputParams, byte[] data, Size size, bool isReuseable)
44 {
45 InputCommands = inputCommands;
46 InputParams = inputParams;
47 Data = data;
48 Size = size;
49 IsReuseable = isReuseable;
50 }
51
52 public DynamicTexture(Uri inputUri, string inputParams, byte[] data, Size size, bool isReuseable)
53 {
54 InputUri = inputUri;
55 InputParams = inputParams;
56 Data = data;
57 Size = size;
58 IsReuseable = isReuseable;
59 }
60 }
61} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs
index 18bd018..1f340df 100644
--- a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs
@@ -42,13 +42,29 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
42{ 42{
43 public class DynamicTextureModule : IRegionModule, IDynamicTextureManager 43 public class DynamicTextureModule : IRegionModule, IDynamicTextureManager
44 { 44 {
45 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46 46
47 private const int ALL_SIDES = -1; 47 private const int ALL_SIDES = -1;
48 48
49 public const int DISP_EXPIRE = 1; 49 public const int DISP_EXPIRE = 1;
50 public const int DISP_TEMP = 2; 50 public const int DISP_TEMP = 2;
51 51
52 /// <summary>
53 /// If true then where possible dynamic textures are reused.
54 /// </summary>
55 public bool ReuseTextures { get; set; }
56
57 /// <summary>
58 /// If false, then textures which have a low data size are not reused when ReuseTextures = true.
59 /// </summary>
60 /// <remarks>
61 /// LL viewers 3.3.4 and before appear to not fully render textures pulled from the viewer cache if those
62 /// textures have a relatively high pixel surface but a small data size. Typically, this appears to happen
63 /// if the data size is smaller than the viewer's discard level 2 size estimate. So if this is setting is
64 /// false, textures smaller than the calculation in IsSizeReuseable are always regenerated rather than reused
65 /// to work around this problem.</remarks>
66 public bool ReuseLowDataTextures { get; set; }
67
52 private Dictionary<UUID, Scene> RegisteredScenes = new Dictionary<UUID, Scene>(); 68 private Dictionary<UUID, Scene> RegisteredScenes = new Dictionary<UUID, Scene>();
53 69
54 private Dictionary<string, IDynamicTextureRender> RenderPlugins = 70 private Dictionary<string, IDynamicTextureRender> RenderPlugins =
@@ -56,6 +72,15 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
56 72
57 private Dictionary<UUID, DynamicTextureUpdater> Updaters = new Dictionary<UUID, DynamicTextureUpdater>(); 73 private Dictionary<UUID, DynamicTextureUpdater> Updaters = new Dictionary<UUID, DynamicTextureUpdater>();
58 74
75 /// <summary>
76 /// Record dynamic textures that we can reuse for a given data and parameter combination rather than
77 /// regenerate.
78 /// </summary>
79 /// <remarks>
80 /// Key is string.Format("{0}{1}", data
81 /// </remarks>
82 private Cache m_reuseableDynamicTextures;
83
59 #region IDynamicTextureManager Members 84 #region IDynamicTextureManager Members
60 85
61 public void RegisterRender(string handleType, IDynamicTextureRender render) 86 public void RegisterRender(string handleType, IDynamicTextureRender render)
@@ -69,17 +94,17 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
69 /// <summary> 94 /// <summary>
70 /// Called by code which actually renders the dynamic texture to supply texture data. 95 /// Called by code which actually renders the dynamic texture to supply texture data.
71 /// </summary> 96 /// </summary>
72 /// <param name="id"></param> 97 /// <param name="updaterId"></param>
73 /// <param name="data"></param> 98 /// <param name="texture"></param>
74 public void ReturnData(UUID id, byte[] data) 99 public void ReturnData(UUID updaterId, IDynamicTexture texture)
75 { 100 {
76 DynamicTextureUpdater updater = null; 101 DynamicTextureUpdater updater = null;
77 102
78 lock (Updaters) 103 lock (Updaters)
79 { 104 {
80 if (Updaters.ContainsKey(id)) 105 if (Updaters.ContainsKey(updaterId))
81 { 106 {
82 updater = Updaters[id]; 107 updater = Updaters[updaterId];
83 } 108 }
84 } 109 }
85 110
@@ -88,7 +113,16 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
88 if (RegisteredScenes.ContainsKey(updater.SimUUID)) 113 if (RegisteredScenes.ContainsKey(updater.SimUUID))
89 { 114 {
90 Scene scene = RegisteredScenes[updater.SimUUID]; 115 Scene scene = RegisteredScenes[updater.SimUUID];
91 updater.DataReceived(data, scene); 116 UUID newTextureID = updater.DataReceived(texture.Data, scene);
117
118 if (ReuseTextures
119 && !updater.BlendWithOldTexture
120 && texture.IsReuseable
121 && (ReuseLowDataTextures || IsDataSizeReuseable(texture)))
122 {
123 m_reuseableDynamicTextures.Store(
124 GenerateReusableTextureKey(texture.InputCommands, texture.InputParams), newTextureID);
125 }
92 } 126 }
93 } 127 }
94 128
@@ -104,6 +138,27 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
104 } 138 }
105 } 139 }
106 140
141 /// <summary>
142 /// Determines whether the texture is reuseable based on its data size.
143 /// </summary>
144 /// <remarks>
145 /// This is a workaround for a viewer bug where very small data size textures relative to their pixel size
146 /// are not redisplayed properly when pulled from cache. The calculation here is based on the typical discard
147 /// level of 2, a 'rate' of 0.125 and 4 components (which makes for a factor of 0.5).
148 /// </remarks>
149 /// <returns></returns>
150 private bool IsDataSizeReuseable(IDynamicTexture texture)
151 {
152// Console.WriteLine("{0} {1}", texture.Size.Width, texture.Size.Height);
153 int discardLevel2DataThreshold = (int)Math.Ceiling((texture.Size.Width >> 2) * (texture.Size.Height >> 2) * 0.5);
154
155// m_log.DebugFormat(
156// "[DYNAMIC TEXTURE MODULE]: Discard level 2 threshold {0}, texture data length {1}",
157// discardLevel2DataThreshold, texture.Data.Length);
158
159 return discardLevel2DataThreshold < texture.Data.Length;
160 }
161
107 public UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, 162 public UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url,
108 string extraParams, int updateTimer) 163 string extraParams, int updateTimer)
109 { 164 {
@@ -167,22 +222,61 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
167 public UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, 222 public UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data,
168 string extraParams, int updateTimer, bool SetBlending, int disp, byte AlphaValue, int face) 223 string extraParams, int updateTimer, bool SetBlending, int disp, byte AlphaValue, int face)
169 { 224 {
170 if (RenderPlugins.ContainsKey(contentType)) 225 if (!RenderPlugins.ContainsKey(contentType))
226 return UUID.Zero;
227
228 Scene scene;
229 RegisteredScenes.TryGetValue(simID, out scene);
230
231 if (scene == null)
232 return UUID.Zero;
233
234 SceneObjectPart part = scene.GetSceneObjectPart(primID);
235
236 if (part == null)
237 return UUID.Zero;
238
239 // If we want to reuse dynamic textures then we have to ignore any request from the caller to expire
240 // them.
241 if (ReuseTextures)
242 disp = disp & ~DISP_EXPIRE;
243
244 DynamicTextureUpdater updater = new DynamicTextureUpdater();
245 updater.SimUUID = simID;
246 updater.PrimID = primID;
247 updater.ContentType = contentType;
248 updater.BodyData = data;
249 updater.UpdateTimer = updateTimer;
250 updater.UpdaterID = UUID.Random();
251 updater.Params = extraParams;
252 updater.BlendWithOldTexture = SetBlending;
253 updater.FrontAlpha = AlphaValue;
254 updater.Face = face;
255 updater.Url = "Local image";
256 updater.Disp = disp;
257
258 object objReusableTextureUUID = null;
259
260 if (ReuseTextures && !updater.BlendWithOldTexture)
171 { 261 {
172 DynamicTextureUpdater updater = new DynamicTextureUpdater(); 262 string reuseableTextureKey = GenerateReusableTextureKey(data, extraParams);
173 updater.SimUUID = simID; 263 objReusableTextureUUID = m_reuseableDynamicTextures.Get(reuseableTextureKey);
174 updater.PrimID = primID; 264
175 updater.ContentType = contentType; 265 if (objReusableTextureUUID != null)
176 updater.BodyData = data; 266 {
177 updater.UpdateTimer = updateTimer; 267 // If something else has removed this temporary asset from the cache, detect and invalidate
178 updater.UpdaterID = UUID.Random(); 268 // our cached uuid.
179 updater.Params = extraParams; 269 if (scene.AssetService.GetMetadata(objReusableTextureUUID.ToString()) == null)
180 updater.BlendWithOldTexture = SetBlending; 270 {
181 updater.FrontAlpha = AlphaValue; 271 m_reuseableDynamicTextures.Invalidate(reuseableTextureKey);
182 updater.Face = face; 272 objReusableTextureUUID = null;
183 updater.Url = "Local image"; 273 }
184 updater.Disp = disp; 274 }
275 }
185 276
277 // We cannot reuse a dynamic texture if the data is going to be blended with something already there.
278 if (objReusableTextureUUID == null)
279 {
186 lock (Updaters) 280 lock (Updaters)
187 { 281 {
188 if (!Updaters.ContainsKey(updater.UpdaterID)) 282 if (!Updaters.ContainsKey(updater.UpdaterID))
@@ -191,11 +285,29 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
191 } 285 }
192 } 286 }
193 287
288// m_log.DebugFormat(
289// "[DYNAMIC TEXTURE MODULE]: Requesting generation of new dynamic texture for {0} in {1}",
290// part.Name, part.ParentGroup.Scene.Name);
291
194 RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams); 292 RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams);
195 return updater.UpdaterID;
196 } 293 }
197 294 else
198 return UUID.Zero; 295 {
296// m_log.DebugFormat(
297// "[DYNAMIC TEXTURE MODULE]: Reusing cached texture {0} for {1} in {2}",
298// objReusableTextureUUID, part.Name, part.ParentGroup.Scene.Name);
299
300 // No need to add to updaters as the texture is always the same. Not that this functionality
301 // apppears to be implemented anyway.
302 updater.UpdatePart(part, (UUID)objReusableTextureUUID);
303 }
304
305 return updater.UpdaterID;
306 }
307
308 private string GenerateReusableTextureKey(string data, string extraParams)
309 {
310 return string.Format("{0}{1}", data, extraParams);
199 } 311 }
200 312
201 public void GetDrawStringSize(string contentType, string text, string fontName, int fontSize, 313 public void GetDrawStringSize(string contentType, string text, string fontName, int fontSize,
@@ -215,6 +327,13 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
215 327
216 public void Initialise(Scene scene, IConfigSource config) 328 public void Initialise(Scene scene, IConfigSource config)
217 { 329 {
330 IConfig texturesConfig = config.Configs["Textures"];
331 if (texturesConfig != null)
332 {
333 ReuseTextures = texturesConfig.GetBoolean("ReuseDynamicTextures", false);
334 ReuseLowDataTextures = texturesConfig.GetBoolean("ReuseDynamicLowDataTextures", false);
335 }
336
218 if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID)) 337 if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID))
219 { 338 {
220 RegisteredScenes.Add(scene.RegionInfo.RegionID, scene); 339 RegisteredScenes.Add(scene.RegionInfo.RegionID, scene);
@@ -224,6 +343,11 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
224 343
225 public void PostInitialise() 344 public void PostInitialise()
226 { 345 {
346 if (ReuseTextures)
347 {
348 m_reuseableDynamicTextures = new Cache(CacheMedium.Memory, CacheStrategy.Conservative);
349 m_reuseableDynamicTextures.DefaultTTL = new TimeSpan(24, 0, 0);
350 }
227 } 351 }
228 352
229 public void Close() 353 public void Close()
@@ -269,9 +393,60 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
269 } 393 }
270 394
271 /// <summary> 395 /// <summary>
396 /// Update the given part with the new texture.
397 /// </summary>
398 /// <returns>
399 /// The old texture UUID.
400 /// </returns>
401 public UUID UpdatePart(SceneObjectPart part, UUID textureID)
402 {
403 UUID oldID;
404
405 lock (part)
406 {
407 // mostly keep the values from before
408 Primitive.TextureEntry tmptex = part.Shape.Textures;
409
410 // FIXME: Need to return the appropriate ID if only a single face is replaced.
411 oldID = tmptex.DefaultTexture.TextureID;
412
413 if (Face == ALL_SIDES)
414 {
415 oldID = tmptex.DefaultTexture.TextureID;
416 tmptex.DefaultTexture.TextureID = textureID;
417 }
418 else
419 {
420 try
421 {
422 Primitive.TextureEntryFace texface = tmptex.CreateFace((uint)Face);
423 texface.TextureID = textureID;
424 tmptex.FaceTextures[Face] = texface;
425 }
426 catch (Exception)
427 {
428 tmptex.DefaultTexture.TextureID = textureID;
429 }
430 }
431
432 // I'm pretty sure we always want to force this to true
433 // I'm pretty sure noone whats to set fullbright true if it wasn't true before.
434 // tmptex.DefaultTexture.Fullbright = true;
435
436 part.UpdateTextureEntry(tmptex.GetBytes());
437 }
438
439 return oldID;
440 }
441
442 /// <summary>
272 /// Called once new texture data has been received for this updater. 443 /// Called once new texture data has been received for this updater.
273 /// </summary> 444 /// </summary>
274 public void DataReceived(byte[] data, Scene scene) 445 /// <param name="data"></param>
446 /// <param name="scene"></param>
447 /// <param name="isReuseable">True if the data given is reuseable.</param>
448 /// <returns>The asset UUID given to the incoming data.</returns>
449 public UUID DataReceived(byte[] data, Scene scene)
275 { 450 {
276 SceneObjectPart part = scene.GetSceneObjectPart(PrimID); 451 SceneObjectPart part = scene.GetSceneObjectPart(PrimID);
277 452
@@ -281,7 +456,8 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
281 String.Format("DynamicTextureModule: Error preparing image using URL {0}", Url); 456 String.Format("DynamicTextureModule: Error preparing image using URL {0}", Url);
282 scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Say, 457 scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Say,
283 0, part.ParentGroup.RootPart.AbsolutePosition, part.Name, part.UUID, false); 458 0, part.ParentGroup.RootPart.AbsolutePosition, part.Name, part.UUID, false);
284 return; 459
460 return UUID.Zero;
285 } 461 }
286 462
287 byte[] assetData = null; 463 byte[] assetData = null;
@@ -319,56 +495,29 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
319 IJ2KDecoder cacheLayerDecode = scene.RequestModuleInterface<IJ2KDecoder>(); 495 IJ2KDecoder cacheLayerDecode = scene.RequestModuleInterface<IJ2KDecoder>();
320 if (cacheLayerDecode != null) 496 if (cacheLayerDecode != null)
321 { 497 {
322 cacheLayerDecode.Decode(asset.FullID, asset.Data); 498 if (!cacheLayerDecode.Decode(asset.FullID, asset.Data))
323 cacheLayerDecode = null; 499 m_log.WarnFormat(
500 "[DYNAMIC TEXTURE MODULE]: Decoding of dynamically generated asset {0} for {1} in {2} failed",
501 asset.ID, part.Name, part.ParentGroup.Scene.Name);
324 } 502 }
325 503
326 UUID oldID = UUID.Zero; 504 UUID oldID = UpdatePart(part, asset.FullID);
327
328 lock (part)
329 {
330 // mostly keep the values from before
331 Primitive.TextureEntry tmptex = part.Shape.Textures;
332
333 // remove the old asset from the cache
334 oldID = tmptex.DefaultTexture.TextureID;
335
336 if (Face == ALL_SIDES)
337 {
338 tmptex.DefaultTexture.TextureID = asset.FullID;
339 }
340 else
341 {
342 try
343 {
344 Primitive.TextureEntryFace texface = tmptex.CreateFace((uint)Face);
345 texface.TextureID = asset.FullID;
346 tmptex.FaceTextures[Face] = texface;
347 }
348 catch (Exception)
349 {
350 tmptex.DefaultTexture.TextureID = asset.FullID;
351 }
352 }
353
354 // I'm pretty sure we always want to force this to true
355 // I'm pretty sure noone whats to set fullbright true if it wasn't true before.
356 // tmptex.DefaultTexture.Fullbright = true;
357
358 part.UpdateTextureEntry(tmptex.GetBytes());
359 }
360 505
361 if (oldID != UUID.Zero && ((Disp & DISP_EXPIRE) != 0)) 506 if (oldID != UUID.Zero && ((Disp & DISP_EXPIRE) != 0))
362 { 507 {
363 if (oldAsset == null) oldAsset = scene.AssetService.Get(oldID.ToString()); 508 if (oldAsset == null)
509 oldAsset = scene.AssetService.Get(oldID.ToString());
510
364 if (oldAsset != null) 511 if (oldAsset != null)
365 { 512 {
366 if (oldAsset.Temporary == true) 513 if (oldAsset.Temporary)
367 { 514 {
368 scene.AssetService.Delete(oldID.ToString()); 515 scene.AssetService.Delete(oldID.ToString());
369 } 516 }
370 } 517 }
371 } 518 }
519
520 return asset.FullID;
372 } 521 }
373 522
374 private byte[] BlendTextures(byte[] frontImage, byte[] backImage, bool setNewAlpha, byte newAlpha) 523 private byte[] BlendTextures(byte[] frontImage, byte[] backImage, bool setNewAlpha, byte newAlpha)
diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
index 13762f7..99ffbe7 100644
--- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs
@@ -58,6 +58,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
58 public string body; 58 public string body;
59 public int responseCode; 59 public int responseCode;
60 public string responseBody; 60 public string responseBody;
61 public string responseType = "text/plain";
61 //public ManualResetEvent ev; 62 //public ManualResetEvent ev;
62 public bool requestDone; 63 public bool requestDone;
63 public int startTime; 64 public int startTime;
@@ -270,6 +271,22 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp
270 } 271 }
271 } 272 }
272 273
274 public void HttpContentType(UUID request, string type)
275 {
276 lock (m_UrlMap)
277 {
278 if (m_RequestMap.ContainsKey(request))
279 {
280 UrlData urlData = m_RequestMap[request];
281 urlData.requests[request].responseType = type;
282 }
283 else
284 {
285 m_log.Info("[HttpRequestHandler] There is no http-in request with id " + request.ToString());
286 }
287 }
288 }
289
273 public void HttpResponse(UUID request, int status, string body) 290 public void HttpResponse(UUID request, int status, string body)
274 { 291 {
275 lock (m_RequestMap) 292 lock (m_RequestMap)
diff --git a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs
index 6f83948..45e6527 100644
--- a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs
@@ -32,6 +32,7 @@ using System.Net;
32using Nini.Config; 32using Nini.Config;
33using OpenMetaverse; 33using OpenMetaverse;
34using OpenMetaverse.Imaging; 34using OpenMetaverse.Imaging;
35using OpenSim.Region.CoreModules.Scripting.DynamicTexture;
35using OpenSim.Region.Framework.Interfaces; 36using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.Framework.Scenes; 37using OpenSim.Region.Framework.Scenes;
37using log4net; 38using log4net;
@@ -67,12 +68,18 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
67 return true; 68 return true;
68 } 69 }
69 70
70 public byte[] ConvertUrl(string url, string extraParams) 71// public bool AlwaysIdenticalConversion(string bodyData, string extraParams)
72// {
73// // We don't support conversion of body data.
74// return false;
75// }
76
77 public IDynamicTexture ConvertUrl(string url, string extraParams)
71 { 78 {
72 return null; 79 return null;
73 } 80 }
74 81
75 public byte[] ConvertStream(Stream data, string extraParams) 82 public IDynamicTexture ConvertData(string bodyData, string extraParams)
76 { 83 {
77 return null; 84 return null;
78 } 85 }
@@ -165,11 +172,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
165 172
166 private void HttpRequestReturn(IAsyncResult result) 173 private void HttpRequestReturn(IAsyncResult result)
167 { 174 {
168
169 RequestState state = (RequestState) result.AsyncState; 175 RequestState state = (RequestState) result.AsyncState;
170 WebRequest request = (WebRequest) state.Request; 176 WebRequest request = (WebRequest) state.Request;
171 Stream stream = null; 177 Stream stream = null;
172 byte[] imageJ2000 = new byte[0]; 178 byte[] imageJ2000 = new byte[0];
179 Size newSize = new Size(0, 0);
173 180
174 try 181 try
175 { 182 {
@@ -182,37 +189,43 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
182 try 189 try
183 { 190 {
184 Bitmap image = new Bitmap(stream); 191 Bitmap image = new Bitmap(stream);
185 Size newsize;
186 192
187 // TODO: make this a bit less hard coded 193 // TODO: make this a bit less hard coded
188 if ((image.Height < 64) && (image.Width < 64)) 194 if ((image.Height < 64) && (image.Width < 64))
189 { 195 {
190 newsize = new Size(32, 32); 196 newSize.Width = 32;
197 newSize.Height = 32;
191 } 198 }
192 else if ((image.Height < 128) && (image.Width < 128)) 199 else if ((image.Height < 128) && (image.Width < 128))
193 { 200 {
194 newsize = new Size(64, 64); 201 newSize.Width = 64;
202 newSize.Height = 64;
195 } 203 }
196 else if ((image.Height < 256) && (image.Width < 256)) 204 else if ((image.Height < 256) && (image.Width < 256))
197 { 205 {
198 newsize = new Size(128, 128); 206 newSize.Width = 128;
207 newSize.Height = 128;
199 } 208 }
200 else if ((image.Height < 512 && image.Width < 512)) 209 else if ((image.Height < 512 && image.Width < 512))
201 { 210 {
202 newsize = new Size(256, 256); 211 newSize.Width = 256;
212 newSize.Height = 256;
203 } 213 }
204 else if ((image.Height < 1024 && image.Width < 1024)) 214 else if ((image.Height < 1024 && image.Width < 1024))
205 { 215 {
206 newsize = new Size(512, 512); 216 newSize.Width = 512;
217 newSize.Height = 512;
207 } 218 }
208 else 219 else
209 { 220 {
210 newsize = new Size(1024, 1024); 221 newSize.Width = 1024;
222 newSize.Height = 1024;
211 } 223 }
212 224
213 Bitmap resize = new Bitmap(image, newsize); 225 using (Bitmap resize = new Bitmap(image, newSize))
214 226 {
215 imageJ2000 = OpenJPEG.EncodeFromImage(resize, true); 227 imageJ2000 = OpenJPEG.EncodeFromImage(resize, true);
228 }
216 } 229 }
217 catch (Exception) 230 catch (Exception)
218 { 231 {
@@ -227,7 +240,6 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
227 } 240 }
228 catch (WebException) 241 catch (WebException)
229 { 242 {
230
231 } 243 }
232 finally 244 finally
233 { 245 {
@@ -236,9 +248,14 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
236 stream.Close(); 248 stream.Close();
237 } 249 }
238 } 250 }
239 m_log.DebugFormat("[LOADIMAGEURLMODULE] Returning {0} bytes of image data for request {1}", 251
252 m_log.DebugFormat("[LOADIMAGEURLMODULE]: Returning {0} bytes of image data for request {1}",
240 imageJ2000.Length, state.RequestID); 253 imageJ2000.Length, state.RequestID);
241 m_textureManager.ReturnData(state.RequestID, imageJ2000); 254
255 m_textureManager.ReturnData(
256 state.RequestID,
257 new OpenSim.Region.CoreModules.Scripting.DynamicTexture.DynamicTexture(
258 request.RequestUri, null, imageJ2000, newSize, false));
242 } 259 }
243 260
244 #region Nested type: RequestState 261 #region Nested type: RequestState
diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs
index 9787c8c..41baccc 100644
--- a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs
@@ -45,31 +45,292 @@ using OpenSim.Tests.Common.Mock;
45namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests 45namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
46{ 46{
47 [TestFixture] 47 [TestFixture]
48 public class VectorRenderModuleTests 48 public class VectorRenderModuleTests : OpenSimTestCase
49 { 49 {
50 Scene m_scene;
51 DynamicTextureModule m_dtm;
52 VectorRenderModule m_vrm;
53
54 private void SetupScene(bool reuseTextures)
55 {
56 m_scene = new SceneHelpers().SetupScene();
57
58 m_dtm = new DynamicTextureModule();
59 m_dtm.ReuseTextures = reuseTextures;
60// m_dtm.ReuseLowDataTextures = reuseTextures;
61
62 m_vrm = new VectorRenderModule();
63
64 SceneHelpers.SetupSceneModules(m_scene, m_dtm, m_vrm);
65 }
66
50 [Test] 67 [Test]
51 public void TestDraw() 68 public void TestDraw()
52 { 69 {
53 TestHelpers.InMethod(); 70 TestHelpers.InMethod();
54 71
55 Scene scene = new SceneHelpers().SetupScene(); 72 SetupScene(false);
56 DynamicTextureModule dtm = new DynamicTextureModule(); 73 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
57 VectorRenderModule vrm = new VectorRenderModule();
58 SceneHelpers.SetupSceneModules(scene, dtm, vrm);
59
60 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene);
61 UUID originalTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; 74 UUID originalTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
62 75
63 dtm.AddDynamicTextureData( 76 m_dtm.AddDynamicTextureData(
64 scene.RegionInfo.RegionID, 77 m_scene.RegionInfo.RegionID,
65 so.UUID, 78 so.UUID,
66 vrm.GetContentType(), 79 m_vrm.GetContentType(),
67 "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;", 80 "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;",
68 "", 81 "",
69 0); 82 0);
70 83
84 Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
85 }
86
87 [Test]
88 public void TestRepeatSameDraw()
89 {
90 TestHelpers.InMethod();
91
92 string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
93
94 SetupScene(false);
95 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
96
97 m_dtm.AddDynamicTextureData(
98 m_scene.RegionInfo.RegionID,
99 so.UUID,
100 m_vrm.GetContentType(),
101 dtText,
102 "",
103 0);
104
105 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
106
107 m_dtm.AddDynamicTextureData(
108 m_scene.RegionInfo.RegionID,
109 so.UUID,
110 m_vrm.GetContentType(),
111 dtText,
112 "",
113 0);
114
115 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
116 }
117
118 [Test]
119 public void TestRepeatSameDrawDifferentExtraParams()
120 {
121 TestHelpers.InMethod();
122
123 string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
124
125 SetupScene(false);
126 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
127
128 m_dtm.AddDynamicTextureData(
129 m_scene.RegionInfo.RegionID,
130 so.UUID,
131 m_vrm.GetContentType(),
132 dtText,
133 "",
134 0);
135
136 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
137
138 m_dtm.AddDynamicTextureData(
139 m_scene.RegionInfo.RegionID,
140 so.UUID,
141 m_vrm.GetContentType(),
142 dtText,
143 "alpha:250",
144 0);
145
146 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
147 }
148
149 [Test]
150 public void TestRepeatSameDrawContainingImage()
151 {
152 TestHelpers.InMethod();
153
154 string dtText
155 = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World; Image http://localhost/shouldnotexist.png";
156
157 SetupScene(false);
158 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
159
160 m_dtm.AddDynamicTextureData(
161 m_scene.RegionInfo.RegionID,
162 so.UUID,
163 m_vrm.GetContentType(),
164 dtText,
165 "",
166 0);
167
168 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
169
170 m_dtm.AddDynamicTextureData(
171 m_scene.RegionInfo.RegionID,
172 so.UUID,
173 m_vrm.GetContentType(),
174 dtText,
175 "",
176 0);
177
178 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
179 }
180
181 [Test]
182 public void TestDrawReusingTexture()
183 {
184 TestHelpers.InMethod();
185
186 SetupScene(true);
187 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
188 UUID originalTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
189
190 m_dtm.AddDynamicTextureData(
191 m_scene.RegionInfo.RegionID,
192 so.UUID,
193 m_vrm.GetContentType(),
194 "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;",
195 "",
196 0);
71 197
72 Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); 198 Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
73 } 199 }
200
201 [Test]
202 public void TestRepeatSameDrawReusingTexture()
203 {
204 TestHelpers.InMethod();
205// TestHelpers.EnableLogging();
206
207 string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
208
209 SetupScene(true);
210 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
211
212 m_dtm.AddDynamicTextureData(
213 m_scene.RegionInfo.RegionID,
214 so.UUID,
215 m_vrm.GetContentType(),
216 dtText,
217 "",
218 0);
219
220 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
221
222 m_dtm.AddDynamicTextureData(
223 m_scene.RegionInfo.RegionID,
224 so.UUID,
225 m_vrm.GetContentType(),
226 dtText,
227 "",
228 0);
229
230 Assert.That(firstDynamicTextureID, Is.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
231 }
232
233 /// <summary>
234 /// Test a low data dynamically generated texture such that it is treated as a low data texture that causes
235 /// problems for current viewers.
236 /// </summary>
237 /// <remarks>
238 /// As we do not set DynamicTextureModule.ReuseLowDataTextures = true in this test, it should not reuse the
239 /// texture
240 /// </remarks>
241 [Test]
242 public void TestRepeatSameDrawLowDataTexture()
243 {
244 TestHelpers.InMethod();
245// TestHelpers.EnableLogging();
246
247 string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
248
249 SetupScene(true);
250 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
251
252 m_dtm.AddDynamicTextureData(
253 m_scene.RegionInfo.RegionID,
254 so.UUID,
255 m_vrm.GetContentType(),
256 dtText,
257 "1024",
258 0);
259
260 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
261
262 m_dtm.AddDynamicTextureData(
263 m_scene.RegionInfo.RegionID,
264 so.UUID,
265 m_vrm.GetContentType(),
266 dtText,
267 "1024",
268 0);
269
270 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
271 }
272
273 [Test]
274 public void TestRepeatSameDrawDifferentExtraParamsReusingTexture()
275 {
276 TestHelpers.InMethod();
277
278 string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
279
280 SetupScene(true);
281 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
282
283 m_dtm.AddDynamicTextureData(
284 m_scene.RegionInfo.RegionID,
285 so.UUID,
286 m_vrm.GetContentType(),
287 dtText,
288 "",
289 0);
290
291 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
292
293 m_dtm.AddDynamicTextureData(
294 m_scene.RegionInfo.RegionID,
295 so.UUID,
296 m_vrm.GetContentType(),
297 dtText,
298 "alpha:250",
299 0);
300
301 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
302 }
303
304 [Test]
305 public void TestRepeatSameDrawContainingImageReusingTexture()
306 {
307 TestHelpers.InMethod();
308
309 string dtText
310 = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World; Image http://localhost/shouldnotexist.png";
311
312 SetupScene(true);
313 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
314
315 m_dtm.AddDynamicTextureData(
316 m_scene.RegionInfo.RegionID,
317 so.UUID,
318 m_vrm.GetContentType(),
319 dtText,
320 "",
321 0);
322
323 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
324
325 m_dtm.AddDynamicTextureData(
326 m_scene.RegionInfo.RegionID,
327 so.UUID,
328 m_vrm.GetContentType(),
329 dtText,
330 "",
331 0);
332
333 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
334 }
74 } 335 }
75} \ No newline at end of file 336} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
index 8b2f2f8..1e17b02 100644
--- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
@@ -30,10 +30,12 @@ using System.Drawing;
30using System.Drawing.Imaging; 30using System.Drawing.Imaging;
31using System.Globalization; 31using System.Globalization;
32using System.IO; 32using System.IO;
33using System.Linq;
33using System.Net; 34using System.Net;
34using Nini.Config; 35using Nini.Config;
35using OpenMetaverse; 36using OpenMetaverse;
36using OpenMetaverse.Imaging; 37using OpenMetaverse.Imaging;
38using OpenSim.Region.CoreModules.Scripting.DynamicTexture;
37using OpenSim.Region.Framework.Interfaces; 39using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes; 40using OpenSim.Region.Framework.Scenes;
39using log4net; 41using log4net;
@@ -45,9 +47,13 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
45{ 47{
46 public class VectorRenderModule : IRegionModule, IDynamicTextureRender 48 public class VectorRenderModule : IRegionModule, IDynamicTextureRender
47 { 49 {
50 // These fields exist for testing purposes, please do not remove.
51// private static bool s_flipper;
52// private static byte[] s_asset1Data;
53// private static byte[] s_asset2Data;
54
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 55 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49 56
50 private string m_name = "VectorRenderModule";
51 private Scene m_scene; 57 private Scene m_scene;
52 private IDynamicTextureManager m_textureManager; 58 private IDynamicTextureManager m_textureManager;
53 private Graphics m_graph; 59 private Graphics m_graph;
@@ -61,12 +67,12 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
61 67
62 public string GetContentType() 68 public string GetContentType()
63 { 69 {
64 return ("vector"); 70 return "vector";
65 } 71 }
66 72
67 public string GetName() 73 public string GetName()
68 { 74 {
69 return m_name; 75 return Name;
70 } 76 }
71 77
72 public bool SupportsAsynchronous() 78 public bool SupportsAsynchronous()
@@ -74,14 +80,20 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
74 return true; 80 return true;
75 } 81 }
76 82
77 public byte[] ConvertUrl(string url, string extraParams) 83// public bool AlwaysIdenticalConversion(string bodyData, string extraParams)
84// {
85// string[] lines = GetLines(bodyData);
86// return lines.Any((str, r) => str.StartsWith("Image"));
87// }
88
89 public IDynamicTexture ConvertUrl(string url, string extraParams)
78 { 90 {
79 return null; 91 return null;
80 } 92 }
81 93
82 public byte[] ConvertStream(Stream data, string extraParams) 94 public IDynamicTexture ConvertData(string bodyData, string extraParams)
83 { 95 {
84 return null; 96 return Draw(bodyData, extraParams);
85 } 97 }
86 98
87 public bool AsyncConvertUrl(UUID id, string url, string extraParams) 99 public bool AsyncConvertUrl(UUID id, string url, string extraParams)
@@ -91,7 +103,9 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
91 103
92 public bool AsyncConvertData(UUID id, string bodyData, string extraParams) 104 public bool AsyncConvertData(UUID id, string bodyData, string extraParams)
93 { 105 {
94 Draw(bodyData, id, extraParams); 106 // XXX: This isn't actually being done asynchronously!
107 m_textureManager.ReturnData(id, ConvertData(bodyData, extraParams));
108
95 return true; 109 return true;
96 } 110 }
97 111
@@ -144,6 +158,13 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
144 { 158 {
145 m_textureManager.RegisterRender(GetContentType(), this); 159 m_textureManager.RegisterRender(GetContentType(), this);
146 } 160 }
161
162 // This code exists for testing purposes, please do not remove.
163// s_asset1Data = m_scene.AssetService.Get("00000000-0000-1111-9999-000000000001").Data;
164// s_asset1Data = m_scene.AssetService.Get("9f4acf0d-1841-4e15-bdb8-3a12efc9dd8f").Data;
165
166 // Terrain dirt - smallest bin/assets file (6004 bytes)
167// s_asset2Data = m_scene.AssetService.Get("b8d3965a-ad78-bf43-699b-bff8eca6c975").Data;
147 } 168 }
148 169
149 public void Close() 170 public void Close()
@@ -152,7 +173,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
152 173
153 public string Name 174 public string Name
154 { 175 {
155 get { return m_name; } 176 get { return "VectorRenderModule"; }
156 } 177 }
157 178
158 public bool IsSharedModule 179 public bool IsSharedModule
@@ -162,7 +183,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
162 183
163 #endregion 184 #endregion
164 185
165 private void Draw(string data, UUID id, string extraParams) 186 private IDynamicTexture Draw(string data, string extraParams)
166 { 187 {
167 // We need to cater for old scripts that didnt use extraParams neatly, they use either an integer size which represents both width and height, or setalpha 188 // We need to cater for old scripts that didnt use extraParams neatly, they use either an integer size which represents both width and height, or setalpha
168 // we will now support multiple comma seperated params in the form width:256,height:512,alpha:255 189 // we will now support multiple comma seperated params in the form width:256,height:512,alpha:255
@@ -305,40 +326,57 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
305 326
306 Bitmap bitmap = null; 327 Bitmap bitmap = null;
307 Graphics graph = null; 328 Graphics graph = null;
329 bool reuseable = false;
308 330
309 try 331 try
310 { 332 {
311 if (alpha == 256) 333 // XXX: In testing, it appears that if multiple threads dispose of separate GDI+ objects simultaneously,
312 bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb); 334 // the native malloc heap can become corrupted, possibly due to a double free(). This may be due to
313 else 335 // bugs in the underlying libcairo used by mono's libgdiplus.dll on Linux/OSX. These problems were
314 bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb); 336 // seen with both libcario 1.10.2-6.1ubuntu3 and 1.8.10-2ubuntu1. They go away if disposal is perfomed
315 337 // under lock.
316 graph = Graphics.FromImage(bitmap); 338 lock (this)
317
318 // this is really just to save people filling the
319 // background color in their scripts, only do when fully opaque
320 if (alpha >= 255)
321 { 339 {
322 using (SolidBrush bgFillBrush = new SolidBrush(bgColor)) 340 if (alpha == 256)
341 bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb);
342 else
343 bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
344
345 graph = Graphics.FromImage(bitmap);
346
347 // this is really just to save people filling the
348 // background color in their scripts, only do when fully opaque
349 if (alpha >= 255)
323 { 350 {
324 graph.FillRectangle(bgFillBrush, 0, 0, width, height); 351 using (SolidBrush bgFillBrush = new SolidBrush(bgColor))
352 {
353 graph.FillRectangle(bgFillBrush, 0, 0, width, height);
354 }
325 } 355 }
326 } 356
327 357 for (int w = 0; w < bitmap.Width; w++)
328 for (int w = 0; w < bitmap.Width; w++)
329 {
330 if (alpha <= 255)
331 { 358 {
332 for (int h = 0; h < bitmap.Height; h++) 359 if (alpha <= 255)
333 { 360 {
334 bitmap.SetPixel(w, h, Color.FromArgb(alpha, bitmap.GetPixel(w, h))); 361 for (int h = 0; h < bitmap.Height; h++)
362 {
363 bitmap.SetPixel(w, h, Color.FromArgb(alpha, bitmap.GetPixel(w, h)));
364 }
335 } 365 }
336 } 366 }
367
368 GDIDraw(data, graph, altDataDelim, out reuseable);
337 } 369 }
338 370
339 GDIDraw(data, graph, altDataDelim);
340
341 byte[] imageJ2000 = new byte[0]; 371 byte[] imageJ2000 = new byte[0];
372
373 // This code exists for testing purposes, please do not remove.
374// if (s_flipper)
375// imageJ2000 = s_asset1Data;
376// else
377// imageJ2000 = s_asset2Data;
378//
379// s_flipper = !s_flipper;
342 380
343 try 381 try
344 { 382 {
@@ -351,15 +389,24 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
351 e.Message, e.StackTrace); 389 e.Message, e.StackTrace);
352 } 390 }
353 391
354 m_textureManager.ReturnData(id, imageJ2000); 392 return new OpenSim.Region.CoreModules.Scripting.DynamicTexture.DynamicTexture(
393 data, extraParams, imageJ2000, new Size(width, height), reuseable);
355 } 394 }
356 finally 395 finally
357 { 396 {
358 if (graph != null) 397 // XXX: In testing, it appears that if multiple threads dispose of separate GDI+ objects simultaneously,
359 graph.Dispose(); 398 // the native malloc heap can become corrupted, possibly due to a double free(). This may be due to
360 399 // bugs in the underlying libcairo used by mono's libgdiplus.dll on Linux/OSX. These problems were
361 if (bitmap != null) 400 // seen with both libcario 1.10.2-6.1ubuntu3 and 1.8.10-2ubuntu1. They go away if disposal is perfomed
362 bitmap.Dispose(); 401 // under lock.
402 lock (this)
403 {
404 if (graph != null)
405 graph.Dispose();
406
407 if (bitmap != null)
408 bitmap.Dispose();
409 }
363 } 410 }
364 } 411 }
365 412
@@ -418,8 +465,21 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
418 } 465 }
419*/ 466*/
420 467
421 private void GDIDraw(string data, Graphics graph, char dataDelim) 468 /// <summary>
469 /// Split input data into discrete command lines.
470 /// </summary>
471 /// <returns></returns>
472 /// <param name='data'></param>
473 /// <param name='dataDelim'></param>
474 private string[] GetLines(string data, char dataDelim)
475 {
476 char[] lineDelimiter = { dataDelim };
477 return data.Split(lineDelimiter);
478 }
479
480 private void GDIDraw(string data, Graphics graph, char dataDelim, out bool reuseable)
422 { 481 {
482 reuseable = true;
423 Point startPoint = new Point(0, 0); 483 Point startPoint = new Point(0, 0);
424 Point endPoint = new Point(0, 0); 484 Point endPoint = new Point(0, 0);
425 Pen drawPen = null; 485 Pen drawPen = null;
@@ -434,11 +494,9 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
434 myFont = new Font(fontName, fontSize); 494 myFont = new Font(fontName, fontSize);
435 myBrush = new SolidBrush(Color.Black); 495 myBrush = new SolidBrush(Color.Black);
436 496
437 char[] lineDelimiter = {dataDelim};
438 char[] partsDelimiter = {','}; 497 char[] partsDelimiter = {','};
439 string[] lines = data.Split(lineDelimiter);
440 498
441 foreach (string line in lines) 499 foreach (string line in GetLines(data, dataDelim))
442 { 500 {
443 string nextLine = line.Trim(); 501 string nextLine = line.Trim();
444 //replace with switch, or even better, do some proper parsing 502 //replace with switch, or even better, do some proper parsing
@@ -469,6 +527,10 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
469 } 527 }
470 else if (nextLine.StartsWith("Image")) 528 else if (nextLine.StartsWith("Image"))
471 { 529 {
530 // We cannot reuse any generated texture involving fetching an image via HTTP since that image
531 // can change.
532 reuseable = false;
533
472 float x = 0; 534 float x = 0;
473 float y = 0; 535 float y = 0;
474 GetParams(partsDelimiter, ref nextLine, 5, ref x, ref y); 536 GetParams(partsDelimiter, ref nextLine, 5, ref x, ref y);
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs
index c78915f..449c1f1 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs
@@ -204,8 +204,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
204 public byte[] GetData(string id) 204 public byte[] GetData(string id)
205 { 205 {
206// m_log.DebugFormat("[LOCAL ASSET SERVICES CONNECTOR]: Requesting data for asset {0}", id); 206// m_log.DebugFormat("[LOCAL ASSET SERVICES CONNECTOR]: Requesting data for asset {0}", id);
207 207
208 AssetBase asset = m_Cache.Get(id); 208 AssetBase asset = null;
209
210 if (m_Cache != null)
211 asset = m_Cache.Get(id);
209 212
210 if (asset != null) 213 if (asset != null)
211 return asset.Data; 214 return asset.Data;
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/Tests/AssetConnectorTests.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/Tests/AssetConnectorTests.cs
new file mode 100644
index 0000000..1982473
--- /dev/null
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/Tests/AssetConnectorTests.cs
@@ -0,0 +1,136 @@
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.Threading;
33using log4net.Config;
34using Nini.Config;
35using NUnit.Framework;
36using OpenMetaverse;
37using OpenSim.Framework;
38using OpenSim.Region.Framework.Scenes;
39using OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset;
40using OpenSim.Tests.Common;
41
42namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset.Tests
43{
44 [TestFixture]
45 public class AssetConnectorsTests : OpenSimTestCase
46 {
47 [Test]
48 public void TestAddAsset()
49 {
50 TestHelpers.InMethod();
51// TestHelpers.EnableLogging();
52
53 IConfigSource config = new IniConfigSource();
54 config.AddConfig("Modules");
55 config.Configs["Modules"].Set("AssetServices", "LocalAssetServicesConnector");
56 config.AddConfig("AssetService");
57 config.Configs["AssetService"].Set("LocalServiceModule", "OpenSim.Services.AssetService.dll:AssetService");
58 config.Configs["AssetService"].Set("StorageProvider", "OpenSim.Tests.Common.dll");
59
60 LocalAssetServicesConnector lasc = new LocalAssetServicesConnector();
61 lasc.Initialise(config);
62
63 AssetBase a1 = AssetHelpers.CreateNotecardAsset();
64 lasc.Store(a1);
65
66 AssetBase retreivedA1 = lasc.Get(a1.ID);
67 Assert.That(retreivedA1.ID, Is.EqualTo(a1.ID));
68 Assert.That(retreivedA1.Metadata.ID, Is.EqualTo(a1.Metadata.ID));
69 Assert.That(retreivedA1.Data.Length, Is.EqualTo(a1.Data.Length));
70
71 AssetMetadata retrievedA1Metadata = lasc.GetMetadata(a1.ID);
72 Assert.That(retrievedA1Metadata.ID, Is.EqualTo(a1.ID));
73
74 byte[] retrievedA1Data = lasc.GetData(a1.ID);
75 Assert.That(retrievedA1Data.Length, Is.EqualTo(a1.Data.Length));
76
77 // TODO: Add cache and check that this does receive a copy of the asset
78 }
79
80 [Test]
81 public void TestAddTemporaryAsset()
82 {
83 TestHelpers.InMethod();
84// TestHelpers.EnableLogging();
85
86 IConfigSource config = new IniConfigSource();
87 config.AddConfig("Modules");
88 config.Configs["Modules"].Set("AssetServices", "LocalAssetServicesConnector");
89 config.AddConfig("AssetService");
90 config.Configs["AssetService"].Set("LocalServiceModule", "OpenSim.Services.AssetService.dll:AssetService");
91 config.Configs["AssetService"].Set("StorageProvider", "OpenSim.Tests.Common.dll");
92
93 LocalAssetServicesConnector lasc = new LocalAssetServicesConnector();
94 lasc.Initialise(config);
95
96 AssetBase a1 = AssetHelpers.CreateNotecardAsset();
97 a1.Temporary = true;
98
99 lasc.Store(a1);
100
101 Assert.That(lasc.Get(a1.ID), Is.Null);
102 Assert.That(lasc.GetData(a1.ID), Is.Null);
103 Assert.That(lasc.GetMetadata(a1.ID), Is.Null);
104
105 // TODO: Add cache and check that this does receive a copy of the asset
106 }
107
108 [Test]
109 public void TestAddLocalAsset()
110 {
111 TestHelpers.InMethod();
112// TestHelpers.EnableLogging();
113
114 IConfigSource config = new IniConfigSource();
115 config.AddConfig("Modules");
116 config.Configs["Modules"].Set("AssetServices", "LocalAssetServicesConnector");
117 config.AddConfig("AssetService");
118 config.Configs["AssetService"].Set("LocalServiceModule", "OpenSim.Services.AssetService.dll:AssetService");
119 config.Configs["AssetService"].Set("StorageProvider", "OpenSim.Tests.Common.dll");
120
121 LocalAssetServicesConnector lasc = new LocalAssetServicesConnector();
122 lasc.Initialise(config);
123
124 AssetBase a1 = AssetHelpers.CreateNotecardAsset();
125 a1.Local = true;
126
127 lasc.Store(a1);
128
129 Assert.That(lasc.Get(a1.ID), Is.Null);
130 Assert.That(lasc.GetData(a1.ID), Is.Null);
131 Assert.That(lasc.GetMetadata(a1.ID), Is.Null);
132
133 // TODO: Add cache and check that this does receive a copy of the asset
134 }
135 }
136} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs
index b286d17..57ae549 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/Tests/GridConnectorsTests.cs
@@ -43,7 +43,7 @@ using OpenSim.Tests.Common;
43namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.Tests 43namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.Tests
44{ 44{
45 [TestFixture] 45 [TestFixture]
46 public class GridConnectorsTests 46 public class GridConnectorsTests : OpenSimTestCase
47 { 47 {
48 LocalGridServicesConnector m_LocalConnector; 48 LocalGridServicesConnector m_LocalConnector;
49 private void SetUp() 49 private void SetUp()
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
index 6eb99ea..8ed1833 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
@@ -313,7 +313,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
313 313
314 if (m_scenes.ContainsKey(destination.RegionID)) 314 if (m_scenes.ContainsKey(destination.RegionID))
315 { 315 {
316 Util.FireAndForget(delegate { m_scenes[destination.RegionID].IncomingCloseAgent(id); }); 316// m_log.DebugFormat(
317// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate",
318// s.RegionInfo.RegionName, destination.RegionHandle);
319
320 Util.FireAndForget(delegate { m_scenes[destination.RegionID].IncomingCloseAgent(id, false); });
317 return true; 321 return true;
318 } 322 }
319 //m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent"); 323 //m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent");
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
index 619550c..2127f4d 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
@@ -43,6 +43,7 @@ using OpenSim.Region.Framework.Interfaces;
43using OpenSim.Region.Framework.Scenes; 43using OpenSim.Region.Framework.Scenes;
44using OpenSim.Region.Framework.Scenes.Serialization; 44using OpenSim.Region.Framework.Scenes.Serialization;
45using OpenSim.Services.Interfaces; 45using OpenSim.Services.Interfaces;
46using System.Threading;
46 47
47namespace OpenSim.Region.CoreModules.World.Archiver 48namespace OpenSim.Region.CoreModules.World.Archiver
48{ 49{
@@ -52,7 +53,30 @@ namespace OpenSim.Region.CoreModules.World.Archiver
52 public class ArchiveReadRequest 53 public class ArchiveReadRequest
53 { 54 {
54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 55 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
56
57 /// <summary>
58 /// Contains data used while dearchiving a single scene.
59 /// </summary>
60 private class DearchiveContext
61 {
62 public Scene Scene { get; set; }
63
64 public List<string> SerialisedSceneObjects { get; set; }
65
66 public List<string> SerialisedParcels { get; set; }
67
68 public List<SceneObjectGroup> SceneObjects { get; set; }
69
70 public DearchiveContext(Scene scene)
71 {
72 Scene = scene;
73 SerialisedSceneObjects = new List<string>();
74 SerialisedParcels = new List<string>();
75 SceneObjects = new List<SceneObjectGroup>();
76 }
77 }
55 78
79
56 /// <summary> 80 /// <summary>
57 /// The maximum major version of OAR that we can read. Minor versions shouldn't need a max number since version 81 /// The maximum major version of OAR that we can read. Minor versions shouldn't need a max number since version
58 /// bumps here should be compatible. 82 /// bumps here should be compatible.
@@ -62,9 +86,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver
62 /// <summary> 86 /// <summary>
63 /// Has the control file been loaded for this archive? 87 /// Has the control file been loaded for this archive?
64 /// </summary> 88 /// </summary>
65 public bool ControlFileLoaded { get; private set; } 89 public bool ControlFileLoaded { get; private set; }
66 90
67 protected Scene m_scene; 91 protected string m_loadPath;
92 protected Scene m_rootScene;
68 protected Stream m_loadStream; 93 protected Stream m_loadStream;
69 protected Guid m_requestId; 94 protected Guid m_requestId;
70 protected string m_errorMessage; 95 protected string m_errorMessage;
@@ -91,16 +116,27 @@ namespace OpenSim.Region.CoreModules.World.Archiver
91 { 116 {
92 if (m_UserMan == null) 117 if (m_UserMan == null)
93 { 118 {
94 m_UserMan = m_scene.RequestModuleInterface<IUserManagement>(); 119 m_UserMan = m_rootScene.RequestModuleInterface<IUserManagement>();
95 } 120 }
96 return m_UserMan; 121 return m_UserMan;
97 } 122 }
98 } 123 }
99 124
125 /// <summary>
126 /// Used to cache lookups for valid groups.
127 /// </summary>
128 private IDictionary<UUID, bool> m_validGroupUuids = new Dictionary<UUID, bool>();
129
130 private IGroupsModule m_groupsModule;
131
132 private IAssetService m_assetService = null;
133
134
100 public ArchiveReadRequest(Scene scene, string loadPath, bool merge, bool skipAssets, Guid requestId) 135 public ArchiveReadRequest(Scene scene, string loadPath, bool merge, bool skipAssets, Guid requestId)
101 { 136 {
102 m_scene = scene; 137 m_rootScene = scene;
103 138
139 m_loadPath = loadPath;
104 try 140 try
105 { 141 {
106 m_loadStream = new GZipStream(ArchiveHelpers.GetStream(loadPath), CompressionMode.Decompress); 142 m_loadStream = new GZipStream(ArchiveHelpers.GetStream(loadPath), CompressionMode.Decompress);
@@ -120,11 +156,15 @@ namespace OpenSim.Region.CoreModules.World.Archiver
120 156
121 // Zero can never be a valid user id 157 // Zero can never be a valid user id
122 m_validUserUuids[UUID.Zero] = false; 158 m_validUserUuids[UUID.Zero] = false;
159
160 m_groupsModule = m_rootScene.RequestModuleInterface<IGroupsModule>();
161 m_assetService = m_rootScene.AssetService;
123 } 162 }
124 163
125 public ArchiveReadRequest(Scene scene, Stream loadStream, bool merge, bool skipAssets, Guid requestId) 164 public ArchiveReadRequest(Scene scene, Stream loadStream, bool merge, bool skipAssets, Guid requestId)
126 { 165 {
127 m_scene = scene; 166 m_rootScene = scene;
167 m_loadPath = null;
128 m_loadStream = loadStream; 168 m_loadStream = loadStream;
129 m_merge = merge; 169 m_merge = merge;
130 m_skipAssets = skipAssets; 170 m_skipAssets = skipAssets;
@@ -132,6 +172,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver
132 172
133 // Zero can never be a valid user id 173 // Zero can never be a valid user id
134 m_validUserUuids[UUID.Zero] = false; 174 m_validUserUuids[UUID.Zero] = false;
175
176 m_groupsModule = m_rootScene.RequestModuleInterface<IGroupsModule>();
177 m_assetService = m_rootScene.AssetService;
135 } 178 }
136 179
137 /// <summary> 180 /// <summary>
@@ -139,25 +182,25 @@ namespace OpenSim.Region.CoreModules.World.Archiver
139 /// </summary> 182 /// </summary>
140 public void DearchiveRegion() 183 public void DearchiveRegion()
141 { 184 {
142 // The same code can handle dearchiving 0.1 and 0.2 OpenSim Archive versions
143 DearchiveRegion0DotStar();
144 }
145
146 private void DearchiveRegion0DotStar()
147 {
148 int successfulAssetRestores = 0; 185 int successfulAssetRestores = 0;
149 int failedAssetRestores = 0; 186 int failedAssetRestores = 0;
150 List<string> serialisedSceneObjects = new List<string>();
151 List<string> serialisedParcels = new List<string>();
152 string filePath = "NONE";
153 187
154 TarArchiveReader archive = new TarArchiveReader(m_loadStream); 188 DearchiveScenesInfo dearchivedScenes;
189
190 // We dearchive all the scenes at once, because the files in the TAR archive might be mixed.
191 // Therefore, we have to keep track of the dearchive context of all the scenes.
192 Dictionary<UUID, DearchiveContext> sceneContexts = new Dictionary<UUID, DearchiveContext>();
193
194 string fullPath = "NONE";
195 TarArchiveReader archive = null;
155 byte[] data; 196 byte[] data;
156 TarArchiveReader.TarEntryType entryType; 197 TarArchiveReader.TarEntryType entryType;
157 198
158 try 199 try
159 { 200 {
160 while ((data = archive.ReadEntry(out filePath, out entryType)) != null) 201 FindAndLoadControlFile(out archive, out dearchivedScenes);
202
203 while ((data = archive.ReadEntry(out fullPath, out entryType)) != null)
161 { 204 {
162 //m_log.DebugFormat( 205 //m_log.DebugFormat(
163 // "[ARCHIVER]: Successfully read {0} ({1} bytes)", filePath, data.Length); 206 // "[ARCHIVER]: Successfully read {0} ({1} bytes)", filePath, data.Length);
@@ -165,9 +208,30 @@ namespace OpenSim.Region.CoreModules.World.Archiver
165 if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY == entryType) 208 if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY == entryType)
166 continue; 209 continue;
167 210
211
212 // Find the scene that this file belongs to
213
214 Scene scene;
215 string filePath;
216 if (!dearchivedScenes.GetRegionFromPath(fullPath, out scene, out filePath))
217 continue; // this file belongs to a region that we're not loading
218
219 DearchiveContext sceneContext = null;
220 if (scene != null)
221 {
222 if (!sceneContexts.TryGetValue(scene.RegionInfo.RegionID, out sceneContext))
223 {
224 sceneContext = new DearchiveContext(scene);
225 sceneContexts.Add(scene.RegionInfo.RegionID, sceneContext);
226 }
227 }
228
229
230 // Process the file
231
168 if (filePath.StartsWith(ArchiveConstants.OBJECTS_PATH)) 232 if (filePath.StartsWith(ArchiveConstants.OBJECTS_PATH))
169 { 233 {
170 serialisedSceneObjects.Add(Encoding.UTF8.GetString(data)); 234 sceneContext.SerialisedSceneObjects.Add(Encoding.UTF8.GetString(data));
171 } 235 }
172 else if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH) && !m_skipAssets) 236 else if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH) && !m_skipAssets)
173 { 237 {
@@ -181,19 +245,19 @@ namespace OpenSim.Region.CoreModules.World.Archiver
181 } 245 }
182 else if (!m_merge && filePath.StartsWith(ArchiveConstants.TERRAINS_PATH)) 246 else if (!m_merge && filePath.StartsWith(ArchiveConstants.TERRAINS_PATH))
183 { 247 {
184 LoadTerrain(filePath, data); 248 LoadTerrain(scene, filePath, data);
185 } 249 }
186 else if (!m_merge && filePath.StartsWith(ArchiveConstants.SETTINGS_PATH)) 250 else if (!m_merge && filePath.StartsWith(ArchiveConstants.SETTINGS_PATH))
187 { 251 {
188 LoadRegionSettings(filePath, data); 252 LoadRegionSettings(scene, filePath, data, dearchivedScenes);
189 } 253 }
190 else if (!m_merge && filePath.StartsWith(ArchiveConstants.LANDDATA_PATH)) 254 else if (!m_merge && filePath.StartsWith(ArchiveConstants.LANDDATA_PATH))
191 { 255 {
192 serialisedParcels.Add(Encoding.UTF8.GetString(data)); 256 sceneContext.SerialisedParcels.Add(Encoding.UTF8.GetString(data));
193 } 257 }
194 else if (filePath == ArchiveConstants.CONTROL_FILE_PATH) 258 else if (filePath == ArchiveConstants.CONTROL_FILE_PATH)
195 { 259 {
196 LoadControlFile(filePath, data); 260 // Ignore, because we already read the control file
197 } 261 }
198 } 262 }
199 263
@@ -201,15 +265,16 @@ namespace OpenSim.Region.CoreModules.World.Archiver
201 } 265 }
202 catch (Exception e) 266 catch (Exception e)
203 { 267 {
204 m_log.ErrorFormat( 268 m_log.Error(
205 "[ARCHIVER]: Aborting load with error in archive file {0}. {1}", filePath, e); 269 String.Format("[ARCHIVER]: Aborting load with error in archive file {0} ", fullPath), e);
206 m_errorMessage += e.ToString(); 270 m_errorMessage += e.ToString();
207 m_scene.EventManager.TriggerOarFileLoaded(m_requestId, m_errorMessage); 271 m_rootScene.EventManager.TriggerOarFileLoaded(m_requestId, new List<UUID>(), m_errorMessage);
208 return; 272 return;
209 } 273 }
210 finally 274 finally
211 { 275 {
212 archive.Close(); 276 if (archive != null)
277 archive.Close();
213 } 278 }
214 279
215 if (!m_skipAssets) 280 if (!m_skipAssets)
@@ -223,32 +288,143 @@ namespace OpenSim.Region.CoreModules.World.Archiver
223 } 288 }
224 } 289 }
225 290
226 if (!m_merge) 291 foreach (DearchiveContext sceneContext in sceneContexts.Values)
227 { 292 {
228 m_log.Info("[ARCHIVER]: Clearing all existing scene objects"); 293 m_log.InfoFormat("[ARCHIVER:] Loading region {0}", sceneContext.Scene.RegionInfo.RegionName);
229 m_scene.DeleteAllSceneObjects(); 294
295 if (!m_merge)
296 {
297 m_log.Info("[ARCHIVER]: Clearing all existing scene objects");
298 sceneContext.Scene.DeleteAllSceneObjects();
299 }
300
301 try
302 {
303 LoadParcels(sceneContext.Scene, sceneContext.SerialisedParcels);
304 LoadObjects(sceneContext.Scene, sceneContext.SerialisedSceneObjects, sceneContext.SceneObjects);
305
306 // Inform any interested parties that the region has changed. We waited until now so that all
307 // of the region's objects will be loaded when we send this notification.
308 IEstateModule estateModule = sceneContext.Scene.RequestModuleInterface<IEstateModule>();
309 if (estateModule != null)
310 estateModule.TriggerRegionInfoChange();
311 }
312 catch (Exception e)
313 {
314 m_log.Error("[ARCHIVER]: Error loading parcels or objects ", e);
315 m_errorMessage += e.ToString();
316 m_rootScene.EventManager.TriggerOarFileLoaded(m_requestId, new List<UUID>(), m_errorMessage);
317 return;
318 }
230 } 319 }
231 320
232 LoadParcels(serialisedParcels); 321 // Start the scripts. We delayed this because we want the OAR to finish loading ASAP, so
233 LoadObjects(serialisedSceneObjects); 322 // that users can enter the scene. If we allow the scripts to start in the loop above
323 // then they significantly increase the time until the OAR finishes loading.
324 Util.FireAndForget(delegate(object o)
325 {
326 Thread.Sleep(15000);
327 m_log.Info("Starting scripts in scene objects");
328
329 foreach (DearchiveContext sceneContext in sceneContexts.Values)
330 {
331 foreach (SceneObjectGroup sceneObject in sceneContext.SceneObjects)
332 {
333 sceneObject.CreateScriptInstances(0, false, sceneContext.Scene.DefaultScriptEngine, 0); // StateSource.RegionStart
334 sceneObject.ResumeScripts();
335 }
336
337 sceneContext.SceneObjects.Clear();
338 }
339 });
234 340
235 m_log.InfoFormat("[ARCHIVER]: Successfully loaded archive"); 341 m_log.InfoFormat("[ARCHIVER]: Successfully loaded archive");
236 342
237 m_scene.EventManager.TriggerOarFileLoaded(m_requestId, m_errorMessage); 343 m_rootScene.EventManager.TriggerOarFileLoaded(m_requestId, dearchivedScenes.GetLoadedScenes(), m_errorMessage);
344 }
345
346 /// <summary>
347 /// Searches through the files in the archive for the control file, and reads it.
348 /// We must read the control file first, in order to know which regions are available.
349 /// </summary>
350 /// <remarks>
351 /// In most cases the control file *is* first, since that's how we create archives. However,
352 /// it's possible that someone rewrote the archive externally so we can't rely on this fact.
353 /// </remarks>
354 /// <param name="archive"></param>
355 /// <param name="dearchivedScenes"></param>
356 private void FindAndLoadControlFile(out TarArchiveReader archive, out DearchiveScenesInfo dearchivedScenes)
357 {
358 archive = new TarArchiveReader(m_loadStream);
359 dearchivedScenes = new DearchiveScenesInfo();
360
361 string filePath;
362 byte[] data;
363 TarArchiveReader.TarEntryType entryType;
364 bool firstFile = true;
365
366 while ((data = archive.ReadEntry(out filePath, out entryType)) != null)
367 {
368 if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY == entryType)
369 continue;
370
371 if (filePath == ArchiveConstants.CONTROL_FILE_PATH)
372 {
373 LoadControlFile(filePath, data, dearchivedScenes);
374
375 // Find which scenes are available in the simulator
376 ArchiveScenesGroup simulatorScenes = new ArchiveScenesGroup();
377 SceneManager.Instance.ForEachScene(delegate(Scene scene2)
378 {
379 simulatorScenes.AddScene(scene2);
380 });
381 simulatorScenes.CalcSceneLocations();
382 dearchivedScenes.SetSimulatorScenes(m_rootScene, simulatorScenes);
383
384 // If the control file wasn't the first file then reset the read pointer
385 if (!firstFile)
386 {
387 m_log.Warn("Control file wasn't the first file in the archive");
388 if (m_loadStream.CanSeek)
389 {
390 m_loadStream.Seek(0, SeekOrigin.Begin);
391 }
392 else if (m_loadPath != null)
393 {
394 archive.Close();
395 archive = null;
396 m_loadStream.Close();
397 m_loadStream = null;
398 m_loadStream = new GZipStream(ArchiveHelpers.GetStream(m_loadPath), CompressionMode.Decompress);
399 archive = new TarArchiveReader(m_loadStream);
400 }
401 else
402 {
403 // There isn't currently a scenario where this happens, but it's best to add a check just in case
404 throw new Exception("Error reading archive: control file wasn't the first file, and the input stream doesn't allow seeking");
405 }
406 }
407
408 return;
409 }
410
411 firstFile = false;
412 }
413
414 throw new Exception("Control file not found");
238 } 415 }
239 416
240 /// <summary> 417 /// <summary>
241 /// Load serialized scene objects. 418 /// Load serialized scene objects.
242 /// </summary> 419 /// </summary>
243 /// <param name="serialisedSceneObjects"></param> 420 protected void LoadObjects(Scene scene, List<string> serialisedSceneObjects, List<SceneObjectGroup> sceneObjects)
244 protected void LoadObjects(List<string> serialisedSceneObjects)
245 { 421 {
246 // Reload serialized prims 422 // Reload serialized prims
247 m_log.InfoFormat("[ARCHIVER]: Loading {0} scene objects. Please wait.", serialisedSceneObjects.Count); 423 m_log.InfoFormat("[ARCHIVER]: Loading {0} scene objects. Please wait.", serialisedSceneObjects.Count);
248 424
249 UUID oldTelehubUUID = m_scene.RegionInfo.RegionSettings.TelehubObject; 425 UUID oldTelehubUUID = scene.RegionInfo.RegionSettings.TelehubObject;
250 426
251 IRegionSerialiserModule serialiser = m_scene.RequestModuleInterface<IRegionSerialiserModule>(); 427 IRegionSerialiserModule serialiser = scene.RequestModuleInterface<IRegionSerialiserModule>();
252 int sceneObjectsLoadedCount = 0; 428 int sceneObjectsLoadedCount = 0;
253 429
254 foreach (string serialisedSceneObject in serialisedSceneObjects) 430 foreach (string serialisedSceneObject in serialisedSceneObjects)
@@ -269,7 +445,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
269 445
270 SceneObjectGroup sceneObject = serialiser.DeserializeGroupFromXml2(serialisedSceneObject); 446 SceneObjectGroup sceneObject = serialiser.DeserializeGroupFromXml2(serialisedSceneObject);
271 447
272 bool isTelehub = (sceneObject.UUID == oldTelehubUUID); 448 bool isTelehub = (sceneObject.UUID == oldTelehubUUID) && (oldTelehubUUID != UUID.Zero);
273 449
274 // For now, give all incoming scene objects new uuids. This will allow scenes to be cloned 450 // For now, give all incoming scene objects new uuids. This will allow scenes to be cloned
275 // on the same region server and multiple examples a single object archive to be imported 451 // on the same region server and multiple examples a single object archive to be imported
@@ -279,8 +455,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
279 if (isTelehub) 455 if (isTelehub)
280 { 456 {
281 // Change the Telehub Object to the new UUID 457 // Change the Telehub Object to the new UUID
282 m_scene.RegionInfo.RegionSettings.TelehubObject = sceneObject.UUID; 458 scene.RegionInfo.RegionSettings.TelehubObject = sceneObject.UUID;
283 m_scene.RegionInfo.RegionSettings.Save(); 459 scene.RegionInfo.RegionSettings.Save();
284 oldTelehubUUID = UUID.Zero; 460 oldTelehubUUID = UUID.Zero;
285 } 461 }
286 462
@@ -290,17 +466,20 @@ namespace OpenSim.Region.CoreModules.World.Archiver
290 { 466 {
291 if (part.CreatorData == null || part.CreatorData == string.Empty) 467 if (part.CreatorData == null || part.CreatorData == string.Empty)
292 { 468 {
293 if (!ResolveUserUuid(part.CreatorID)) 469 if (!ResolveUserUuid(scene, part.CreatorID))
294 part.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner; 470 part.CreatorID = scene.RegionInfo.EstateSettings.EstateOwner;
295 } 471 }
296 if (UserManager != null) 472 if (UserManager != null)
297 UserManager.AddUser(part.CreatorID, part.CreatorData); 473 UserManager.AddUser(part.CreatorID, part.CreatorData);
298 474
299 if (!ResolveUserUuid(part.OwnerID)) 475 if (!ResolveUserUuid(scene, part.OwnerID))
300 part.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; 476 part.OwnerID = scene.RegionInfo.EstateSettings.EstateOwner;
477
478 if (!ResolveUserUuid(scene, part.LastOwnerID))
479 part.LastOwnerID = scene.RegionInfo.EstateSettings.EstateOwner;
301 480
302 if (!ResolveUserUuid(part.LastOwnerID)) 481 if (!ResolveGroupUuid(part.GroupID))
303 part.LastOwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; 482 part.GroupID = UUID.Zero;
304 483
305 // And zap any troublesome sit target information 484 // And zap any troublesome sit target information
306// part.SitTargetOrientation = new Quaternion(0, 0, 0, 1); 485// part.SitTargetOrientation = new Quaternion(0, 0, 0, 1);
@@ -311,14 +490,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver
311 // being no copy/no mod for everyone 490 // being no copy/no mod for everyone
312 lock (part.TaskInventory) 491 lock (part.TaskInventory)
313 { 492 {
314 if (!ResolveUserUuid(part.CreatorID)) 493 if (!ResolveUserUuid(scene, part.CreatorID))
315 part.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner; 494 part.CreatorID = scene.RegionInfo.EstateSettings.EstateOwner;
316 495
317 if (!ResolveUserUuid(part.OwnerID)) 496 if (!ResolveUserUuid(scene, part.OwnerID))
318 part.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; 497 part.OwnerID = scene.RegionInfo.EstateSettings.EstateOwner;
319 498
320 if (!ResolveUserUuid(part.LastOwnerID)) 499 if (!ResolveUserUuid(scene, part.LastOwnerID))
321 part.LastOwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; 500 part.LastOwnerID = scene.RegionInfo.EstateSettings.EstateOwner;
322 501
323 // And zap any troublesome sit target information 502 // And zap any troublesome sit target information
324 part.SitTargetOrientation = new Quaternion(0, 0, 0, 1); 503 part.SitTargetOrientation = new Quaternion(0, 0, 0, 1);
@@ -331,26 +510,31 @@ namespace OpenSim.Region.CoreModules.World.Archiver
331 TaskInventoryDictionary inv = part.TaskInventory; 510 TaskInventoryDictionary inv = part.TaskInventory;
332 foreach (KeyValuePair<UUID, TaskInventoryItem> kvp in inv) 511 foreach (KeyValuePair<UUID, TaskInventoryItem> kvp in inv)
333 { 512 {
334 if (!ResolveUserUuid(kvp.Value.OwnerID)) 513 if (!ResolveUserUuid(scene, kvp.Value.OwnerID))
335 { 514 {
336 kvp.Value.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; 515 kvp.Value.OwnerID = scene.RegionInfo.EstateSettings.EstateOwner;
337 } 516 }
517
338 if (kvp.Value.CreatorData == null || kvp.Value.CreatorData == string.Empty) 518 if (kvp.Value.CreatorData == null || kvp.Value.CreatorData == string.Empty)
339 { 519 {
340 if (!ResolveUserUuid(kvp.Value.CreatorID)) 520 if (!ResolveUserUuid(scene, kvp.Value.CreatorID))
341 kvp.Value.CreatorID = m_scene.RegionInfo.EstateSettings.EstateOwner; 521 kvp.Value.CreatorID = scene.RegionInfo.EstateSettings.EstateOwner;
342 } 522 }
523
343 if (UserManager != null) 524 if (UserManager != null)
344 UserManager.AddUser(kvp.Value.CreatorID, kvp.Value.CreatorData); 525 UserManager.AddUser(kvp.Value.CreatorID, kvp.Value.CreatorData);
526
527 if (!ResolveGroupUuid(kvp.Value.GroupID))
528 kvp.Value.GroupID = UUID.Zero;
345 } 529 }
346 part.TaskInventory.LockItemsForRead(false); 530 part.TaskInventory.LockItemsForRead(false);
347 } 531 }
348 } 532 }
349 533
350 if (m_scene.AddRestoredSceneObject(sceneObject, true, false)) 534 if (scene.AddRestoredSceneObject(sceneObject, true, false))
351 { 535 {
352 sceneObjectsLoadedCount++; 536 sceneObjectsLoadedCount++;
353 sceneObject.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, 0); 537 sceneObject.CreateScriptInstances(0, false, scene.DefaultScriptEngine, 0);
354 sceneObject.ResumeScripts(); 538 sceneObject.ResumeScripts();
355 } 539 }
356 } 540 }
@@ -365,16 +549,17 @@ namespace OpenSim.Region.CoreModules.World.Archiver
365 if (oldTelehubUUID != UUID.Zero) 549 if (oldTelehubUUID != UUID.Zero)
366 { 550 {
367 m_log.WarnFormat("Telehub object not found: {0}", oldTelehubUUID); 551 m_log.WarnFormat("Telehub object not found: {0}", oldTelehubUUID);
368 m_scene.RegionInfo.RegionSettings.TelehubObject = UUID.Zero; 552 scene.RegionInfo.RegionSettings.TelehubObject = UUID.Zero;
369 m_scene.RegionInfo.RegionSettings.ClearSpawnPoints(); 553 scene.RegionInfo.RegionSettings.ClearSpawnPoints();
370 } 554 }
371 } 555 }
372 556
373 /// <summary> 557 /// <summary>
374 /// Load serialized parcels. 558 /// Load serialized parcels.
375 /// </summary> 559 /// </summary>
560 /// <param name="scene"></param>
376 /// <param name="serialisedParcels"></param> 561 /// <param name="serialisedParcels"></param>
377 protected void LoadParcels(List<string> serialisedParcels) 562 protected void LoadParcels(Scene scene, List<string> serialisedParcels)
378 { 563 {
379 // Reload serialized parcels 564 // Reload serialized parcels
380 m_log.InfoFormat("[ARCHIVER]: Loading {0} parcels. Please wait.", serialisedParcels.Count); 565 m_log.InfoFormat("[ARCHIVER]: Loading {0} parcels. Please wait.", serialisedParcels.Count);
@@ -382,9 +567,27 @@ namespace OpenSim.Region.CoreModules.World.Archiver
382 foreach (string serialisedParcel in serialisedParcels) 567 foreach (string serialisedParcel in serialisedParcels)
383 { 568 {
384 LandData parcel = LandDataSerializer.Deserialize(serialisedParcel); 569 LandData parcel = LandDataSerializer.Deserialize(serialisedParcel);
385 if (!ResolveUserUuid(parcel.OwnerID))
386 parcel.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
387 570
571 // Validate User and Group UUID's
572
573 if (!ResolveUserUuid(scene, parcel.OwnerID))
574 parcel.OwnerID = m_rootScene.RegionInfo.EstateSettings.EstateOwner;
575
576 if (!ResolveGroupUuid(parcel.GroupID))
577 {
578 parcel.GroupID = UUID.Zero;
579 parcel.IsGroupOwned = false;
580 }
581
582 List<LandAccessEntry> accessList = new List<LandAccessEntry>();
583 foreach (LandAccessEntry entry in parcel.ParcelAccessList)
584 {
585 if (ResolveUserUuid(scene, entry.AgentID))
586 accessList.Add(entry);
587 // else, drop this access rule
588 }
589 parcel.ParcelAccessList = accessList;
590
388// m_log.DebugFormat( 591// m_log.DebugFormat(
389// "[ARCHIVER]: Adding parcel {0}, local id {1}, area {2}", 592// "[ARCHIVER]: Adding parcel {0}, local id {1}, area {2}",
390// parcel.Name, parcel.LocalID, parcel.Area); 593// parcel.Name, parcel.LocalID, parcel.Area);
@@ -395,23 +598,24 @@ namespace OpenSim.Region.CoreModules.World.Archiver
395 if (!m_merge) 598 if (!m_merge)
396 { 599 {
397 bool setupDefaultParcel = (landData.Count == 0); 600 bool setupDefaultParcel = (landData.Count == 0);
398 m_scene.LandChannel.Clear(setupDefaultParcel); 601 scene.LandChannel.Clear(setupDefaultParcel);
399 } 602 }
400 603
401 m_scene.EventManager.TriggerIncomingLandDataFromStorage(landData); 604 scene.EventManager.TriggerIncomingLandDataFromStorage(landData);
402 m_log.InfoFormat("[ARCHIVER]: Restored {0} parcels.", landData.Count); 605 m_log.InfoFormat("[ARCHIVER]: Restored {0} parcels.", landData.Count);
403 } 606 }
404 607
405 /// <summary> 608 /// <summary>
406 /// Look up the given user id to check whether it's one that is valid for this grid. 609 /// Look up the given user id to check whether it's one that is valid for this grid.
407 /// </summary> 610 /// </summary>
611 /// <param name="scene"></param>
408 /// <param name="uuid"></param> 612 /// <param name="uuid"></param>
409 /// <returns></returns> 613 /// <returns></returns>
410 private bool ResolveUserUuid(UUID uuid) 614 private bool ResolveUserUuid(Scene scene, UUID uuid)
411 { 615 {
412 if (!m_validUserUuids.ContainsKey(uuid)) 616 if (!m_validUserUuids.ContainsKey(uuid))
413 { 617 {
414 UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, uuid); 618 UserAccount account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, uuid);
415 m_validUserUuids.Add(uuid, account != null); 619 m_validUserUuids.Add(uuid, account != null);
416 } 620 }
417 621
@@ -419,6 +623,30 @@ namespace OpenSim.Region.CoreModules.World.Archiver
419 } 623 }
420 624
421 /// <summary> 625 /// <summary>
626 /// Look up the given group id to check whether it's one that is valid for this grid.
627 /// </summary>
628 /// <param name="uuid"></param>
629 /// <returns></returns>
630 private bool ResolveGroupUuid(UUID uuid)
631 {
632 if (uuid == UUID.Zero)
633 return true; // this means the object has no group
634
635 if (!m_validGroupUuids.ContainsKey(uuid))
636 {
637 bool exists;
638
639 if (m_groupsModule == null)
640 exists = false;
641 else
642 exists = (m_groupsModule.GetGroupRecord(uuid) != null);
643
644 m_validGroupUuids.Add(uuid, exists);
645 }
646
647 return m_validGroupUuids[uuid];
648 }
649
422 /// Load an asset 650 /// Load an asset
423 /// </summary> 651 /// </summary>
424 /// <param name="assetFilename"></param> 652 /// <param name="assetFilename"></param>
@@ -442,7 +670,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
442 string extension = filename.Substring(i); 670 string extension = filename.Substring(i);
443 string uuid = filename.Remove(filename.Length - extension.Length); 671 string uuid = filename.Remove(filename.Length - extension.Length);
444 672
445 if (m_scene.AssetService.GetMetadata(uuid) != null) 673 if (m_assetService.GetMetadata(uuid) != null)
446 { 674 {
447 // m_log.DebugFormat("[ARCHIVER]: found existing asset {0}",uuid); 675 // m_log.DebugFormat("[ARCHIVER]: found existing asset {0}",uuid);
448 return true; 676 return true;
@@ -462,7 +690,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
462 690
463 // We're relying on the asset service to do the sensible thing and not store the asset if it already 691 // We're relying on the asset service to do the sensible thing and not store the asset if it already
464 // exists. 692 // exists.
465 m_scene.AssetService.Store(asset); 693 m_assetService.Store(asset);
466 694
467 /** 695 /**
468 * Create layers on decode for image assets. This is likely to significantly increase the time to load archives so 696 * Create layers on decode for image assets. This is likely to significantly increase the time to load archives so
@@ -490,12 +718,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver
490 /// <summary> 718 /// <summary>
491 /// Load region settings data 719 /// Load region settings data
492 /// </summary> 720 /// </summary>
721 /// <param name="scene"></param>
493 /// <param name="settingsPath"></param> 722 /// <param name="settingsPath"></param>
494 /// <param name="data"></param> 723 /// <param name="data"></param>
724 /// <param name="dearchivedScenes"></param>
495 /// <returns> 725 /// <returns>
496 /// true if settings were loaded successfully, false otherwise 726 /// true if settings were loaded successfully, false otherwise
497 /// </returns> 727 /// </returns>
498 private bool LoadRegionSettings(string settingsPath, byte[] data) 728 private bool LoadRegionSettings(Scene scene, string settingsPath, byte[] data, DearchiveScenesInfo dearchivedScenes)
499 { 729 {
500 RegionSettings loadedRegionSettings; 730 RegionSettings loadedRegionSettings;
501 731
@@ -511,7 +741,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
511 return false; 741 return false;
512 } 742 }
513 743
514 RegionSettings currentRegionSettings = m_scene.RegionInfo.RegionSettings; 744 RegionSettings currentRegionSettings = scene.RegionInfo.RegionSettings;
515 745
516 currentRegionSettings.AgentLimit = loadedRegionSettings.AgentLimit; 746 currentRegionSettings.AgentLimit = loadedRegionSettings.AgentLimit;
517 currentRegionSettings.AllowDamage = loadedRegionSettings.AllowDamage; 747 currentRegionSettings.AllowDamage = loadedRegionSettings.AllowDamage;
@@ -548,12 +778,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver
548 foreach (SpawnPoint sp in loadedRegionSettings.SpawnPoints()) 778 foreach (SpawnPoint sp in loadedRegionSettings.SpawnPoints())
549 currentRegionSettings.AddSpawnPoint(sp); 779 currentRegionSettings.AddSpawnPoint(sp);
550 780
781 currentRegionSettings.LoadedCreationDateTime = dearchivedScenes.LoadedCreationDateTime;
782 currentRegionSettings.LoadedCreationID = dearchivedScenes.GetOriginalRegionID(scene.RegionInfo.RegionID).ToString();
783
551 currentRegionSettings.Save(); 784 currentRegionSettings.Save();
552 785
553 m_scene.TriggerEstateSunUpdate(); 786 scene.TriggerEstateSunUpdate();
554 787
555 IEstateModule estateModule = m_scene.RequestModuleInterface<IEstateModule>(); 788 IEstateModule estateModule = scene.RequestModuleInterface<IEstateModule>();
556
557 if (estateModule != null) 789 if (estateModule != null)
558 estateModule.sendRegionHandshakeToAll(); 790 estateModule.sendRegionHandshakeToAll();
559 791
@@ -563,14 +795,15 @@ namespace OpenSim.Region.CoreModules.World.Archiver
563 /// <summary> 795 /// <summary>
564 /// Load terrain data 796 /// Load terrain data
565 /// </summary> 797 /// </summary>
798 /// <param name="scene"></param>
566 /// <param name="terrainPath"></param> 799 /// <param name="terrainPath"></param>
567 /// <param name="data"></param> 800 /// <param name="data"></param>
568 /// <returns> 801 /// <returns>
569 /// true if terrain was resolved successfully, false otherwise. 802 /// true if terrain was resolved successfully, false otherwise.
570 /// </returns> 803 /// </returns>
571 private bool LoadTerrain(string terrainPath, byte[] data) 804 private bool LoadTerrain(Scene scene, string terrainPath, byte[] data)
572 { 805 {
573 ITerrainModule terrainModule = m_scene.RequestModuleInterface<ITerrainModule>(); 806 ITerrainModule terrainModule = scene.RequestModuleInterface<ITerrainModule>();
574 807
575 MemoryStream ms = new MemoryStream(data); 808 MemoryStream ms = new MemoryStream(data);
576 terrainModule.LoadFromStream(terrainPath, ms); 809 terrainModule.LoadFromStream(terrainPath, ms);
@@ -586,17 +819,18 @@ namespace OpenSim.Region.CoreModules.World.Archiver
586 /// </summary> 819 /// </summary>
587 /// <param name="path"></param> 820 /// <param name="path"></param>
588 /// <param name="data"></param> 821 /// <param name="data"></param>
589 public void LoadControlFile(string path, byte[] data) 822 /// <param name="dearchivedScenes"></param>
823 public DearchiveScenesInfo LoadControlFile(string path, byte[] data, DearchiveScenesInfo dearchivedScenes)
590 { 824 {
591 XmlNamespaceManager nsmgr = new XmlNamespaceManager(new NameTable()); 825 XmlNamespaceManager nsmgr = new XmlNamespaceManager(new NameTable());
592 XmlParserContext context = new XmlParserContext(null, nsmgr, null, XmlSpace.None); 826 XmlParserContext context = new XmlParserContext(null, nsmgr, null, XmlSpace.None);
593 XmlTextReader xtr = new XmlTextReader(Encoding.ASCII.GetString(data), XmlNodeType.Document, context); 827 XmlTextReader xtr = new XmlTextReader(Encoding.ASCII.GetString(data), XmlNodeType.Document, context);
594 828
595 RegionSettings currentRegionSettings = m_scene.RegionInfo.RegionSettings; 829 // Loaded metadata will be empty if no information exists in the archive
830 dearchivedScenes.LoadedCreationDateTime = 0;
831 dearchivedScenes.DefaultOriginalID = "";
596 832
597 // Loaded metadata will empty if no information exists in the archive 833 bool multiRegion = false;
598 currentRegionSettings.LoadedCreationDateTime = 0;
599 currentRegionSettings.LoadedCreationID = "";
600 834
601 while (xtr.Read()) 835 while (xtr.Read())
602 { 836 {
@@ -622,18 +856,44 @@ namespace OpenSim.Region.CoreModules.World.Archiver
622 { 856 {
623 int value; 857 int value;
624 if (Int32.TryParse(xtr.ReadElementContentAsString(), out value)) 858 if (Int32.TryParse(xtr.ReadElementContentAsString(), out value))
625 currentRegionSettings.LoadedCreationDateTime = value; 859 dearchivedScenes.LoadedCreationDateTime = value;
626 } 860 }
627 else if (xtr.Name.ToString() == "id") 861 else if (xtr.Name.ToString() == "row")
862 {
863 multiRegion = true;
864 dearchivedScenes.StartRow();
865 }
866 else if (xtr.Name.ToString() == "region")
867 {
868 dearchivedScenes.StartRegion();
869 }
870 else if (xtr.Name.ToString() == "id")
871 {
872 string id = xtr.ReadElementContentAsString();
873 dearchivedScenes.DefaultOriginalID = id;
874 if (multiRegion)
875 dearchivedScenes.SetRegionOriginalID(id);
876 }
877 else if (xtr.Name.ToString() == "dir")
628 { 878 {
629 currentRegionSettings.LoadedCreationID = xtr.ReadElementContentAsString(); 879 dearchivedScenes.SetRegionDirectory(xtr.ReadElementContentAsString());
630 } 880 }
631 } 881 }
632 } 882 }
633 883
634 currentRegionSettings.Save(); 884 dearchivedScenes.MultiRegionFormat = multiRegion;
635 885 if (!multiRegion)
886 {
887 // Add the single scene
888 dearchivedScenes.StartRow();
889 dearchivedScenes.StartRegion();
890 dearchivedScenes.SetRegionOriginalID(dearchivedScenes.DefaultOriginalID);
891 dearchivedScenes.SetRegionDirectory("");
892 }
893
636 ControlFileLoaded = true; 894 ControlFileLoaded = true;
895
896 return dearchivedScenes;
637 } 897 }
638 } 898 }
639} \ No newline at end of file 899}
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveScenesGroup.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveScenesGroup.cs
new file mode 100644
index 0000000..a66ed88
--- /dev/null
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveScenesGroup.cs
@@ -0,0 +1,176 @@
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.Linq;
31using System.Text;
32using OpenSim.Region.Framework.Scenes;
33using OpenMetaverse;
34using System.Drawing;
35
36namespace OpenSim.Region.CoreModules.World.Archiver
37{
38 /// <summary>
39 /// A group of regions arranged in a rectangle, possibly with holes.
40 /// </summary>
41 /// <remarks>
42 /// The regions usually (but not necessarily) belong to an archive file, in which case we
43 /// store additional information used to create the archive (e.g., each region's
44 /// directory within the archive).
45 /// </remarks>
46 public class ArchiveScenesGroup
47 {
48 /// <summary>
49 /// All the regions. The outer dictionary contains rows (key: Y coordinate).
50 /// The inner dictionaries contain each row's regions (key: X coordinate).
51 /// </summary>
52 public SortedDictionary<uint, SortedDictionary<uint, Scene>> Regions { get; set; }
53
54 /// <summary>
55 /// The subdirectory where each region is stored in the archive.
56 /// </summary>
57 protected Dictionary<UUID, string> m_regionDirs;
58
59 /// <summary>
60 /// The grid coordinates of the regions' bounding box.
61 /// </summary>
62 public Rectangle Rect { get; set; }
63
64
65 public ArchiveScenesGroup()
66 {
67 Regions = new SortedDictionary<uint, SortedDictionary<uint, Scene>>();
68 m_regionDirs = new Dictionary<UUID, string>();
69 Rect = new Rectangle(0, 0, 0, 0);
70 }
71
72 public void AddScene(Scene scene)
73 {
74 uint x = scene.RegionInfo.RegionLocX;
75 uint y = scene.RegionInfo.RegionLocY;
76
77 SortedDictionary<uint, Scene> row;
78 if (!Regions.TryGetValue(y, out row))
79 {
80 row = new SortedDictionary<uint, Scene>();
81 Regions[y] = row;
82 }
83
84 row[x] = scene;
85 }
86
87 /// <summary>
88 /// Called after all the scenes have been added. Performs calculations that require
89 /// knowledge of all the scenes.
90 /// </summary>
91 public void CalcSceneLocations()
92 {
93 if (Regions.Count == 0)
94 return;
95
96 // Find the bounding rectangle
97
98 uint firstY = Regions.First().Key;
99 uint lastY = Regions.Last().Key;
100
101 uint? firstX = null;
102 uint? lastX = null;
103
104 foreach (SortedDictionary<uint, Scene> row in Regions.Values)
105 {
106 uint curFirstX = row.First().Key;
107 uint curLastX = row.Last().Key;
108
109 firstX = (firstX == null) ? curFirstX : (firstX < curFirstX) ? firstX : curFirstX;
110 lastX = (lastX == null) ? curLastX : (lastX > curLastX) ? lastX : curLastX;
111 }
112
113 Rect = new Rectangle((int)firstX, (int)firstY, (int)(lastY - firstY + 1), (int)(lastX - firstX + 1));
114
115
116 // Calculate the subdirectory in which each region will be stored in the archive
117
118 m_regionDirs.Clear();
119 ForEachScene(delegate(Scene scene)
120 {
121 // We add the region's coordinates to ensure uniqueness even if multiple regions have the same name
122 string path = string.Format("{0}_{1}_{2}",
123 scene.RegionInfo.RegionLocX - Rect.X + 1,
124 scene.RegionInfo.RegionLocY - Rect.Y + 1,
125 scene.RegionInfo.RegionName.Replace(' ', '_'));
126 m_regionDirs[scene.RegionInfo.RegionID] = path;
127 });
128 }
129
130 /// <summary>
131 /// Returns the subdirectory where the region is stored.
132 /// </summary>
133 /// <param name="regionID"></param>
134 /// <returns></returns>
135 public string GetRegionDir(UUID regionID)
136 {
137 return m_regionDirs[regionID];
138 }
139
140 /// <summary>
141 /// Performs an action on all the scenes in this order: rows from South to North,
142 /// and within each row West to East.
143 /// </summary>
144 /// <param name="action"></param>
145 public void ForEachScene(Action<Scene> action)
146 {
147 foreach (SortedDictionary<uint, Scene> row in Regions.Values)
148 {
149 foreach (Scene scene in row.Values)
150 {
151 action(scene);
152 }
153 }
154 }
155
156 /// <summary>
157 /// Returns the scene at position 'location'.
158 /// </summary>
159 /// <param name="location">A location in the grid</param>
160 /// <param name="scene">The scene at this location</param>
161 /// <returns>Whether the scene was found</returns>
162 public bool TryGetScene(Point location, out Scene scene)
163 {
164 SortedDictionary<uint, Scene> row;
165 if (Regions.TryGetValue((uint)location.Y, out row))
166 {
167 if (row.TryGetValue((uint)location.X, out scene))
168 return true;
169 }
170
171 scene = null;
172 return false;
173 }
174
175 }
176}
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs
new file mode 100644
index 0000000..d751b1c
--- /dev/null
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs
@@ -0,0 +1,634 @@
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.IO.Compression;
32using System.Reflection;
33using System.Text.RegularExpressions;
34using System.Threading;
35using System.Xml;
36using log4net;
37using OpenMetaverse;
38using OpenSim.Framework;
39using OpenSim.Framework.Serialization;
40using OpenSim.Region.CoreModules.World.Terrain;
41using OpenSim.Region.Framework.Interfaces;
42using OpenSim.Region.Framework.Scenes;
43using Ionic.Zlib;
44using GZipStream = Ionic.Zlib.GZipStream;
45using CompressionMode = Ionic.Zlib.CompressionMode;
46using OpenSim.Framework.Serialization.External;
47
48namespace OpenSim.Region.CoreModules.World.Archiver
49{
50 /// <summary>
51 /// Prepare to write out an archive.
52 /// </summary>
53 public class ArchiveWriteRequest
54 {
55 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
56
57 /// <summary>
58 /// The minimum major version of OAR that we can write.
59 /// </summary>
60 public static int MIN_MAJOR_VERSION = 0;
61
62 /// <summary>
63 /// The maximum major version of OAR that we can write.
64 /// </summary>
65 public static int MAX_MAJOR_VERSION = 1;
66
67 /// <summary>
68 /// Whether we're saving a multi-region archive.
69 /// </summary>
70 public bool MultiRegionFormat { get; set; }
71
72 /// <summary>
73 /// Determine whether this archive will save assets. Default is true.
74 /// </summary>
75 public bool SaveAssets { get; set; }
76
77 /// <summary>
78 /// Determines which objects will be included in the archive, according to their permissions.
79 /// Default is null, meaning no permission checks.
80 /// </summary>
81 public string CheckPermissions { get; set; }
82
83 protected Scene m_rootScene;
84 protected Stream m_saveStream;
85 protected TarArchiveWriter m_archiveWriter;
86 protected Guid m_requestId;
87 protected Dictionary<string, object> m_options;
88
89 /// <summary>
90 /// Constructor
91 /// </summary>
92 /// <param name="module">Calling module</param>
93 /// <param name="savePath">The path to which to save data.</param>
94 /// <param name="requestId">The id associated with this request</param>
95 /// <exception cref="System.IO.IOException">
96 /// If there was a problem opening a stream for the file specified by the savePath
97 /// </exception>
98 public ArchiveWriteRequest(Scene scene, string savePath, Guid requestId) : this(scene, requestId)
99 {
100 try
101 {
102 m_saveStream = new GZipStream(new FileStream(savePath, FileMode.Create), CompressionMode.Compress, CompressionLevel.BestCompression);
103 }
104 catch (EntryPointNotFoundException e)
105 {
106 m_log.ErrorFormat(
107 "[ARCHIVER]: Mismatch between Mono and zlib1g library version when trying to create compression stream."
108 + "If you've manually installed Mono, have you appropriately updated zlib1g as well?");
109 m_log.ErrorFormat("{0} {1}", e.Message, e.StackTrace);
110 }
111 }
112
113 /// <summary>
114 /// Constructor.
115 /// </summary>
116 /// <param name="scene">The root scene to archive</param>
117 /// <param name="saveStream">The stream to which to save data.</param>
118 /// <param name="requestId">The id associated with this request</param>
119 public ArchiveWriteRequest(Scene scene, Stream saveStream, Guid requestId) : this(scene, requestId)
120 {
121 m_saveStream = saveStream;
122 }
123
124 protected ArchiveWriteRequest(Scene scene, Guid requestId)
125 {
126 m_rootScene = scene;
127 m_requestId = requestId;
128 m_archiveWriter = null;
129
130 MultiRegionFormat = false;
131 SaveAssets = true;
132 CheckPermissions = null;
133 }
134
135 /// <summary>
136 /// Archive the region requested.
137 /// </summary>
138 /// <exception cref="System.IO.IOException">if there was an io problem with creating the file</exception>
139 public void ArchiveRegion(Dictionary<string, object> options)
140 {
141 m_options = options;
142
143 if (options.ContainsKey("all") && (bool)options["all"])
144 MultiRegionFormat = true;
145
146 if (options.ContainsKey("noassets") && (bool)options["noassets"])
147 SaveAssets = false;
148
149 Object temp;
150 if (options.TryGetValue("checkPermissions", out temp))
151 CheckPermissions = (string)temp;
152
153
154 // Find the regions to archive
155 ArchiveScenesGroup scenesGroup = new ArchiveScenesGroup();
156 if (MultiRegionFormat)
157 {
158 m_log.InfoFormat("[ARCHIVER]: Saving {0} regions", SceneManager.Instance.Scenes.Count);
159 SceneManager.Instance.ForEachScene(delegate(Scene scene)
160 {
161 scenesGroup.AddScene(scene);
162 });
163 }
164 else
165 {
166 scenesGroup.AddScene(m_rootScene);
167 }
168 scenesGroup.CalcSceneLocations();
169
170
171 m_archiveWriter = new TarArchiveWriter(m_saveStream);
172
173 try
174 {
175 // Write out control file. It should be first so that it will be found ASAP when loading the file.
176 m_archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, CreateControlFile(scenesGroup));
177 m_log.InfoFormat("[ARCHIVER]: Added control file to archive.");
178
179 // Archive the regions
180
181 Dictionary<UUID, AssetType> assetUuids = new Dictionary<UUID, AssetType>();
182
183 scenesGroup.ForEachScene(delegate(Scene scene)
184 {
185 string regionDir = MultiRegionFormat ? scenesGroup.GetRegionDir(scene.RegionInfo.RegionID) : "";
186 ArchiveOneRegion(scene, regionDir, assetUuids);
187 });
188
189 // Archive the assets
190
191 if (SaveAssets)
192 {
193 m_log.DebugFormat("[ARCHIVER]: Saving {0} assets", assetUuids.Count);
194
195 // Asynchronously request all the assets required to perform this archive operation
196 AssetsRequest ar
197 = new AssetsRequest(
198 new AssetsArchiver(m_archiveWriter), assetUuids,
199 m_rootScene.AssetService, m_rootScene.UserAccountService,
200 m_rootScene.RegionInfo.ScopeID, options, ReceivedAllAssets);
201
202 Util.FireAndForget(o => ar.Execute());
203
204 // CloseArchive() will be called from ReceivedAllAssets()
205 }
206 else
207 {
208 m_log.DebugFormat("[ARCHIVER]: Not saving assets since --noassets was specified");
209 CloseArchive(string.Empty);
210 }
211 }
212 catch (Exception e)
213 {
214 CloseArchive(e.Message);
215 throw;
216 }
217 }
218
219
220 private void ArchiveOneRegion(Scene scene, string regionDir, Dictionary<UUID, AssetType> assetUuids)
221 {
222 m_log.InfoFormat("[ARCHIVER]: Writing region {0}", scene.RegionInfo.RegionName);
223
224 EntityBase[] entities = scene.GetEntities();
225 List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>();
226
227 int numObjectsSkippedPermissions = 0;
228
229 // Filter entities so that we only have scene objects.
230 // FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods
231 // end up having to do this
232 IPermissionsModule permissionsModule = scene.RequestModuleInterface<IPermissionsModule>();
233 foreach (EntityBase entity in entities)
234 {
235 if (entity is SceneObjectGroup)
236 {
237 SceneObjectGroup sceneObject = (SceneObjectGroup)entity;
238
239 if (!sceneObject.IsDeleted && !sceneObject.IsAttachment)
240 {
241 if (!CanUserArchiveObject(scene.RegionInfo.EstateSettings.EstateOwner, sceneObject, CheckPermissions, permissionsModule))
242 {
243 // The user isn't allowed to copy/transfer this object, so it will not be included in the OAR.
244 ++numObjectsSkippedPermissions;
245 }
246 else
247 {
248 sceneObjects.Add(sceneObject);
249 }
250 }
251 }
252 }
253
254 if (SaveAssets)
255 {
256 UuidGatherer assetGatherer = new UuidGatherer(scene.AssetService);
257 int prevAssets = assetUuids.Count;
258
259 foreach (SceneObjectGroup sceneObject in sceneObjects)
260 {
261 assetGatherer.GatherAssetUuids(sceneObject, assetUuids);
262 }
263
264 m_log.DebugFormat(
265 "[ARCHIVER]: {0} scene objects to serialize requiring save of {1} assets",
266 sceneObjects.Count, assetUuids.Count - prevAssets);
267 }
268
269 if (numObjectsSkippedPermissions > 0)
270 {
271 m_log.DebugFormat(
272 "[ARCHIVER]: {0} scene objects skipped due to lack of permissions",
273 numObjectsSkippedPermissions);
274 }
275
276 // Make sure that we also request terrain texture assets
277 RegionSettings regionSettings = scene.RegionInfo.RegionSettings;
278
279 if (regionSettings.TerrainTexture1 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_1)
280 assetUuids[regionSettings.TerrainTexture1] = AssetType.Texture;
281
282 if (regionSettings.TerrainTexture2 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_2)
283 assetUuids[regionSettings.TerrainTexture2] = AssetType.Texture;
284
285 if (regionSettings.TerrainTexture3 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_3)
286 assetUuids[regionSettings.TerrainTexture3] = AssetType.Texture;
287
288 if (regionSettings.TerrainTexture4 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_4)
289 assetUuids[regionSettings.TerrainTexture4] = AssetType.Texture;
290
291 Save(scene, sceneObjects, regionDir);
292 }
293
294 /// <summary>
295 /// Checks whether the user has permission to export an object group to an OAR.
296 /// </summary>
297 /// <param name="user">The user</param>
298 /// <param name="objGroup">The object group</param>
299 /// <param name="checkPermissions">Which permissions to check: "C" = Copy, "T" = Transfer</param>
300 /// <param name="permissionsModule">The scene's permissions module</param>
301 /// <returns>Whether the user is allowed to export the object to an OAR</returns>
302 private bool CanUserArchiveObject(UUID user, SceneObjectGroup objGroup, string checkPermissions, IPermissionsModule permissionsModule)
303 {
304 if (checkPermissions == null)
305 return true;
306
307 if (permissionsModule == null)
308 return true; // this shouldn't happen
309
310 // Check whether the user is permitted to export all of the parts in the SOG. If any
311 // part can't be exported then the entire SOG can't be exported.
312
313 bool permitted = true;
314 //int primNumber = 1;
315
316 foreach (SceneObjectPart obj in objGroup.Parts)
317 {
318 uint perm;
319 PermissionClass permissionClass = permissionsModule.GetPermissionClass(user, obj);
320 switch (permissionClass)
321 {
322 case PermissionClass.Owner:
323 perm = obj.BaseMask;
324 break;
325 case PermissionClass.Group:
326 perm = obj.GroupMask | obj.EveryoneMask;
327 break;
328 case PermissionClass.Everyone:
329 default:
330 perm = obj.EveryoneMask;
331 break;
332 }
333
334 bool canCopy = (perm & (uint)PermissionMask.Copy) != 0;
335 bool canTransfer = (perm & (uint)PermissionMask.Transfer) != 0;
336
337 // Special case: if Everyone can copy the object then this implies it can also be
338 // Transferred.
339 // However, if the user is the Owner then we don't check EveryoneMask, because it seems that the mask
340 // always (incorrectly) includes the Copy bit set in this case. But that's a mistake: the viewer
341 // does NOT show that the object has Everyone-Copy permissions, and doesn't allow it to be copied.
342 if (permissionClass != PermissionClass.Owner)
343 canTransfer |= (obj.EveryoneMask & (uint)PermissionMask.Copy) != 0;
344
345 bool partPermitted = true;
346 if (checkPermissions.Contains("C") && !canCopy)
347 partPermitted = false;
348 if (checkPermissions.Contains("T") && !canTransfer)
349 partPermitted = false;
350
351 // If the user is the Creator of the object then it can always be included in the OAR
352 bool creator = (obj.CreatorID.Guid == user.Guid);
353 if (creator)
354 partPermitted = true;
355
356 //string name = (objGroup.PrimCount == 1) ? objGroup.Name : string.Format("{0} ({1}/{2})", obj.Name, primNumber, objGroup.PrimCount);
357 //m_log.DebugFormat("[ARCHIVER]: Object permissions: {0}: Base={1:X4}, Owner={2:X4}, Everyone={3:X4}, permissionClass={4}, checkPermissions={5}, canCopy={6}, canTransfer={7}, creator={8}, permitted={9}",
358 // name, obj.BaseMask, obj.OwnerMask, obj.EveryoneMask,
359 // permissionClass, checkPermissions, canCopy, canTransfer, creator, partPermitted);
360
361 if (!partPermitted)
362 {
363 permitted = false;
364 break;
365 }
366
367 //++primNumber;
368 }
369
370 return permitted;
371 }
372
373 /// <summary>
374 /// Create the control file.
375 /// </summary>
376 /// <returns></returns>
377 public string CreateControlFile(ArchiveScenesGroup scenesGroup)
378 {
379 int majorVersion;
380 int minorVersion;
381
382 if (MultiRegionFormat)
383 {
384 majorVersion = MAX_MAJOR_VERSION;
385 minorVersion = 0;
386 }
387 else
388 {
389 // To support older versions of OpenSim, we continue to create single-region OARs
390 // using the old file format. In the future this format will be discontinued.
391 majorVersion = 0;
392 minorVersion = 8;
393 }
394//
395// if (m_options.ContainsKey("version"))
396// {
397// string[] parts = m_options["version"].ToString().Split('.');
398// if (parts.Length >= 1)
399// {
400// majorVersion = Int32.Parse(parts[0]);
401//
402// if (parts.Length >= 2)
403// minorVersion = Int32.Parse(parts[1]);
404// }
405// }
406//
407// if (majorVersion < MIN_MAJOR_VERSION || majorVersion > MAX_MAJOR_VERSION)
408// {
409// throw new Exception(
410// string.Format(
411// "OAR version number for save must be between {0} and {1}",
412// MIN_MAJOR_VERSION, MAX_MAJOR_VERSION));
413// }
414// else if (majorVersion == MAX_MAJOR_VERSION)
415// {
416// // Force 1.0
417// minorVersion = 0;
418// }
419// else if (majorVersion == MIN_MAJOR_VERSION)
420// {
421// // Force 0.4
422// minorVersion = 4;
423// }
424
425 m_log.InfoFormat("[ARCHIVER]: Creating version {0}.{1} OAR", majorVersion, minorVersion);
426 if (majorVersion == 1)
427 {
428 m_log.WarnFormat("[ARCHIVER]: Please be aware that version 1.0 OARs are not compatible with OpenSim versions prior to 0.7.4. Do not use the --all option if you want to produce a compatible OAR");
429 }
430
431 String s;
432
433 using (StringWriter sw = new StringWriter())
434 {
435 using (XmlTextWriter xtw = new XmlTextWriter(sw))
436 {
437 xtw.Formatting = Formatting.Indented;
438 xtw.WriteStartDocument();
439 xtw.WriteStartElement("archive");
440 xtw.WriteAttributeString("major_version", majorVersion.ToString());
441 xtw.WriteAttributeString("minor_version", minorVersion.ToString());
442
443 xtw.WriteStartElement("creation_info");
444 DateTime now = DateTime.UtcNow;
445 TimeSpan t = now - new DateTime(1970, 1, 1);
446 xtw.WriteElementString("datetime", ((int)t.TotalSeconds).ToString());
447 if (!MultiRegionFormat)
448 xtw.WriteElementString("id", m_rootScene.RegionInfo.RegionID.ToString());
449 xtw.WriteEndElement();
450
451 xtw.WriteElementString("assets_included", SaveAssets.ToString());
452
453 if (MultiRegionFormat)
454 {
455 WriteRegionsManifest(scenesGroup, xtw);
456 }
457 else
458 {
459 xtw.WriteStartElement("region_info");
460 WriteRegionInfo(m_rootScene, xtw);
461 xtw.WriteEndElement();
462 }
463
464 xtw.WriteEndElement();
465
466 xtw.Flush();
467 }
468
469 s = sw.ToString();
470 }
471
472 return s;
473 }
474
475 /// <summary>
476 /// Writes the list of regions included in a multi-region OAR.
477 /// </summary>
478 private static void WriteRegionsManifest(ArchiveScenesGroup scenesGroup, XmlTextWriter xtw)
479 {
480 xtw.WriteStartElement("regions");
481
482 // Write the regions in order: rows from South to North, then regions from West to East.
483 // The list of regions can have "holes"; we write empty elements in their position.
484
485 for (uint y = (uint)scenesGroup.Rect.Top; y < scenesGroup.Rect.Bottom; ++y)
486 {
487 SortedDictionary<uint, Scene> row;
488 if (scenesGroup.Regions.TryGetValue(y, out row))
489 {
490 xtw.WriteStartElement("row");
491
492 for (uint x = (uint)scenesGroup.Rect.Left; x < scenesGroup.Rect.Right; ++x)
493 {
494 Scene scene;
495 if (row.TryGetValue(x, out scene))
496 {
497 xtw.WriteStartElement("region");
498 xtw.WriteElementString("id", scene.RegionInfo.RegionID.ToString());
499 xtw.WriteElementString("dir", scenesGroup.GetRegionDir(scene.RegionInfo.RegionID));
500 WriteRegionInfo(scene, xtw);
501 xtw.WriteEndElement();
502 }
503 else
504 {
505 // Write a placeholder for a missing region
506 xtw.WriteElementString("region", "");
507 }
508 }
509
510 xtw.WriteEndElement();
511 }
512 else
513 {
514 // Write a placeholder for a missing row
515 xtw.WriteElementString("row", "");
516 }
517 }
518
519 xtw.WriteEndElement(); // "regions"
520 }
521
522 protected static void WriteRegionInfo(Scene scene, XmlTextWriter xtw)
523 {
524 bool isMegaregion;
525 Vector2 size;
526
527 IRegionCombinerModule rcMod = scene.RequestModuleInterface<IRegionCombinerModule>();
528
529 if (rcMod != null)
530 isMegaregion = rcMod.IsRootForMegaregion(scene.RegionInfo.RegionID);
531 else
532 isMegaregion = false;
533
534 if (isMegaregion)
535 size = rcMod.GetSizeOfMegaregion(scene.RegionInfo.RegionID);
536 else
537 size = new Vector2((float)Constants.RegionSize, (float)Constants.RegionSize);
538
539 xtw.WriteElementString("is_megaregion", isMegaregion.ToString());
540 xtw.WriteElementString("size_in_meters", string.Format("{0},{1}", size.X, size.Y));
541 }
542
543
544 protected void Save(Scene scene, List<SceneObjectGroup> sceneObjects, string regionDir)
545 {
546 if (regionDir != string.Empty)
547 regionDir = ArchiveConstants.REGIONS_PATH + regionDir + "/";
548
549 m_log.InfoFormat("[ARCHIVER]: Adding region settings to archive.");
550
551 // Write out region settings
552 string settingsPath = String.Format("{0}{1}{2}.xml",
553 regionDir, ArchiveConstants.SETTINGS_PATH, scene.RegionInfo.RegionName);
554 m_archiveWriter.WriteFile(settingsPath, RegionSettingsSerializer.Serialize(scene.RegionInfo.RegionSettings));
555
556 m_log.InfoFormat("[ARCHIVER]: Adding parcel settings to archive.");
557
558 // Write out land data (aka parcel) settings
559 List<ILandObject> landObjects = scene.LandChannel.AllParcels();
560 foreach (ILandObject lo in landObjects)
561 {
562 LandData landData = lo.LandData;
563 string landDataPath = String.Format("{0}{1}{2}.xml",
564 regionDir, ArchiveConstants.LANDDATA_PATH, landData.GlobalID.ToString());
565 m_archiveWriter.WriteFile(landDataPath, LandDataSerializer.Serialize(landData, m_options));
566 }
567
568 m_log.InfoFormat("[ARCHIVER]: Adding terrain information to archive.");
569
570 // Write out terrain
571 string terrainPath = String.Format("{0}{1}{2}.r32",
572 regionDir, ArchiveConstants.TERRAINS_PATH, scene.RegionInfo.RegionName);
573
574 MemoryStream ms = new MemoryStream();
575 scene.RequestModuleInterface<ITerrainModule>().SaveToStream(terrainPath, ms);
576 m_archiveWriter.WriteFile(terrainPath, ms.ToArray());
577 ms.Close();
578
579 m_log.InfoFormat("[ARCHIVER]: Adding scene objects to archive.");
580
581 // Write out scene object metadata
582 IRegionSerialiserModule serializer = scene.RequestModuleInterface<IRegionSerialiserModule>();
583 foreach (SceneObjectGroup sceneObject in sceneObjects)
584 {
585 //m_log.DebugFormat("[ARCHIVER]: Saving {0} {1}, {2}", entity.Name, entity.UUID, entity.GetType());
586
587 string serializedObject = serializer.SerializeGroupToXml2(sceneObject, m_options);
588 string objectPath = string.Format("{0}{1}", regionDir, ArchiveHelpers.CreateObjectPath(sceneObject));
589 m_archiveWriter.WriteFile(objectPath, serializedObject);
590 }
591 }
592
593 protected void ReceivedAllAssets(
594 ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids)
595 {
596 foreach (UUID uuid in assetsNotFoundUuids)
597 {
598 m_log.DebugFormat("[ARCHIVER]: Could not find asset {0}", uuid);
599 }
600
601 // m_log.InfoFormat(
602 // "[ARCHIVER]: Received {0} of {1} assets requested",
603 // assetsFoundUuids.Count, assetsFoundUuids.Count + assetsNotFoundUuids.Count);
604
605 CloseArchive(String.Empty);
606 }
607
608
609 /// <summary>
610 /// Closes the archive and notifies that we're done.
611 /// </summary>
612 /// <param name="errorMessage">The error that occurred, or empty for success</param>
613 protected void CloseArchive(string errorMessage)
614 {
615 try
616 {
617 if (m_archiveWriter != null)
618 m_archiveWriter.Close();
619 m_saveStream.Close();
620 }
621 catch (Exception e)
622 {
623 m_log.Error(string.Format("[ARCHIVER]: Error closing archive: {0} ", e.Message), e);
624 if (errorMessage == string.Empty)
625 errorMessage = e.Message;
626 }
627
628 m_log.InfoFormat("[ARCHIVER]: Finished writing out OAR for {0}", m_rootScene.RegionInfo.RegionName);
629
630 m_rootScene.EventManager.TriggerOarFileSaved(m_requestId, errorMessage);
631 }
632
633 }
634}
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestExecution.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestExecution.cs
deleted file mode 100644
index 0780d86..0000000
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestExecution.cs
+++ /dev/null
@@ -1,153 +0,0 @@
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.Xml;
33using log4net;
34using OpenMetaverse;
35using OpenSim.Framework;
36using OpenSim.Framework.Serialization;
37using OpenSim.Framework.Serialization.External;
38using OpenSim.Region.CoreModules.World.Terrain;
39using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes;
41
42namespace OpenSim.Region.CoreModules.World.Archiver
43{
44 /// <summary>
45 /// Method called when all the necessary assets for an archive request have been received.
46 /// </summary>
47 public delegate void AssetsRequestCallback(
48 ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids);
49
50 /// <summary>
51 /// Execute the write of an archive once we have received all the necessary data
52 /// </summary>
53 public class ArchiveWriteRequestExecution
54 {
55 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
56
57 protected ITerrainModule m_terrainModule;
58 protected IRegionSerialiserModule m_serialiser;
59 protected List<SceneObjectGroup> m_sceneObjects;
60 protected Scene m_scene;
61 protected TarArchiveWriter m_archiveWriter;
62 protected Guid m_requestId;
63 protected Dictionary<string, object> m_options;
64
65 public ArchiveWriteRequestExecution(
66 List<SceneObjectGroup> sceneObjects,
67 ITerrainModule terrainModule,
68 IRegionSerialiserModule serialiser,
69 Scene scene,
70 TarArchiveWriter archiveWriter,
71 Guid requestId,
72 Dictionary<string, object> options)
73 {
74 m_sceneObjects = sceneObjects;
75 m_terrainModule = terrainModule;
76 m_serialiser = serialiser;
77 m_scene = scene;
78 m_archiveWriter = archiveWriter;
79 m_requestId = requestId;
80 m_options = options;
81 }
82
83 protected internal void ReceivedAllAssets(
84 ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids)
85 {
86 try
87 {
88 Save(assetsFoundUuids, assetsNotFoundUuids);
89 }
90 finally
91 {
92 m_archiveWriter.Close();
93 }
94
95 m_log.InfoFormat("[ARCHIVER]: Finished writing out OAR for {0}", m_scene.RegionInfo.RegionName);
96
97 m_scene.EventManager.TriggerOarFileSaved(m_requestId, String.Empty);
98 }
99
100 protected internal void Save(ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids)
101 {
102 foreach (UUID uuid in assetsNotFoundUuids)
103 {
104 m_log.DebugFormat("[ARCHIVER]: Could not find asset {0}", uuid);
105 }
106
107// m_log.InfoFormat(
108// "[ARCHIVER]: Received {0} of {1} assets requested",
109// assetsFoundUuids.Count, assetsFoundUuids.Count + assetsNotFoundUuids.Count);
110
111 m_log.InfoFormat("[ARCHIVER]: Adding region settings to archive.");
112
113 // Write out region settings
114 string settingsPath
115 = String.Format("{0}{1}.xml", ArchiveConstants.SETTINGS_PATH, m_scene.RegionInfo.RegionName);
116 m_archiveWriter.WriteFile(settingsPath, RegionSettingsSerializer.Serialize(m_scene.RegionInfo.RegionSettings));
117
118 m_log.InfoFormat("[ARCHIVER]: Adding parcel settings to archive.");
119
120 // Write out land data (aka parcel) settings
121 List<ILandObject>landObjects = m_scene.LandChannel.AllParcels();
122 foreach (ILandObject lo in landObjects)
123 {
124 LandData landData = lo.LandData;
125 string landDataPath = String.Format("{0}{1}.xml", ArchiveConstants.LANDDATA_PATH,
126 landData.GlobalID.ToString());
127 m_archiveWriter.WriteFile(landDataPath, LandDataSerializer.Serialize(landData, m_options));
128 }
129
130 m_log.InfoFormat("[ARCHIVER]: Adding terrain information to archive.");
131
132 // Write out terrain
133 string terrainPath
134 = String.Format("{0}{1}.r32", ArchiveConstants.TERRAINS_PATH, m_scene.RegionInfo.RegionName);
135
136 MemoryStream ms = new MemoryStream();
137 m_terrainModule.SaveToStream(terrainPath, ms);
138 m_archiveWriter.WriteFile(terrainPath, ms.ToArray());
139 ms.Close();
140
141 m_log.InfoFormat("[ARCHIVER]: Adding scene objects to archive.");
142
143 // Write out scene object metadata
144 foreach (SceneObjectGroup sceneObject in m_sceneObjects)
145 {
146 //m_log.DebugFormat("[ARCHIVER]: Saving {0} {1}, {2}", entity.Name, entity.UUID, entity.GetType());
147
148 string serializedObject = m_serialiser.SerializeGroupToXml2(sceneObject, m_options);
149 m_archiveWriter.WriteFile(ArchiveHelpers.CreateObjectPath(sceneObject), serializedObject);
150 }
151 }
152 }
153} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs
deleted file mode 100644
index 4edaaca..0000000
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs
+++ /dev/null
@@ -1,438 +0,0 @@
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.IO.Compression;
32using System.Reflection;
33using System.Text.RegularExpressions;
34using System.Threading;
35using System.Xml;
36using log4net;
37using OpenMetaverse;
38using OpenSim.Framework;
39using OpenSim.Framework.Serialization;
40using OpenSim.Region.CoreModules.World.Terrain;
41using OpenSim.Region.Framework.Interfaces;
42using OpenSim.Region.Framework.Scenes;
43using Ionic.Zlib;
44using GZipStream = Ionic.Zlib.GZipStream;
45using CompressionMode = Ionic.Zlib.CompressionMode;
46
47namespace OpenSim.Region.CoreModules.World.Archiver
48{
49 /// <summary>
50 /// Prepare to write out an archive.
51 /// </summary>
52 public class ArchiveWriteRequestPreparation
53 {
54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55
56 /// <summary>
57 /// The minimum major version of OAR that we can write.
58 /// </summary>
59 public static int MIN_MAJOR_VERSION = 0;
60
61 /// <summary>
62 /// The maximum major version of OAR that we can write.
63 /// </summary>
64 public static int MAX_MAJOR_VERSION = 0;
65
66 /// <summary>
67 /// Determine whether this archive will save assets. Default is true.
68 /// </summary>
69 public bool SaveAssets { get; set; }
70
71 protected ArchiverModule m_module;
72 protected Scene m_scene;
73 protected Stream m_saveStream;
74 protected Guid m_requestId;
75
76 /// <summary>
77 /// Constructor
78 /// </summary>
79 /// <param name="module">Calling module</param>
80 /// <param name="savePath">The path to which to save data.</param>
81 /// <param name="requestId">The id associated with this request</param>
82 /// <exception cref="System.IO.IOException">
83 /// If there was a problem opening a stream for the file specified by the savePath
84 /// </exception>
85 public ArchiveWriteRequestPreparation(ArchiverModule module, string savePath, Guid requestId) : this(module, requestId)
86 {
87 try
88 {
89 m_saveStream = new GZipStream(new FileStream(savePath, FileMode.Create), CompressionMode.Compress, CompressionLevel.BestCompression);
90 }
91 catch (EntryPointNotFoundException e)
92 {
93 m_log.ErrorFormat(
94 "[ARCHIVER]: Mismatch between Mono and zlib1g library version when trying to create compression stream."
95 + "If you've manually installed Mono, have you appropriately updated zlib1g as well?");
96 m_log.ErrorFormat("{0} {1}", e.Message, e.StackTrace);
97 }
98 }
99
100 /// <summary>
101 /// Constructor.
102 /// </summary>
103 /// <param name="module">Calling module</param>
104 /// <param name="saveStream">The stream to which to save data.</param>
105 /// <param name="requestId">The id associated with this request</param>
106 public ArchiveWriteRequestPreparation(ArchiverModule module, Stream saveStream, Guid requestId) : this(module, requestId)
107 {
108 m_saveStream = saveStream;
109 }
110
111 protected ArchiveWriteRequestPreparation(ArchiverModule module, Guid requestId)
112 {
113 m_module = module;
114
115 // FIXME: This is only here for regression test purposes since they do not supply a module. Need to fix
116 // this.
117 if (m_module != null)
118 m_scene = m_module.Scene;
119
120 m_requestId = requestId;
121
122 SaveAssets = true;
123 }
124
125 /// <summary>
126 /// Archive the region requested.
127 /// </summary>
128 /// <exception cref="System.IO.IOException">if there was an io problem with creating the file</exception>
129 public void ArchiveRegion(Dictionary<string, object> options)
130 {
131 if (options.ContainsKey("noassets") && (bool)options["noassets"])
132 SaveAssets = false;
133
134 try
135 {
136 Dictionary<UUID, AssetType> assetUuids = new Dictionary<UUID, AssetType>();
137
138 EntityBase[] entities = m_scene.GetEntities();
139 List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>();
140
141 string checkPermissions = null;
142 int numObjectsSkippedPermissions = 0;
143 Object temp;
144 if (options.TryGetValue("checkPermissions", out temp))
145 checkPermissions = (string)temp;
146
147 // Filter entities so that we only have scene objects.
148 // FIXME: Would be nicer to have this as a proper list in SceneGraph, since lots of methods
149 // end up having to do this
150 foreach (EntityBase entity in entities)
151 {
152 if (entity is SceneObjectGroup)
153 {
154 SceneObjectGroup sceneObject = (SceneObjectGroup)entity;
155
156 if (!sceneObject.IsDeleted && !sceneObject.IsAttachment)
157 {
158 if (!CanUserArchiveObject(m_scene.RegionInfo.EstateSettings.EstateOwner, sceneObject, checkPermissions))
159 {
160 // The user isn't allowed to copy/transfer this object, so it will not be included in the OAR.
161 ++numObjectsSkippedPermissions;
162 }
163 else
164 {
165 sceneObjects.Add(sceneObject);
166 }
167 }
168 }
169 }
170
171 if (SaveAssets)
172 {
173 UuidGatherer assetGatherer = new UuidGatherer(m_scene.AssetService);
174
175 foreach (SceneObjectGroup sceneObject in sceneObjects)
176 {
177 assetGatherer.GatherAssetUuids(sceneObject, assetUuids);
178 }
179
180 m_log.DebugFormat(
181 "[ARCHIVER]: {0} scene objects to serialize requiring save of {1} assets",
182 sceneObjects.Count, assetUuids.Count);
183 }
184 else
185 {
186 m_log.DebugFormat("[ARCHIVER]: Not saving assets since --noassets was specified");
187 }
188
189 if (numObjectsSkippedPermissions > 0)
190 {
191 m_log.DebugFormat(
192 "[ARCHIVER]: {0} scene objects skipped due to lack of permissions",
193 numObjectsSkippedPermissions);
194 }
195
196 // Make sure that we also request terrain texture assets
197 RegionSettings regionSettings = m_scene.RegionInfo.RegionSettings;
198
199 if (regionSettings.TerrainTexture1 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_1)
200 assetUuids[regionSettings.TerrainTexture1] = AssetType.Texture;
201
202 if (regionSettings.TerrainTexture2 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_2)
203 assetUuids[regionSettings.TerrainTexture2] = AssetType.Texture;
204
205 if (regionSettings.TerrainTexture3 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_3)
206 assetUuids[regionSettings.TerrainTexture3] = AssetType.Texture;
207
208 if (regionSettings.TerrainTexture4 != RegionSettings.DEFAULT_TERRAIN_TEXTURE_4)
209 assetUuids[regionSettings.TerrainTexture4] = AssetType.Texture;
210
211 TarArchiveWriter archiveWriter = new TarArchiveWriter(m_saveStream);
212
213 // Asynchronously request all the assets required to perform this archive operation
214 ArchiveWriteRequestExecution awre
215 = new ArchiveWriteRequestExecution(
216 sceneObjects,
217 m_scene.RequestModuleInterface<ITerrainModule>(),
218 m_scene.RequestModuleInterface<IRegionSerialiserModule>(),
219 m_scene,
220 archiveWriter,
221 m_requestId,
222 options);
223
224 m_log.InfoFormat("[ARCHIVER]: Creating archive file. This may take some time.");
225
226 // Write out control file. This has to be done first so that subsequent loaders will see this file first
227 // XXX: I know this is a weak way of doing it since external non-OAR aware tar executables will not do this
228 archiveWriter.WriteFile(ArchiveConstants.CONTROL_FILE_PATH, CreateControlFile(options));
229 m_log.InfoFormat("[ARCHIVER]: Added control file to archive.");
230
231 if (SaveAssets)
232 {
233 AssetsRequest ar
234 = new AssetsRequest(
235 new AssetsArchiver(archiveWriter), assetUuids,
236 m_scene.AssetService, m_scene.UserAccountService,
237 m_scene.RegionInfo.ScopeID, options, awre.ReceivedAllAssets);
238
239 Util.FireAndForget(o => ar.Execute());
240 }
241 else
242 {
243 awre.ReceivedAllAssets(new List<UUID>(), new List<UUID>());
244 }
245 }
246 catch (Exception)
247 {
248 m_saveStream.Close();
249 throw;
250 }
251 }
252
253 /// <summary>
254 /// Checks whether the user has permission to export an object group to an OAR.
255 /// </summary>
256 /// <param name="user">The user</param>
257 /// <param name="objGroup">The object group</param>
258 /// <param name="checkPermissions">Which permissions to check: "C" = Copy, "T" = Transfer</param>
259 /// <returns>Whether the user is allowed to export the object to an OAR</returns>
260 private bool CanUserArchiveObject(UUID user, SceneObjectGroup objGroup, string checkPermissions)
261 {
262 if (checkPermissions == null)
263 return true;
264
265 IPermissionsModule module = m_scene.RequestModuleInterface<IPermissionsModule>();
266 if (module == null)
267 return true; // this shouldn't happen
268
269 // Check whether the user is permitted to export all of the parts in the SOG. If any
270 // part can't be exported then the entire SOG can't be exported.
271
272 bool permitted = true;
273 //int primNumber = 1;
274
275 foreach (SceneObjectPart obj in objGroup.Parts)
276 {
277 uint perm;
278 PermissionClass permissionClass = module.GetPermissionClass(user, obj);
279 switch (permissionClass)
280 {
281 case PermissionClass.Owner:
282 perm = obj.BaseMask;
283 break;
284 case PermissionClass.Group:
285 perm = obj.GroupMask | obj.EveryoneMask;
286 break;
287 case PermissionClass.Everyone:
288 default:
289 perm = obj.EveryoneMask;
290 break;
291 }
292
293 bool canCopy = (perm & (uint)PermissionMask.Copy) != 0;
294 bool canTransfer = (perm & (uint)PermissionMask.Transfer) != 0;
295
296 // Special case: if Everyone can copy the object then this implies it can also be
297 // Transferred.
298 // However, if the user is the Owner then we don't check EveryoneMask, because it seems that the mask
299 // always (incorrectly) includes the Copy bit set in this case. But that's a mistake: the viewer
300 // does NOT show that the object has Everyone-Copy permissions, and doesn't allow it to be copied.
301 if (permissionClass != PermissionClass.Owner)
302 canTransfer |= (obj.EveryoneMask & (uint)PermissionMask.Copy) != 0;
303
304 bool partPermitted = true;
305 if (checkPermissions.Contains("C") && !canCopy)
306 partPermitted = false;
307 if (checkPermissions.Contains("T") && !canTransfer)
308 partPermitted = false;
309
310 // If the user is the Creator of the object then it can always be included in the OAR
311 bool creator = (obj.CreatorID.Guid == user.Guid);
312 if (creator)
313 partPermitted = true;
314
315 //string name = (objGroup.PrimCount == 1) ? objGroup.Name : string.Format("{0} ({1}/{2})", obj.Name, primNumber, objGroup.PrimCount);
316 //m_log.DebugFormat("[ARCHIVER]: Object permissions: {0}: Base={1:X4}, Owner={2:X4}, Everyone={3:X4}, permissionClass={4}, checkPermissions={5}, canCopy={6}, canTransfer={7}, creator={8}, permitted={9}",
317 // name, obj.BaseMask, obj.OwnerMask, obj.EveryoneMask,
318 // permissionClass, checkPermissions, canCopy, canTransfer, creator, partPermitted);
319
320 if (!partPermitted)
321 {
322 permitted = false;
323 break;
324 }
325
326 //++primNumber;
327 }
328
329 return permitted;
330 }
331
332 /// <summary>
333 /// Create the control file for the most up to date archive
334 /// </summary>
335 /// <returns></returns>
336 public string CreateControlFile(Dictionary<string, object> options)
337 {
338 int majorVersion = MAX_MAJOR_VERSION, minorVersion = 8;
339//
340// if (options.ContainsKey("version"))
341// {
342// string[] parts = options["version"].ToString().Split('.');
343// if (parts.Length >= 1)
344// {
345// majorVersion = Int32.Parse(parts[0]);
346//
347// if (parts.Length >= 2)
348// minorVersion = Int32.Parse(parts[1]);
349// }
350// }
351//
352// if (majorVersion < MIN_MAJOR_VERSION || majorVersion > MAX_MAJOR_VERSION)
353// {
354// throw new Exception(
355// string.Format(
356// "OAR version number for save must be between {0} and {1}",
357// MIN_MAJOR_VERSION, MAX_MAJOR_VERSION));
358// }
359// else if (majorVersion == MAX_MAJOR_VERSION)
360// {
361// // Force 1.0
362// minorVersion = 0;
363// }
364// else if (majorVersion == MIN_MAJOR_VERSION)
365// {
366// // Force 0.4
367// minorVersion = 4;
368// }
369
370 m_log.InfoFormat("[ARCHIVER]: Creating version {0}.{1} OAR", majorVersion, minorVersion);
371 //if (majorVersion == 1)
372 //{
373 // m_log.WarnFormat("[ARCHIVER]: Please be aware that version 1.0 OARs are not compatible with OpenSim 0.7.0.2 and earlier. Please use the --version=0 option if you want to produce a compatible OAR");
374 //}
375
376 String s;
377
378 using (StringWriter sw = new StringWriter())
379 {
380 using (XmlTextWriter xtw = new XmlTextWriter(sw))
381 {
382 xtw.Formatting = Formatting.Indented;
383 xtw.WriteStartDocument();
384 xtw.WriteStartElement("archive");
385 xtw.WriteAttributeString("major_version", majorVersion.ToString());
386 xtw.WriteAttributeString("minor_version", minorVersion.ToString());
387
388 xtw.WriteStartElement("creation_info");
389 DateTime now = DateTime.UtcNow;
390 TimeSpan t = now - new DateTime(1970, 1, 1);
391 xtw.WriteElementString("datetime", ((int)t.TotalSeconds).ToString());
392 xtw.WriteElementString("id", UUID.Random().ToString());
393 xtw.WriteEndElement();
394
395 xtw.WriteStartElement("region_info");
396
397 bool isMegaregion;
398 Vector2 size;
399 IRegionCombinerModule rcMod = null;
400
401 // FIXME: This is only here for regression test purposes since they do not supply a module. Need to fix
402 // this, possibly by doing control file creation somewhere else.
403 if (m_module != null)
404 rcMod = m_module.RegionCombinerModule;
405
406 if (rcMod != null)
407 isMegaregion = rcMod.IsRootForMegaregion(m_scene.RegionInfo.RegionID);
408 else
409 isMegaregion = false;
410
411 if (isMegaregion)
412 size = rcMod.GetSizeOfMegaregion(m_scene.RegionInfo.RegionID);
413 else
414 size = new Vector2((float)Constants.RegionSize, (float)Constants.RegionSize);
415
416 xtw.WriteElementString("is_megaregion", isMegaregion.ToString());
417 xtw.WriteElementString("size_in_meters", string.Format("{0},{1}", size.X, size.Y));
418
419 xtw.WriteEndElement();
420
421 xtw.WriteElementString("assets_included", SaveAssets.ToString());
422
423 xtw.WriteEndElement();
424
425 xtw.Flush();
426 }
427
428 s = sw.ToString();
429 }
430
431// if (m_scene != null)
432// Console.WriteLine(
433// "[ARCHIVE WRITE REQUEST PREPARATION]: Control file for {0} is: {1}", m_scene.RegionInfo.RegionName, s);
434
435 return s;
436 }
437 }
438}
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
index bf3b124..2a87dc2 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs
@@ -146,6 +146,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
146 ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; }); 146 ops.Add("noassets", delegate(string v) { options["noassets"] = v != null; });
147 ops.Add("publish", v => options["wipe-owners"] = v != null); 147 ops.Add("publish", v => options["wipe-owners"] = v != null);
148 ops.Add("perm=", delegate(string v) { options["checkPermissions"] = v; }); 148 ops.Add("perm=", delegate(string v) { options["checkPermissions"] = v; });
149 ops.Add("all", delegate(string v) { options["all"] = v != null; });
149 150
150 List<string> mainParams = ops.Parse(cmdparams); 151 List<string> mainParams = ops.Parse(cmdparams);
151 152
@@ -169,7 +170,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
169 m_log.InfoFormat( 170 m_log.InfoFormat(
170 "[ARCHIVER]: Writing archive for region {0} to {1}", Scene.RegionInfo.RegionName, savePath); 171 "[ARCHIVER]: Writing archive for region {0} to {1}", Scene.RegionInfo.RegionName, savePath);
171 172
172 new ArchiveWriteRequestPreparation(this, savePath, requestId).ArchiveRegion(options); 173 new ArchiveWriteRequest(Scene, savePath, requestId).ArchiveRegion(options);
173 } 174 }
174 175
175 public void ArchiveRegion(Stream saveStream) 176 public void ArchiveRegion(Stream saveStream)
@@ -184,7 +185,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver
184 185
185 public void ArchiveRegion(Stream saveStream, Guid requestId, Dictionary<string, object> options) 186 public void ArchiveRegion(Stream saveStream, Guid requestId, Dictionary<string, object> options)
186 { 187 {
187 new ArchiveWriteRequestPreparation(this, saveStream, requestId).ArchiveRegion(options); 188 new ArchiveWriteRequest(Scene, saveStream, requestId).ArchiveRegion(options);
188 } 189 }
189 190
190 public void DearchiveRegion(string loadPath) 191 public void DearchiveRegion(string loadPath)
diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
index 89e9593..bf58591 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs
@@ -46,6 +46,12 @@ namespace OpenSim.Region.CoreModules.World.Archiver
46 { 46 {
47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48 48
49 /// <summary>
50 /// Method called when all the necessary assets for an archive request have been received.
51 /// </summary>
52 public delegate void AssetsRequestCallback(
53 ICollection<UUID> assetsFoundUuids, ICollection<UUID> assetsNotFoundUuids);
54
49 enum RequestState 55 enum RequestState
50 { 56 {
51 Initial, 57 Initial,
diff --git a/OpenSim/Region/CoreModules/World/Archiver/DearchiveScenesGroup.cs b/OpenSim/Region/CoreModules/World/Archiver/DearchiveScenesGroup.cs
new file mode 100644
index 0000000..3dcc020
--- /dev/null
+++ b/OpenSim/Region/CoreModules/World/Archiver/DearchiveScenesGroup.cs
@@ -0,0 +1,232 @@
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.Linq;
31using System.Text;
32using OpenSim.Region.Framework.Scenes;
33using OpenMetaverse;
34using System.Drawing;
35using log4net;
36using System.Reflection;
37using OpenSim.Framework.Serialization;
38
39namespace OpenSim.Region.CoreModules.World.Archiver
40{
41 /// <summary>
42 /// The regions included in an OAR file.
43 /// </summary>
44 public class DearchiveScenesInfo
45 {
46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47
48 /// <summary>
49 /// One region in the archive.
50 /// </summary>
51 public class RegionInfo
52 {
53 /// <summary>
54 /// The subdirectory in which the region is stored.
55 /// </summary>
56 public string Directory { get; set; }
57
58 /// <summary>
59 /// The region's coordinates (relative to the South-West corner of the block).
60 /// </summary>
61 public Point Location { get; set; }
62
63 /// <summary>
64 /// The UUID of the original scene from which this archived region was saved.
65 /// </summary>
66 public string OriginalID { get; set; }
67
68 /// <summary>
69 /// The scene in the current simulator into which this region is loaded.
70 /// If null then the region doesn't have a corresponding scene, and it won't be loaded.
71 /// </summary>
72 public Scene Scene { get; set; }
73 }
74
75 /// <summary>
76 /// Whether this archive uses the multi-region format.
77 /// </summary>
78 public Boolean MultiRegionFormat { get; set; }
79
80 /// <summary>
81 /// Maps (Region directory -> region)
82 /// </summary>
83 protected Dictionary<string, RegionInfo> m_directory2region = new Dictionary<string, RegionInfo>();
84
85 /// <summary>
86 /// Maps (UUID of the scene in the simulator where the region will be loaded -> region)
87 /// </summary>
88 protected Dictionary<UUID, RegionInfo> m_newId2region = new Dictionary<UUID, RegionInfo>();
89
90 public int LoadedCreationDateTime { get; set; }
91 public string DefaultOriginalID { get; set; }
92
93 // These variables are used while reading the archive control file
94 protected int? m_curY = null;
95 protected int? m_curX = null;
96 protected RegionInfo m_curRegion;
97
98
99 public DearchiveScenesInfo()
100 {
101 MultiRegionFormat = false;
102 }
103
104
105 // The following methods are used while reading the archive control file
106
107 public void StartRow()
108 {
109 m_curY = (m_curY == null) ? 0 : m_curY + 1;
110 m_curX = null;
111 }
112
113 public void StartRegion()
114 {
115 m_curX = (m_curX == null) ? 0 : m_curX + 1;
116 // Note: this doesn't mean we have a real region in this location; this could just be a "hole"
117 }
118
119 public void SetRegionOriginalID(string id)
120 {
121 m_curRegion = new RegionInfo();
122 m_curRegion.Location = new Point((int)m_curX, (int)m_curY);
123 m_curRegion.OriginalID = id;
124 // 'curRegion' will be saved in 'm_directory2region' when SetRegionDir() is called
125 }
126
127 public void SetRegionDirectory(string directory)
128 {
129 m_curRegion.Directory = directory;
130 m_directory2region[directory] = m_curRegion;
131 }
132
133
134 /// <summary>
135 /// Sets all the scenes present in the simulator.
136 /// </summary>
137 /// <remarks>
138 /// This method matches regions in the archive to scenes in the simulator according to
139 /// their relative position. We only load regions if there's an existing Scene in the
140 /// grid location where the region should be loaded.
141 /// </remarks>
142 /// <param name="rootScene">The scene where the Load OAR operation was run</param>
143 /// <param name="simulatorScenes">All the scenes in the simulator</param>
144 public void SetSimulatorScenes(Scene rootScene, ArchiveScenesGroup simulatorScenes)
145 {
146 foreach (RegionInfo archivedRegion in m_directory2region.Values)
147 {
148 Point location = new Point((int)rootScene.RegionInfo.RegionLocX, (int)rootScene.RegionInfo.RegionLocY);
149 location.Offset(archivedRegion.Location);
150
151 Scene scene;
152 if (simulatorScenes.TryGetScene(location, out scene))
153 {
154 archivedRegion.Scene = scene;
155 m_newId2region[scene.RegionInfo.RegionID] = archivedRegion;
156 }
157 else
158 {
159 m_log.WarnFormat("[ARCHIVER]: Not loading archived region {0} because there's no existing region at location {1},{2}",
160 archivedRegion.Directory, location.X, location.Y);
161 }
162 }
163 }
164
165 /// <summary>
166 /// Returns the archived region according to the path of a file in the archive.
167 /// Also, converts the full path into a path that is relative to the region's directory.
168 /// </summary>
169 /// <param name="fullPath">The path of a file in the archive</param>
170 /// <param name="scene">The corresponding Scene, or null if none</param>
171 /// <param name="relativePath">The path relative to the region's directory. (Or the original
172 /// path, if this file doesn't belong to a region.)</param>
173 /// <returns>True: use this file; False: skip it</returns>
174 public bool GetRegionFromPath(string fullPath, out Scene scene, out string relativePath)
175 {
176 scene = null;
177 relativePath = fullPath;
178
179 if (!MultiRegionFormat)
180 {
181 if (m_newId2region.Count > 0)
182 scene = m_newId2region.First().Value.Scene;
183 return true;
184 }
185
186 if (!fullPath.StartsWith(ArchiveConstants.REGIONS_PATH))
187 return true; // this file doesn't belong to a region
188
189 string[] parts = fullPath.Split(new Char[] { '/' }, 3);
190 if (parts.Length != 3)
191 return false;
192 string regionDirectory = parts[1];
193 relativePath = parts[2];
194
195 RegionInfo region;
196 if (m_directory2region.TryGetValue(regionDirectory, out region))
197 {
198 scene = region.Scene;
199 return (scene != null);
200 }
201 else
202 {
203 return false;
204 }
205 }
206
207 /// <summary>
208 /// Returns the original UUID of a region (from the simulator where the OAR was saved),
209 /// given the UUID of the scene it was loaded into in the current simulator.
210 /// </summary>
211 /// <param name="newID"></param>
212 /// <returns></returns>
213 public string GetOriginalRegionID(UUID newID)
214 {
215 RegionInfo region;
216 if (m_newId2region.TryGetValue(newID, out region))
217 return region.OriginalID;
218 else
219 return DefaultOriginalID;
220 }
221
222 /// <summary>
223 /// Returns the scenes that have been (or will be) loaded.
224 /// </summary>
225 /// <returns></returns>
226 public List<UUID> GetLoadedScenes()
227 {
228 return m_newId2region.Keys.ToList();
229 }
230
231 }
232}
diff --git a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
index 5deaf52..0a30905 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/Tests/ArchiverTests.cs
@@ -47,32 +47,38 @@ using ArchiveConstants = OpenSim.Framework.Serialization.ArchiveConstants;
47using TarArchiveReader = OpenSim.Framework.Serialization.TarArchiveReader; 47using TarArchiveReader = OpenSim.Framework.Serialization.TarArchiveReader;
48using TarArchiveWriter = OpenSim.Framework.Serialization.TarArchiveWriter; 48using TarArchiveWriter = OpenSim.Framework.Serialization.TarArchiveWriter;
49using RegionSettings = OpenSim.Framework.RegionSettings; 49using RegionSettings = OpenSim.Framework.RegionSettings;
50using OpenSim.Region.Framework.Interfaces;
50 51
51namespace OpenSim.Region.CoreModules.World.Archiver.Tests 52namespace OpenSim.Region.CoreModules.World.Archiver.Tests
52{ 53{
53 [TestFixture] 54 [TestFixture]
54 public class ArchiverTests 55 public class ArchiverTests : OpenSimTestCase
55 { 56 {
56 private Guid m_lastRequestId; 57 private Guid m_lastRequestId;
57 private string m_lastErrorMessage; 58 private string m_lastErrorMessage;
58 59
60 protected SceneHelpers m_sceneHelpers;
59 protected TestScene m_scene; 61 protected TestScene m_scene;
60 protected ArchiverModule m_archiverModule; 62 protected ArchiverModule m_archiverModule;
63 protected SerialiserModule m_serialiserModule;
61 64
62 protected TaskInventoryItem m_soundItem; 65 protected TaskInventoryItem m_soundItem;
63 66
64 [SetUp] 67 [SetUp]
65 public void SetUp() 68 public void SetUp()
66 { 69 {
70 new SceneManager();
71
67 m_archiverModule = new ArchiverModule(); 72 m_archiverModule = new ArchiverModule();
68 SerialiserModule serialiserModule = new SerialiserModule(); 73 m_serialiserModule = new SerialiserModule();
69 TerrainModule terrainModule = new TerrainModule(); 74 TerrainModule terrainModule = new TerrainModule();
70 75
71 m_scene = new SceneHelpers().SetupScene(); 76 m_sceneHelpers = new SceneHelpers();
72 SceneHelpers.SetupSceneModules(m_scene, m_archiverModule, serialiserModule, terrainModule); 77 m_scene = m_sceneHelpers.SetupScene();
78 SceneHelpers.SetupSceneModules(m_scene, m_archiverModule, m_serialiserModule, terrainModule);
73 } 79 }
74 80
75 private void LoadCompleted(Guid requestId, string errorMessage) 81 private void LoadCompleted(Guid requestId, List<UUID> loadedScenes, string errorMessage)
76 { 82 {
77 lock (this) 83 lock (this)
78 { 84 {
@@ -128,26 +134,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
128 TestHelpers.InMethod(); 134 TestHelpers.InMethod();
129// log4net.Config.XmlConfigurator.Configure(); 135// log4net.Config.XmlConfigurator.Configure();
130 136
131 SceneObjectPart part1 = CreateSceneObjectPart1(); 137 SceneObjectGroup sog1;
132 SceneObjectGroup sog1 = new SceneObjectGroup(part1); 138 SceneObjectGroup sog2;
133 m_scene.AddNewSceneObject(sog1, false); 139 UUID ncAssetUuid;
134 140 CreateTestObjects(m_scene, out sog1, out sog2, out ncAssetUuid);
135 SceneObjectPart part2 = CreateSceneObjectPart2();
136
137 AssetNotecard nc = new AssetNotecard();
138 nc.BodyText = "Hello World!";
139 nc.Encode();
140 UUID ncAssetUuid = new UUID("00000000-0000-0000-1000-000000000000");
141 UUID ncItemUuid = new UUID("00000000-0000-0000-1100-000000000000");
142 AssetBase ncAsset
143 = AssetHelpers.CreateAsset(ncAssetUuid, AssetType.Notecard, nc.AssetData, UUID.Zero);
144 m_scene.AssetService.Store(ncAsset);
145 SceneObjectGroup sog2 = new SceneObjectGroup(part2);
146 TaskInventoryItem ncItem
147 = new TaskInventoryItem { Name = "ncItem", AssetID = ncAssetUuid, ItemID = ncItemUuid };
148 part2.Inventory.AddInventoryItem(ncItem, true);
149
150 m_scene.AddNewSceneObject(sog2, false);
151 141
152 MemoryStream archiveWriteStream = new MemoryStream(); 142 MemoryStream archiveWriteStream = new MemoryStream();
153 m_scene.EventManager.OnOarFileSaved += SaveCompleted; 143 m_scene.EventManager.OnOarFileSaved += SaveCompleted;
@@ -186,7 +176,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
186 Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH)); 176 Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH));
187 177
188 ArchiveReadRequest arr = new ArchiveReadRequest(m_scene, (Stream)null, false, false, Guid.Empty); 178 ArchiveReadRequest arr = new ArchiveReadRequest(m_scene, (Stream)null, false, false, Guid.Empty);
189 arr.LoadControlFile(filePath, data); 179 arr.LoadControlFile(filePath, data, new DearchiveScenesInfo());
190 180
191 Assert.That(arr.ControlFileLoaded, Is.True); 181 Assert.That(arr.ControlFileLoaded, Is.True);
192 182
@@ -211,6 +201,30 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
211 // TODO: Test presence of more files and contents of files. 201 // TODO: Test presence of more files and contents of files.
212 } 202 }
213 203
204 private void CreateTestObjects(Scene scene, out SceneObjectGroup sog1, out SceneObjectGroup sog2, out UUID ncAssetUuid)
205 {
206 SceneObjectPart part1 = CreateSceneObjectPart1();
207 sog1 = new SceneObjectGroup(part1);
208 scene.AddNewSceneObject(sog1, false);
209
210 AssetNotecard nc = new AssetNotecard();
211 nc.BodyText = "Hello World!";
212 nc.Encode();
213 ncAssetUuid = UUID.Random();
214 UUID ncItemUuid = UUID.Random();
215 AssetBase ncAsset
216 = AssetHelpers.CreateAsset(ncAssetUuid, AssetType.Notecard, nc.AssetData, UUID.Zero);
217 m_scene.AssetService.Store(ncAsset);
218
219 TaskInventoryItem ncItem
220 = new TaskInventoryItem { Name = "ncItem", AssetID = ncAssetUuid, ItemID = ncItemUuid };
221 SceneObjectPart part2 = CreateSceneObjectPart2();
222 sog2 = new SceneObjectGroup(part2);
223 part2.Inventory.AddInventoryItem(ncItem, true);
224
225 scene.AddNewSceneObject(sog2, false);
226 }
227
214 /// <summary> 228 /// <summary>
215 /// Test saving an OpenSim Region Archive with the no assets option 229 /// Test saving an OpenSim Region Archive with the no assets option
216 /// </summary> 230 /// </summary>
@@ -270,7 +284,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
270 Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH)); 284 Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH));
271 285
272 ArchiveReadRequest arr = new ArchiveReadRequest(m_scene, (Stream)null, false, false, Guid.Empty); 286 ArchiveReadRequest arr = new ArchiveReadRequest(m_scene, (Stream)null, false, false, Guid.Empty);
273 arr.LoadControlFile(filePath, data); 287 arr.LoadControlFile(filePath, data, new DearchiveScenesInfo());
274 288
275 Assert.That(arr.ControlFileLoaded, Is.True); 289 Assert.That(arr.ControlFileLoaded, Is.True);
276 290
@@ -307,7 +321,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
307 321
308 tar.WriteFile( 322 tar.WriteFile(
309 ArchiveConstants.CONTROL_FILE_PATH, 323 ArchiveConstants.CONTROL_FILE_PATH,
310 new ArchiveWriteRequestPreparation(null, (Stream)null, Guid.Empty).CreateControlFile(new Dictionary<string, Object>())); 324 new ArchiveWriteRequest(m_scene, (Stream)null, Guid.Empty).CreateControlFile(new ArchiveScenesGroup()));
311 325
312 SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, ownerId, "obj1-", 0x11); 326 SceneObjectGroup sog1 = SceneHelpers.CreateSceneObject(1, ownerId, "obj1-", 0x11);
313 SceneObjectPart sop2 327 SceneObjectPart sop2
@@ -362,11 +376,10 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
362 // Also check that direct entries which will also have a file entry containing that directory doesn't 376 // Also check that direct entries which will also have a file entry containing that directory doesn't
363 // upset load 377 // upset load
364 tar.WriteDir(ArchiveConstants.TERRAINS_PATH); 378 tar.WriteDir(ArchiveConstants.TERRAINS_PATH);
365 379
366 tar.WriteFile( 380 tar.WriteFile(
367 ArchiveConstants.CONTROL_FILE_PATH, 381 ArchiveConstants.CONTROL_FILE_PATH,
368 new ArchiveWriteRequestPreparation(null, (Stream)null, Guid.Empty).CreateControlFile(new Dictionary<string, Object>())); 382 new ArchiveWriteRequest(m_scene, (Stream)null, Guid.Empty).CreateControlFile(new ArchiveScenesGroup()));
369
370 SceneObjectPart part1 = CreateSceneObjectPart1(); 383 SceneObjectPart part1 = CreateSceneObjectPart1();
371 384
372 part1.SitTargetOrientation = new Quaternion(0.2f, 0.3f, 0.4f, 0.5f); 385 part1.SitTargetOrientation = new Quaternion(0.2f, 0.3f, 0.4f, 0.5f);
@@ -389,31 +402,12 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
389 Assert.That(soundDataResourceName, Is.Not.Null); 402 Assert.That(soundDataResourceName, Is.Not.Null);
390 403
391 byte[] soundData; 404 byte[] soundData;
392 Console.WriteLine("Loading " + soundDataResourceName); 405 UUID soundUuid;
393 using (Stream resource = assembly.GetManifestResourceStream(soundDataResourceName)) 406 CreateSoundAsset(tar, assembly, soundDataResourceName, out soundData, out soundUuid);
394 { 407
395 using (BinaryReader br = new BinaryReader(resource)) 408 TaskInventoryItem item1
396 { 409 = new TaskInventoryItem { AssetID = soundUuid, ItemID = soundItemUuid, Name = soundItemName };
397 // FIXME: Use the inspector instead 410 part1.Inventory.AddInventoryItem(item1, true);
398 soundData = br.ReadBytes(99999999);
399 UUID soundUuid = UUID.Parse("00000000-0000-0000-0000-000000000001");
400 string soundAssetFileName
401 = ArchiveConstants.ASSETS_PATH + soundUuid
402 + ArchiveConstants.ASSET_TYPE_TO_EXTENSION[(sbyte)AssetType.SoundWAV];
403 tar.WriteFile(soundAssetFileName, soundData);
404
405 /*
406 AssetBase soundAsset = AssetHelpers.CreateAsset(soundUuid, soundData);
407 scene.AssetService.Store(soundAsset);
408 asset1FileName = ArchiveConstants.ASSETS_PATH + soundUuid + ".wav";
409 */
410
411 TaskInventoryItem item1
412 = new TaskInventoryItem { AssetID = soundUuid, ItemID = soundItemUuid, Name = soundItemName };
413 part1.Inventory.AddInventoryItem(item1, true);
414 }
415 }
416
417 m_scene.AddNewSceneObject(object1, false); 411 m_scene.AddNewSceneObject(object1, false);
418 412
419 string object1FileName = string.Format( 413 string object1FileName = string.Format(
@@ -435,6 +429,34 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
435 429
436 Assert.That(m_lastErrorMessage, Is.Null); 430 Assert.That(m_lastErrorMessage, Is.Null);
437 431
432 TestLoadedRegion(part1, soundItemName, soundData);
433 }
434
435 private static void CreateSoundAsset(TarArchiveWriter tar, Assembly assembly, string soundDataResourceName, out byte[] soundData, out UUID soundUuid)
436 {
437 using (Stream resource = assembly.GetManifestResourceStream(soundDataResourceName))
438 {
439 using (BinaryReader br = new BinaryReader(resource))
440 {
441 // FIXME: Use the inspector instead
442 soundData = br.ReadBytes(99999999);
443 soundUuid = UUID.Parse("00000000-0000-0000-0000-000000000001");
444 string soundAssetFileName
445 = ArchiveConstants.ASSETS_PATH + soundUuid
446 + ArchiveConstants.ASSET_TYPE_TO_EXTENSION[(sbyte)AssetType.SoundWAV];
447 tar.WriteFile(soundAssetFileName, soundData);
448
449 /*
450 AssetBase soundAsset = AssetHelpers.CreateAsset(soundUuid, soundData);
451 scene.AssetService.Store(soundAsset);
452 asset1FileName = ArchiveConstants.ASSETS_PATH + soundUuid + ".wav";
453 */
454 }
455 }
456 }
457
458 private void TestLoadedRegion(SceneObjectPart part1, string soundItemName, byte[] soundData)
459 {
438 SceneObjectPart object1PartLoaded = m_scene.GetSceneObjectPart(part1.Name); 460 SceneObjectPart object1PartLoaded = m_scene.GetSceneObjectPart(part1.Name);
439 461
440 Assert.That(object1PartLoaded, Is.Not.Null, "object1 was not loaded"); 462 Assert.That(object1PartLoaded, Is.Not.Null, "object1 was not loaded");
@@ -454,9 +476,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
454 Assert.That(loadedSoundAsset.Data, Is.EqualTo(soundData), "saved and loaded sound data do not match"); 476 Assert.That(loadedSoundAsset.Data, Is.EqualTo(soundData), "saved and loaded sound data do not match");
455 477
456 Assert.Greater(m_scene.LandChannel.AllParcels().Count, 0, "incorrect number of parcels"); 478 Assert.Greater(m_scene.LandChannel.AllParcels().Count, 0, "incorrect number of parcels");
457
458 // Temporary
459 Console.WriteLine("Successfully completed {0}", MethodBase.GetCurrentMethod());
460 } 479 }
461 480
462 /// <summary> 481 /// <summary>
@@ -516,7 +535,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
516 SerialiserModule serialiserModule = new SerialiserModule(); 535 SerialiserModule serialiserModule = new SerialiserModule();
517 TerrainModule terrainModule = new TerrainModule(); 536 TerrainModule terrainModule = new TerrainModule();
518 537
519 TestScene scene2 = new SceneHelpers().SetupScene(); 538 m_sceneHelpers = new SceneHelpers();
539 TestScene scene2 = m_sceneHelpers.SetupScene();
520 SceneHelpers.SetupSceneModules(scene2, archiverModule, serialiserModule, terrainModule); 540 SceneHelpers.SetupSceneModules(scene2, archiverModule, serialiserModule, terrainModule);
521 541
522 // Make sure there's a valid owner for the owner we saved (this should have been wiped if the code is 542 // Make sure there's a valid owner for the owner we saved (this should have been wiped if the code is
@@ -554,7 +574,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
554 tar.WriteDir(ArchiveConstants.TERRAINS_PATH); 574 tar.WriteDir(ArchiveConstants.TERRAINS_PATH);
555 tar.WriteFile( 575 tar.WriteFile(
556 ArchiveConstants.CONTROL_FILE_PATH, 576 ArchiveConstants.CONTROL_FILE_PATH,
557 new ArchiveWriteRequestPreparation(null, (Stream)null, Guid.Empty).CreateControlFile(new Dictionary<string, Object>())); 577 new ArchiveWriteRequest(m_scene, (Stream)null, Guid.Empty).CreateControlFile(new ArchiveScenesGroup()));
558 578
559 RegionSettings rs = new RegionSettings(); 579 RegionSettings rs = new RegionSettings();
560 rs.AgentLimit = 17; 580 rs.AgentLimit = 17;
@@ -664,7 +684,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
664 SerialiserModule serialiserModule = new SerialiserModule(); 684 SerialiserModule serialiserModule = new SerialiserModule();
665 TerrainModule terrainModule = new TerrainModule(); 685 TerrainModule terrainModule = new TerrainModule();
666 686
667 Scene scene = new SceneHelpers().SetupScene(); 687 Scene scene = m_sceneHelpers.SetupScene();
668 SceneHelpers.SetupSceneModules(scene, archiverModule, serialiserModule, terrainModule); 688 SceneHelpers.SetupSceneModules(scene, archiverModule, serialiserModule, terrainModule);
669 689
670 m_scene.AddNewSceneObject(new SceneObjectGroup(part2), false); 690 m_scene.AddNewSceneObject(new SceneObjectGroup(part2), false);
@@ -700,5 +720,258 @@ namespace OpenSim.Region.CoreModules.World.Archiver.Tests
700 Assert.That(object2PartMerged.GroupPosition, Is.EqualTo(part2.GroupPosition), "object2 group position not equal after merge"); 720 Assert.That(object2PartMerged.GroupPosition, Is.EqualTo(part2.GroupPosition), "object2 group position not equal after merge");
701 } 721 }
702 } 722 }
723
724 /// <summary>
725 /// Test saving a multi-region OAR.
726 /// </summary>
727 [Test]
728 public void TestSaveMultiRegionOar()
729 {
730 TestHelpers.InMethod();
731
732 // Create test regions
733
734 int WIDTH = 2;
735 int HEIGHT = 2;
736
737 List<Scene> scenes = new List<Scene>();
738
739 // Maps (Directory in OAR file -> scene)
740 Dictionary<string, Scene> regionPaths = new Dictionary<string, Scene>();
741
742 // Maps (Scene -> expected object paths)
743 Dictionary<UUID, List<string>> expectedPaths = new Dictionary<UUID, List<string>>();
744
745 // List of expected assets
746 List<UUID> expectedAssets = new List<UUID>();
747
748 for (uint y = 0; y < HEIGHT; y++)
749 {
750 for (uint x = 0; x < WIDTH; x++)
751 {
752 Scene scene;
753 if (x == 0 && y == 0)
754 {
755 scene = m_scene; // this scene was already created in SetUp()
756 }
757 else
758 {
759 scene = m_sceneHelpers.SetupScene(string.Format("Unit test region {0}", (y * WIDTH) + x + 1), UUID.Random(), 1000 + x, 1000 + y);
760 SceneHelpers.SetupSceneModules(scene, new ArchiverModule(), m_serialiserModule, new TerrainModule());
761 }
762 scenes.Add(scene);
763
764 string dir = String.Format("{0}_{1}_{2}", x + 1, y + 1, scene.RegionInfo.RegionName.Replace(" ", "_"));
765 regionPaths[dir] = scene;
766
767 SceneObjectGroup sog1;
768 SceneObjectGroup sog2;
769 UUID ncAssetUuid;
770
771 CreateTestObjects(scene, out sog1, out sog2, out ncAssetUuid);
772
773 expectedPaths[scene.RegionInfo.RegionID] = new List<string>();
774 expectedPaths[scene.RegionInfo.RegionID].Add(ArchiveHelpers.CreateObjectPath(sog1));
775 expectedPaths[scene.RegionInfo.RegionID].Add(ArchiveHelpers.CreateObjectPath(sog2));
776
777 expectedAssets.Add(ncAssetUuid);
778 }
779 }
780
781
782 // Save OAR
783
784 MemoryStream archiveWriteStream = new MemoryStream();
785 m_scene.EventManager.OnOarFileSaved += SaveCompleted;
786
787 Guid requestId = new Guid("00000000-0000-0000-0000-808080808080");
788
789 Dictionary<string, Object> options = new Dictionary<string, Object>();
790 options.Add("all", true);
791
792 lock (this)
793 {
794 m_archiverModule.ArchiveRegion(archiveWriteStream, requestId, options);
795 Monitor.Wait(this, 60000);
796 }
797
798
799 // Check that the OAR contains the expected data
800
801 Assert.That(m_lastRequestId, Is.EqualTo(requestId));
802
803 byte[] archive = archiveWriteStream.ToArray();
804 MemoryStream archiveReadStream = new MemoryStream(archive);
805 TarArchiveReader tar = new TarArchiveReader(archiveReadStream);
806
807 Dictionary<UUID, List<string>> foundPaths = new Dictionary<UUID, List<string>>();
808 List<UUID> foundAssets = new List<UUID>();
809
810 foreach (Scene scene in scenes)
811 {
812 foundPaths[scene.RegionInfo.RegionID] = new List<string>();
813 }
814
815 string filePath;
816 TarArchiveReader.TarEntryType tarEntryType;
817
818 byte[] data = tar.ReadEntry(out filePath, out tarEntryType);
819 Assert.That(filePath, Is.EqualTo(ArchiveConstants.CONTROL_FILE_PATH));
820
821 ArchiveReadRequest arr = new ArchiveReadRequest(m_scene, (Stream)null, false, false, Guid.Empty);
822 arr.LoadControlFile(filePath, data, new DearchiveScenesInfo());
823
824 Assert.That(arr.ControlFileLoaded, Is.True);
825
826 while (tar.ReadEntry(out filePath, out tarEntryType) != null)
827 {
828 if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH))
829 {
830 // Assets are shared, so this file doesn't belong to any specific region.
831 string fileName = filePath.Remove(0, ArchiveConstants.ASSETS_PATH.Length);
832 if (fileName.EndsWith("_notecard.txt"))
833 foundAssets.Add(UUID.Parse(fileName.Substring(0, fileName.Length - "_notecard.txt".Length)));
834 }
835 else
836 {
837 // This file belongs to one of the regions. Find out which one.
838 Assert.IsTrue(filePath.StartsWith(ArchiveConstants.REGIONS_PATH));
839 string[] parts = filePath.Split(new Char[] { '/' }, 3);
840 Assert.AreEqual(3, parts.Length);
841 string regionDirectory = parts[1];
842 string relativePath = parts[2];
843 Scene scene = regionPaths[regionDirectory];
844
845 if (relativePath.StartsWith(ArchiveConstants.OBJECTS_PATH))
846 {
847 foundPaths[scene.RegionInfo.RegionID].Add(relativePath);
848 }
849 }
850 }
851
852 Assert.AreEqual(scenes.Count, foundPaths.Count);
853 foreach (Scene scene in scenes)
854 {
855 Assert.That(foundPaths[scene.RegionInfo.RegionID], Is.EquivalentTo(expectedPaths[scene.RegionInfo.RegionID]));
856 }
857
858 Assert.That(foundAssets, Is.EquivalentTo(expectedAssets));
859 }
860
861 /// <summary>
862 /// Test loading a multi-region OAR.
863 /// </summary>
864 [Test]
865 public void TestLoadMultiRegionOar()
866 {
867 TestHelpers.InMethod();
868
869 // Create an ArchiveScenesGroup with the regions in the OAR. This is needed to generate the control file.
870
871 int WIDTH = 2;
872 int HEIGHT = 2;
873
874 for (uint y = 0; y < HEIGHT; y++)
875 {
876 for (uint x = 0; x < WIDTH; x++)
877 {
878 Scene scene;
879 if (x == 0 && y == 0)
880 {
881 scene = m_scene; // this scene was already created in SetUp()
882 }
883 else
884 {
885 scene = m_sceneHelpers.SetupScene(string.Format("Unit test region {0}", (y * WIDTH) + x + 1), UUID.Random(), 1000 + x, 1000 + y);
886 SceneHelpers.SetupSceneModules(scene, new ArchiverModule(), m_serialiserModule, new TerrainModule());
887 }
888 }
889 }
890
891 ArchiveScenesGroup scenesGroup = new ArchiveScenesGroup();
892 SceneManager.Instance.ForEachScene(delegate(Scene scene)
893 {
894 scenesGroup.AddScene(scene);
895 });
896 scenesGroup.CalcSceneLocations();
897
898 // Generate the OAR file
899
900 MemoryStream archiveWriteStream = new MemoryStream();
901 TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream);
902
903 ArchiveWriteRequest writeRequest = new ArchiveWriteRequest(m_scene, (Stream)null, Guid.Empty);
904 writeRequest.MultiRegionFormat = true;
905 tar.WriteFile(
906 ArchiveConstants.CONTROL_FILE_PATH, writeRequest.CreateControlFile(scenesGroup));
907
908 SceneObjectPart part1 = CreateSceneObjectPart1();
909 part1.SitTargetOrientation = new Quaternion(0.2f, 0.3f, 0.4f, 0.5f);
910 part1.SitTargetPosition = new Vector3(1, 2, 3);
911
912 SceneObjectGroup object1 = new SceneObjectGroup(part1);
913
914 // Let's put some inventory items into our object
915 string soundItemName = "sound-item1";
916 UUID soundItemUuid = UUID.Parse("00000000-0000-0000-0000-000000000002");
917 Type type = GetType();
918 Assembly assembly = type.Assembly;
919 string soundDataResourceName = null;
920 string[] names = assembly.GetManifestResourceNames();
921 foreach (string name in names)
922 {
923 if (name.EndsWith(".Resources.test-sound.wav"))
924 soundDataResourceName = name;
925 }
926 Assert.That(soundDataResourceName, Is.Not.Null);
927
928 byte[] soundData;
929 UUID soundUuid;
930 CreateSoundAsset(tar, assembly, soundDataResourceName, out soundData, out soundUuid);
931
932 TaskInventoryItem item1
933 = new TaskInventoryItem { AssetID = soundUuid, ItemID = soundItemUuid, Name = soundItemName };
934 part1.Inventory.AddInventoryItem(item1, true);
935 m_scene.AddNewSceneObject(object1, false);
936
937 string object1FileName = string.Format(
938 "{0}_{1:000}-{2:000}-{3:000}__{4}.xml",
939 part1.Name,
940 Math.Round(part1.GroupPosition.X), Math.Round(part1.GroupPosition.Y), Math.Round(part1.GroupPosition.Z),
941 part1.UUID);
942 string path = "regions/1_1_Unit_test_region/" + ArchiveConstants.OBJECTS_PATH + object1FileName;
943 tar.WriteFile(path, SceneObjectSerializer.ToXml2Format(object1));
944
945 tar.Close();
946
947
948 // Delete the current objects, to test that they're loaded from the OAR and didn't
949 // just remain in the scene.
950 SceneManager.Instance.ForEachScene(delegate(Scene scene)
951 {
952 scene.DeleteAllSceneObjects();
953 });
954
955 // Create a "hole", to test that that the corresponding region isn't loaded from the OAR
956 SceneManager.Instance.CloseScene(SceneManager.Instance.Scenes[1]);
957
958
959 // Check thay the OAR file contains the expected data
960
961 MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
962
963 lock (this)
964 {
965 m_scene.EventManager.OnOarFileLoaded += LoadCompleted;
966 m_archiverModule.DearchiveRegion(archiveReadStream);
967 }
968
969 Assert.That(m_lastErrorMessage, Is.Null);
970
971 Assert.AreEqual(3, SceneManager.Instance.Scenes.Count);
972
973 TestLoadedRegion(part1, soundItemName, soundData);
974 }
975
703 } 976 }
704} 977}
diff --git a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
index 102b4d7..cbb3abe 100644
--- a/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/PrimCountModule.cs
@@ -69,7 +69,7 @@ namespace OpenSim.Region.CoreModules.World.Land
69 /// without recounting the whole sim. 69 /// without recounting the whole sim.
70 /// 70 ///
71 /// We start out tainted so that the first get call resets the various prim counts. 71 /// We start out tainted so that the first get call resets the various prim counts.
72 /// <value> 72 /// </value>
73 private bool m_Tainted = true; 73 private bool m_Tainted = true;
74 74
75 private Object m_TaintLock = new Object(); 75 private Object m_TaintLock = new Object();
diff --git a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs
index 14c1a39..a2f0950 100644
--- a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs
+++ b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs
@@ -85,13 +85,15 @@ namespace OpenSim.Region.CoreModules.World.Sound
85 dis = 0; 85 dis = 0;
86 } 86 }
87 87
88 float thisSpGain;
89
88 // Scale by distance 90 // Scale by distance
89 if (radius == 0) 91 if (radius == 0)
90 gain = (float)((double)gain * ((100.0 - dis) / 100.0)); 92 thisSpGain = (float)((double)gain * ((100.0 - dis) / 100.0));
91 else 93 else
92 gain = (float)((double)gain * ((radius - dis) / radius)); 94 thisSpGain = (float)((double)gain * ((radius - dis) / radius));
93 95
94 sp.ControllingClient.SendPlayAttachedSound(soundID, objectID, ownerID, (float)gain, flags); 96 sp.ControllingClient.SendPlayAttachedSound(soundID, objectID, ownerID, thisSpGain, flags);
95 }); 97 });
96 } 98 }
97 99
diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
index 402b9fb..d99567c 100644
--- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
+++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs
@@ -414,6 +414,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain
414 private void LoadPlugins() 414 private void LoadPlugins()
415 { 415 {
416 m_plugineffects = new Dictionary<string, ITerrainEffect>(); 416 m_plugineffects = new Dictionary<string, ITerrainEffect>();
417 LoadPlugins(Assembly.GetCallingAssembly());
417 string plugineffectsPath = "Terrain"; 418 string plugineffectsPath = "Terrain";
418 419
419 // Load the files in the Terrain/ dir 420 // Load the files in the Terrain/ dir
@@ -427,34 +428,39 @@ namespace OpenSim.Region.CoreModules.World.Terrain
427 try 428 try
428 { 429 {
429 Assembly library = Assembly.LoadFrom(file); 430 Assembly library = Assembly.LoadFrom(file);
430 foreach (Type pluginType in library.GetTypes()) 431 LoadPlugins(library);
431 { 432 }
432 try 433 catch (BadImageFormatException)
433 { 434 {
434 if (pluginType.IsAbstract || pluginType.IsNotPublic) 435 }
435 continue; 436 }
437 }
436 438
437 string typeName = pluginType.Name; 439 private void LoadPlugins(Assembly library)
440 {
441 foreach (Type pluginType in library.GetTypes())
442 {
443 try
444 {
445 if (pluginType.IsAbstract || pluginType.IsNotPublic)
446 continue;
438 447
439 if (pluginType.GetInterface("ITerrainEffect", false) != null) 448 string typeName = pluginType.Name;
440 {
441 ITerrainEffect terEffect = (ITerrainEffect) Activator.CreateInstance(library.GetType(pluginType.ToString()));
442 449
443 InstallPlugin(typeName, terEffect); 450 if (pluginType.GetInterface("ITerrainEffect", false) != null)
444 } 451 {
445 else if (pluginType.GetInterface("ITerrainLoader", false) != null) 452 ITerrainEffect terEffect = (ITerrainEffect)Activator.CreateInstance(library.GetType(pluginType.ToString()));
446 { 453
447 ITerrainLoader terLoader = (ITerrainLoader) Activator.CreateInstance(library.GetType(pluginType.ToString())); 454 InstallPlugin(typeName, terEffect);
448 m_loaders[terLoader.FileExtension] = terLoader; 455 }
449 m_log.Info("L ... " + typeName); 456 else if (pluginType.GetInterface("ITerrainLoader", false) != null)
450 } 457 {
451 } 458 ITerrainLoader terLoader = (ITerrainLoader)Activator.CreateInstance(library.GetType(pluginType.ToString()));
452 catch (AmbiguousMatchException) 459 m_loaders[terLoader.FileExtension] = terLoader;
453 { 460 m_log.Info("L ... " + typeName);
454 }
455 } 461 }
456 } 462 }
457 catch (BadImageFormatException) 463 catch (AmbiguousMatchException)
458 { 464 {
459 } 465 }
460 } 466 }
@@ -1178,7 +1184,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1178 1184
1179 private void InterfaceRunPluginEffect(Object[] args) 1185 private void InterfaceRunPluginEffect(Object[] args)
1180 { 1186 {
1181 if ((string) args[0] == "list") 1187 string firstArg = (string)args[0];
1188 if (firstArg == "list")
1182 { 1189 {
1183 m_log.Info("List of loaded plugins"); 1190 m_log.Info("List of loaded plugins");
1184 foreach (KeyValuePair<string, ITerrainEffect> kvp in m_plugineffects) 1191 foreach (KeyValuePair<string, ITerrainEffect> kvp in m_plugineffects)
@@ -1187,14 +1194,14 @@ namespace OpenSim.Region.CoreModules.World.Terrain
1187 } 1194 }
1188 return; 1195 return;
1189 } 1196 }
1190 if ((string) args[0] == "reload") 1197 if (firstArg == "reload")
1191 { 1198 {
1192 LoadPlugins(); 1199 LoadPlugins();
1193 return; 1200 return;
1194 } 1201 }
1195 if (m_plugineffects.ContainsKey((string) args[0])) 1202 if (m_plugineffects.ContainsKey(firstArg))
1196 { 1203 {
1197 m_plugineffects[(string) args[0]].RunEffect(m_channel); 1204 m_plugineffects[firstArg].RunEffect(m_channel);
1198 CheckForTerrainUpdates(); 1205 CheckForTerrainUpdates();
1199 } 1206 }
1200 else 1207 else
diff --git a/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs b/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs
index 3c48d07..33f6c3f 100644
--- a/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs
+++ b/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs
@@ -222,6 +222,13 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
222 bitmap = ImageUtils.ResizeImage(origBitmap, viewport.Width, viewport.Height); 222 bitmap = ImageUtils.ResizeImage(origBitmap, viewport.Width, viewport.Height);
223 } 223 }
224 224
225 // XXX: It shouldn't really be necesary to force a GC here as one should occur anyway pretty shortly
226 // afterwards. It's generally regarded as a bad idea to manually GC. If Warp3D is using lots of memory
227 // then this may be some issue with the Warp3D code itself, though it's also quite possible that generating
228 // this map tile simply takes a lot of memory.
229 GC.Collect();
230 m_log.Debug("[WARP 3D IMAGE MODULE]: GC.Collect()");
231
225 return bitmap; 232 return bitmap;
226 } 233 }
227 234
diff --git a/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs b/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs
index 8954513..6df5cc2 100644
--- a/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs
+++ b/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs
@@ -25,6 +25,8 @@
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System;
29using System.Drawing;
28using System.IO; 30using System.IO;
29using OpenMetaverse; 31using OpenMetaverse;
30 32
@@ -33,7 +35,14 @@ namespace OpenSim.Region.Framework.Interfaces
33 public interface IDynamicTextureManager 35 public interface IDynamicTextureManager
34 { 36 {
35 void RegisterRender(string handleType, IDynamicTextureRender render); 37 void RegisterRender(string handleType, IDynamicTextureRender render);
36 void ReturnData(UUID id, byte[] data); 38
39 /// <summary>
40 /// Used by IDynamicTextureRender implementations to return renders
41 /// </summary>
42 /// <param name='id'></param>
43 /// <param name='data'></param>
44 /// <param name='isReuseable'></param>
45 void ReturnData(UUID id, IDynamicTexture texture);
37 46
38 UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, string extraParams, 47 UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, string extraParams,
39 int updateTimer); 48 int updateTimer);
@@ -113,11 +122,65 @@ namespace OpenSim.Region.Framework.Interfaces
113 string GetName(); 122 string GetName();
114 string GetContentType(); 123 string GetContentType();
115 bool SupportsAsynchronous(); 124 bool SupportsAsynchronous();
116 byte[] ConvertUrl(string url, string extraParams); 125
117 byte[] ConvertStream(Stream data, string extraParams); 126// /// <summary>
127// /// Return true if converting the input body and extra params data will always result in the same byte[] array
128// /// </summary>
129// /// <remarks>
130// /// This method allows the caller to use a previously generated asset if it has one.
131// /// </remarks>
132// /// <returns></returns>
133// /// <param name='bodyData'></param>
134// /// <param name='extraParams'></param>
135// bool AlwaysIdenticalConversion(string bodyData, string extraParams);
136
137 IDynamicTexture ConvertUrl(string url, string extraParams);
138 IDynamicTexture ConvertData(string bodyData, string extraParams);
139
118 bool AsyncConvertUrl(UUID id, string url, string extraParams); 140 bool AsyncConvertUrl(UUID id, string url, string extraParams);
119 bool AsyncConvertData(UUID id, string bodyData, string extraParams); 141 bool AsyncConvertData(UUID id, string bodyData, string extraParams);
142
120 void GetDrawStringSize(string text, string fontName, int fontSize, 143 void GetDrawStringSize(string text, string fontName, int fontSize,
121 out double xSize, out double ySize); 144 out double xSize, out double ySize);
122 } 145 }
146
147 public interface IDynamicTexture
148 {
149 /// <summary>
150 /// Input commands used to generate this data.
151 /// </summary>
152 /// <remarks>
153 /// Null if input commands were not used.
154 /// </remarks>
155 string InputCommands { get; }
156
157 /// <summary>
158 /// Uri used to generate this data.
159 /// </summary>
160 /// <remarks>
161 /// Null if a uri was not used.
162 /// </remarks>
163 Uri InputUri { get; }
164
165 /// <summary>
166 /// Extra input params used to generate this data.
167 /// </summary>
168 string InputParams { get; }
169
170 /// <summary>
171 /// Texture data.
172 /// </summary>
173 byte[] Data { get; }
174
175 /// <summary>
176 /// Size of texture.
177 /// </summary>
178 Size Size { get; }
179
180 /// <summary>
181 /// Signal whether the texture is reuseable (i.e. whether the same input data will always generate the same
182 /// texture).
183 /// </summary>
184 bool IsReuseable { get; }
185 }
123} 186}
diff --git a/OpenSim/Region/Framework/Interfaces/IEstateModule.cs b/OpenSim/Region/Framework/Interfaces/IEstateModule.cs
index ca2ad94..292efa4 100644
--- a/OpenSim/Region/Framework/Interfaces/IEstateModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEstateModule.cs
@@ -46,6 +46,10 @@ namespace OpenSim.Region.Framework.Interfaces
46 /// </summary> 46 /// </summary>
47 void sendRegionHandshakeToAll(); 47 void sendRegionHandshakeToAll();
48 void TriggerEstateInfoChange(); 48 void TriggerEstateInfoChange();
49
50 /// <summary>
51 /// Fires the OnRegionInfoChange event.
52 /// </summary>
49 void TriggerRegionInfoChange(); 53 void TriggerRegionInfoChange();
50 54
51 void setEstateTerrainBaseTexture(int level, UUID texture); 55 void setEstateTerrainBaseTexture(int level, UUID texture);
diff --git a/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs b/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs
index baac6e8..da39e95 100644
--- a/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IJsonStoreModule.cs
@@ -35,7 +35,7 @@ namespace OpenSim.Region.Framework.Interfaces
35 35
36 public interface IJsonStoreModule 36 public interface IJsonStoreModule
37 { 37 {
38 bool CreateStore(string value, out UUID result); 38 bool CreateStore(string value, ref UUID result);
39 bool DestroyStore(UUID storeID); 39 bool DestroyStore(UUID storeID);
40 bool TestPath(UUID storeID, string path, bool useJson); 40 bool TestPath(UUID storeID, string path, bool useJson);
41 bool SetValue(UUID storeID, string path, string value, bool useJson); 41 bool SetValue(UUID storeID, string path, string value, bool useJson);
diff --git a/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs b/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs
index ed71a95..dae7c00 100644
--- a/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs
+++ b/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs
@@ -46,9 +46,38 @@ namespace OpenSim.Region.Framework.Interfaces
46 /// </summary> 46 /// </summary>
47 event ScriptCommand OnScriptCommand; 47 event ScriptCommand OnScriptCommand;
48 48
49 /// <summary>
50 /// Register an instance method as a script call by method name
51 /// </summary>
52 /// <param name="target"></param>
53 /// <param name="method"></param>
49 void RegisterScriptInvocation(object target, string method); 54 void RegisterScriptInvocation(object target, string method);
55
56 /// <summary>
57 /// Register a static or instance method as a script call by method info
58 /// </summary>
59 /// <param name="target">If target is a Type object, will assume method is static.</param>
60 /// <param name="method"></param>
50 void RegisterScriptInvocation(object target, MethodInfo method); 61 void RegisterScriptInvocation(object target, MethodInfo method);
62
63 /// <summary>
64 /// Register one or more instance methods as script calls by method name
65 /// </summary>
66 /// <param name="target"></param>
67 /// <param name="methods"></param>
51 void RegisterScriptInvocation(object target, string[] methods); 68 void RegisterScriptInvocation(object target, string[] methods);
69
70 /// <summary>
71 /// Register one or more static methods as script calls by method name
72 /// </summary>
73 /// <param name="target"></param>
74 /// <param name="methods"></param>
75 void RegisterScriptInvocation(Type target, string[] methods);
76
77 /// <summary>
78 /// Returns an array of all registered script calls
79 /// </summary>
80 /// <returns></returns>
52 Delegate[] GetScriptInvocationList(); 81 Delegate[] GetScriptInvocationList();
53 82
54 Delegate LookupScriptInvocation(string fname); 83 Delegate LookupScriptInvocation(string fname);
diff --git a/OpenSim/Region/Framework/Interfaces/IUrlModule.cs b/OpenSim/Region/Framework/Interfaces/IUrlModule.cs
index 457444c..79e9f9d 100644
--- a/OpenSim/Region/Framework/Interfaces/IUrlModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IUrlModule.cs
@@ -39,6 +39,8 @@ namespace OpenSim.Region.Framework.Interfaces
39 UUID RequestSecureURL(IScriptModule engine, SceneObjectPart host, UUID itemID); 39 UUID RequestSecureURL(IScriptModule engine, SceneObjectPart host, UUID itemID);
40 void ReleaseURL(string url); 40 void ReleaseURL(string url);
41 void HttpResponse(UUID request, int status, string body); 41 void HttpResponse(UUID request, int status, string body);
42 void HttpContentType(UUID request, string type);
43
42 string GetHttpHeader(UUID request, string header); 44 string GetHttpHeader(UUID request, string header);
43 int GetFreeUrls(); 45 int GetFreeUrls();
44 46
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index eee5960..e257b57 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -47,30 +47,75 @@ namespace OpenSim.Region.Framework.Scenes
47 47
48 public delegate void OnFrameDelegate(); 48 public delegate void OnFrameDelegate();
49 49
50 /// <summary>
51 /// Triggered on each sim frame.
52 /// </summary>
53 /// <remarks>
54 /// This gets triggered in <see cref="OpenSim.Region.Framework.Scenes.Scene.Update"/>
55 /// Core uses it for things like Sun, Wind & Clouds
56 /// The MRM module also uses it.
57 /// </remarks>
50 public event OnFrameDelegate OnFrame; 58 public event OnFrameDelegate OnFrame;
51 59
52 public delegate void ClientMovement(ScenePresence client); 60 public delegate void ClientMovement(ScenePresence client);
53 61
62 /// <summary>
63 /// Trigerred when an agent moves.
64 /// </summary>
65 /// <remarks>
66 /// This gets triggered in <see cref="OpenSim.Region.Framework.Scenes.ScenePresence.HandleAgentUpdate"/>
67 /// prior to <see cref="OpenSim.Region.Framework.Scenes.ScenePresence.TriggerScenePresenceUpdated"/>
68 /// </remarks>
54 public event ClientMovement OnClientMovement; 69 public event ClientMovement OnClientMovement;
55 70
56 public delegate void OnTerrainTaintedDelegate(); 71 public delegate void OnTerrainTaintedDelegate();
57 72
73 /// <summary>
74 /// Triggered if the terrain has been edited
75 /// </summary>
76 /// <remarks>
77 /// This gets triggered in <see cref="OpenSim.Region.CoreModules.World.Terrain.CheckForTerrainUpdates"/>
78 /// after it determines that an update has been made.
79 /// </remarks>
58 public event OnTerrainTaintedDelegate OnTerrainTainted; 80 public event OnTerrainTaintedDelegate OnTerrainTainted;
59 81
60 public delegate void OnTerrainTickDelegate(); 82 public delegate void OnTerrainTickDelegate();
61 83
62 public delegate void OnTerrainUpdateDelegate(); 84 /// <summary>
63 85 /// Triggered if the terrain has been edited
86 /// </summary>
87 /// <remarks>
88 /// This gets triggered in <see cref="OpenSim.Region.Framework.Scenes.Scene.UpdateTerrain"/>
89 /// but is used by core solely to update the physics engine.
90 /// </remarks>
64 public event OnTerrainTickDelegate OnTerrainTick; 91 public event OnTerrainTickDelegate OnTerrainTick;
65 92
93 public delegate void OnTerrainUpdateDelegate();
94
66 public event OnTerrainUpdateDelegate OnTerrainUpdate; 95 public event OnTerrainUpdateDelegate OnTerrainUpdate;
67 96
68 public delegate void OnBackupDelegate(ISimulationDataService datastore, bool forceBackup); 97 public delegate void OnBackupDelegate(ISimulationDataService datastore, bool forceBackup);
69 98
99 /// <summary>
100 /// Triggered when a region is backed up/persisted to storage
101 /// </summary>
102 /// <remarks>
103 /// This gets triggered in <see cref="OpenSim.Region.Framework.Scenes.Scene.Backup"/>
104 /// and is fired before the persistence occurs.
105 /// </remarks>
70 public event OnBackupDelegate OnBackup; 106 public event OnBackupDelegate OnBackup;
71 107
72 public delegate void OnClientConnectCoreDelegate(IClientCore client); 108 public delegate void OnClientConnectCoreDelegate(IClientCore client);
73 109
110 /// <summary>
111 /// Triggered when a new client connects to the scene.
112 /// </summary>
113 /// <remarks>
114 /// This gets triggered in <see cref="TriggerOnNewClient"/>,
115 /// which checks if an instance of <see cref="OpenSim.Framework.IClientAPI"/>
116 /// also implements <see cref="OpenSim.Framework.Client.IClientCore"/> and as such,
117 /// is not triggered by <see cref="OpenSim.Region.OptionalModules.World.NPC">NPCs</see>.
118 /// </remarks>
74 public event OnClientConnectCoreDelegate OnClientConnect; 119 public event OnClientConnectCoreDelegate OnClientConnect;
75 120
76 public delegate void OnNewClientDelegate(IClientAPI client); 121 public delegate void OnNewClientDelegate(IClientAPI client);
@@ -91,18 +136,54 @@ namespace OpenSim.Region.Framework.Scenes
91 136
92 public delegate void OnNewPresenceDelegate(ScenePresence presence); 137 public delegate void OnNewPresenceDelegate(ScenePresence presence);
93 138
139 /// <summary>
140 /// Triggered when a new presence is added to the scene
141 /// </summary>
142 /// <remarks>
143 /// Triggered in <see cref="OpenSim.Region.Framework.Scenes.Scene.AddNewClient"/> which is used by both
144 /// <see cref="OpenSim.Framework.PresenceType.User">users</see> and <see cref="OpenSim.Framework.PresenceType.Npc">NPCs</see>
145 /// </remarks>
94 public event OnNewPresenceDelegate OnNewPresence; 146 public event OnNewPresenceDelegate OnNewPresence;
95 147
96 public delegate void OnRemovePresenceDelegate(UUID agentId); 148 public delegate void OnRemovePresenceDelegate(UUID agentId);
97 149
150 /// <summary>
151 /// Triggered when a presence is removed from the scene
152 /// </summary>
153 /// <remarks>
154 /// Triggered in <see cref="OpenSim.Region.Framework.Scenes.Scene.AddNewClient"/> which is used by both
155 /// <see cref="OpenSim.Framework.PresenceType.User">users</see> and <see cref="OpenSim.Framework.PresenceType.Npc">NPCs</see>
156 /// </remarks>
98 public event OnRemovePresenceDelegate OnRemovePresence; 157 public event OnRemovePresenceDelegate OnRemovePresence;
99 158
100 public delegate void OnParcelPrimCountUpdateDelegate(); 159 public delegate void OnParcelPrimCountUpdateDelegate();
101 160
161 /// <summary>
162 /// Triggered whenever the prim count may have been altered, or prior
163 /// to an action that requires the current prim count to be accurate.
164 /// </summary>
165 /// <remarks>
166 /// Triggered by <see cref="TriggerParcelPrimCountUpdate"/> in
167 /// <see cref="OpenSim.OpenSimBase.CreateRegion"/>,
168 /// <see cref="OpenSim.Region.CoreModules.World.Land.LandManagementModule.EventManagerOnRequestParcelPrimCountUpdate"/>,
169 /// <see cref="OpenSim.Region.CoreModules.World.Land.LandManagementModule.ClientOnParcelObjectOwnerRequest"/>,
170 /// <see cref="OpenSim.Region.CoreModules.World.Land.LandObject.GetPrimsFree"/>,
171 /// <see cref="OpenSim.Region.CoreModules.World.Land.LandObject.UpdateLandSold"/>,
172 /// <see cref="OpenSim.Region.CoreModules.World.Land.LandObject.DeedToGroup"/>,
173 /// <see cref="OpenSim.Region.CoreModules.World.Land.LandObject.SendLandUpdateToClient"/>
174 /// </remarks>
102 public event OnParcelPrimCountUpdateDelegate OnParcelPrimCountUpdate; 175 public event OnParcelPrimCountUpdateDelegate OnParcelPrimCountUpdate;
103 176
104 public delegate void OnParcelPrimCountAddDelegate(SceneObjectGroup obj); 177 public delegate void OnParcelPrimCountAddDelegate(SceneObjectGroup obj);
105 178
179 /// <summary>
180 /// Triggered in response to <see cref="OnParcelPrimCountUpdate"/> for
181 /// objects that actually contribute to parcel prim count.
182 /// </summary>
183 /// <remarks>
184 /// Triggered by <see cref="TriggerParcelPrimCountAdd"/> in
185 /// <see cref="OpenSim.Region.CoreModules.World.Land.LandManagementModule.EventManagerOnParcelPrimCountUpdate"/>
186 /// </remarks>
106 public event OnParcelPrimCountAddDelegate OnParcelPrimCountAdd; 187 public event OnParcelPrimCountAddDelegate OnParcelPrimCountAdd;
107 188
108 public delegate void OnPluginConsoleDelegate(string[] args); 189 public delegate void OnPluginConsoleDelegate(string[] args);
@@ -123,6 +204,14 @@ namespace OpenSim.Region.Framework.Scenes
123 204
124 public event OnSetRootAgentSceneDelegate OnSetRootAgentScene; 205 public event OnSetRootAgentSceneDelegate OnSetRootAgentScene;
125 206
207 /// <summary>
208 /// Triggered after parcel properties have been updated.
209 /// </summary>
210 /// <remarks>
211 /// Triggered by <see cref="TriggerOnParcelPropertiesUpdateRequest"/> in
212 /// <see cref="OpenSim.Region.CoreModules.World.Land.LandManagementModule.ClientOnParcelPropertiesUpdateRequest"/>,
213 /// <see cref="OpenSim.Region.CoreModules.World.Land.LandManagementModule.ProcessPropertiesUpdate"/>
214 /// </remarks>
126 public event ParcelPropertiesUpdateRequest OnParcelPropertiesUpdateRequest; 215 public event ParcelPropertiesUpdateRequest OnParcelPropertiesUpdateRequest;
127 216
128 /// <summary> 217 /// <summary>
@@ -373,6 +462,20 @@ namespace OpenSim.Region.Framework.Scenes
373 public event RequestParcelPrimCountUpdate OnRequestParcelPrimCountUpdate; 462 public event RequestParcelPrimCountUpdate OnRequestParcelPrimCountUpdate;
374 463
375 public delegate void ParcelPrimCountTainted(); 464 public delegate void ParcelPrimCountTainted();
465
466 /// <summary>
467 /// Triggered when the parcel prim count has been altered.
468 /// </summary>
469 /// <remarks>
470 /// Triggered by <see cref="TriggerParcelPrimCountTainted"/> in
471 /// <see cref="OpenSim.Region.CoreModules.Avatar.Attachments.AttachmentsModule.DetachSingleAttachmentToGround"/>,
472 /// <see cref="OpenSim.Region.CoreModules.Avatar.Attachments.AttachmentsModule.AttachToAgent"/>,
473 /// <see cref="Scene.DeleteSceneObject"/>,
474 /// <see cref="Scene.SelectPrim"/>,
475 /// <see cref="Scene.DeselectPrim"/>,
476 /// <see cref="SceneObjectGroup.UpdatePrimFlags"/>,
477 /// <see cref="SceneObjectGroup.AbsolutePosition"/>
478 /// </remarks>
376 public event ParcelPrimCountTainted OnParcelPrimCountTainted; 479 public event ParcelPrimCountTainted OnParcelPrimCountTainted;
377 public event GetScriptRunning OnGetScriptRunning; 480 public event GetScriptRunning OnGetScriptRunning;
378 481
@@ -432,7 +535,7 @@ namespace OpenSim.Region.Framework.Scenes
432 /// the scripts may not have started yet 535 /// the scripts may not have started yet
433 /// Message is non empty string if there were problems loading the oar file 536 /// Message is non empty string if there were problems loading the oar file
434 /// </summary> 537 /// </summary>
435 public delegate void OarFileLoaded(Guid guid, string message); 538 public delegate void OarFileLoaded(Guid guid, List<UUID> loadedScenes, string message);
436 public event OarFileLoaded OnOarFileLoaded; 539 public event OarFileLoaded OnOarFileLoaded;
437 540
438 /// <summary> 541 /// <summary>
@@ -485,6 +588,9 @@ namespace OpenSim.Region.Framework.Scenes
485 /// <param name="copy"></param> 588 /// <param name="copy"></param>
486 /// <param name="original"></param> 589 /// <param name="original"></param>
487 /// <param name="userExposed">True if the duplicate will immediately be in the scene, false otherwise</param> 590 /// <param name="userExposed">True if the duplicate will immediately be in the scene, false otherwise</param>
591 /// <remarks>
592 /// Triggered in <see cref="OpenSim.Region.Framework.Scenes.SceneObjectPart.Copy"/>
593 /// </remarks>
488 public event SceneObjectPartCopyDelegate OnSceneObjectPartCopy; 594 public event SceneObjectPartCopyDelegate OnSceneObjectPartCopy;
489 public delegate void SceneObjectPartCopyDelegate(SceneObjectPart copy, SceneObjectPart original, bool userExposed); 595 public delegate void SceneObjectPartCopyDelegate(SceneObjectPart copy, SceneObjectPart original, bool userExposed);
490 596
@@ -593,8 +699,29 @@ namespace OpenSim.Region.Framework.Scenes
593 699
594 public delegate void LandBuy(Object sender, LandBuyArgs e); 700 public delegate void LandBuy(Object sender, LandBuyArgs e);
595 701
702 /// <summary>
703 /// Triggered when an attempt to transfer grid currency occurs
704 /// </summary>
705 /// <remarks>
706 /// Triggered in <see cref="OpenSim.Region.Framework.Scenes.Scene.ProcessMoneyTransferRequest"/>
707 /// via <see cref="OpenSim.Region.Framework.Scenes.Scene.SubscribeToClientGridEvents"/>
708 /// via <see cref="OpenSim.Region.Framework.Scenes.Scene.SubscribeToClientEvents"/>
709 /// via <see cref="OpenSim.Region.Framework.Scenes.Scene.AddNewClient"/>
710 /// </remarks>
596 public event MoneyTransferEvent OnMoneyTransfer; 711 public event MoneyTransferEvent OnMoneyTransfer;
712
713 /// <summary>
714 /// Triggered after after <see cref="OnValidateLandBuy"/>
715 /// </summary>
597 public event LandBuy OnLandBuy; 716 public event LandBuy OnLandBuy;
717
718 /// <summary>
719 /// Triggered to allow or prevent a real estate transaction
720 /// </summary>
721 /// <remarks>
722 /// Triggered in <see cref="OpenSim.Region.Framework.Scenes.Scene.ProcessParcelBuy"/>
723 /// <seealso cref="OpenSim.Region.OptionalModules.World.MoneyModule.SampleMoneyModule.ValidateLandBuy"/>
724 /// </remarks>
598 public event LandBuy OnValidateLandBuy; 725 public event LandBuy OnValidateLandBuy;
599 726
600 public void TriggerOnAttach(uint localID, UUID itemID, UUID avatarID) 727 public void TriggerOnAttach(uint localID, UUID itemID, UUID avatarID)
@@ -2093,7 +2220,7 @@ namespace OpenSim.Region.Framework.Scenes
2093 return 6; 2220 return 6;
2094 } 2221 }
2095 2222
2096 public void TriggerOarFileLoaded(Guid requestId, string message) 2223 public void TriggerOarFileLoaded(Guid requestId, List<UUID> loadedScenes, string message)
2097 { 2224 {
2098 OarFileLoaded handlerOarFileLoaded = OnOarFileLoaded; 2225 OarFileLoaded handlerOarFileLoaded = OnOarFileLoaded;
2099 if (handlerOarFileLoaded != null) 2226 if (handlerOarFileLoaded != null)
@@ -2102,7 +2229,7 @@ namespace OpenSim.Region.Framework.Scenes
2102 { 2229 {
2103 try 2230 try
2104 { 2231 {
2105 d(requestId, message); 2232 d(requestId, loadedScenes, message);
2106 } 2233 }
2107 catch (Exception e) 2234 catch (Exception e)
2108 { 2235 {
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 2d9a035..3d68081 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -93,7 +93,7 @@ namespace OpenSim.Region.Framework.Scenes
93 /// </summary> 93 /// </summary>
94 public void StartScripts() 94 public void StartScripts()
95 { 95 {
96 m_log.InfoFormat("[SCENE]: Starting scripts in {0}, please wait.", RegionInfo.RegionName); 96// m_log.InfoFormat("[SCENE]: Starting scripts in {0}, please wait.", RegionInfo.RegionName);
97 97
98 IScriptModule[] engines = RequestModuleInterfaces<IScriptModule>(); 98 IScriptModule[] engines = RequestModuleInterfaces<IScriptModule>();
99 99
@@ -1986,6 +1986,9 @@ namespace OpenSim.Region.Framework.Scenes
1986 // If child prims have invalid perms, fix them 1986 // If child prims have invalid perms, fix them
1987 grp.AdjustChildPrimPermissions(); 1987 grp.AdjustChildPrimPermissions();
1988 1988
1989 // If child prims have invalid perms, fix them
1990 grp.AdjustChildPrimPermissions();
1991
1989 if (remoteClient == null) 1992 if (remoteClient == null)
1990 { 1993 {
1991 // Autoreturn has a null client. Nothing else does. So 1994 // Autoreturn has a null client. Nothing else does. So
diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
index e970543..16c0d25 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
@@ -543,7 +543,7 @@ namespace OpenSim.Region.Framework.Scenes
543 if (!InventoryService.AddFolder(folder)) 543 if (!InventoryService.AddFolder(folder))
544 { 544 {
545 m_log.WarnFormat( 545 m_log.WarnFormat(
546 "[AGENT INVENTORY]: Failed to move create folder for user {0} {1}", 546 "[AGENT INVENTORY]: Failed to create folder for user {0} {1}",
547 remoteClient.Name, remoteClient.AgentId); 547 remoteClient.Name, remoteClient.AgentId);
548 } 548 }
549 } 549 }
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 9b9ad80..a5fcf4d 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -103,8 +103,31 @@ namespace OpenSim.Region.Framework.Scenes
103 /// </summary> 103 /// </summary>
104 public bool CollidablePrims { get; private set; } 104 public bool CollidablePrims { get; private set; }
105 105
106 /// <summary>
107 /// Minimum value of the size of a non-physical prim in each axis
108 /// </summary>
109 public float m_minNonphys = 0.01f;
110
111 /// <summary>
112 /// Maximum value of the size of a non-physical prim in each axis
113 /// </summary>
106 public float m_maxNonphys = 256; 114 public float m_maxNonphys = 256;
115
116 /// <summary>
117 /// Minimum value of the size of a physical prim in each axis
118 /// </summary>
119 public float m_minPhys = 0.01f;
120
121 /// <summary>
122 /// Maximum value of the size of a physical prim in each axis
123 /// </summary>
107 public float m_maxPhys = 10; 124 public float m_maxPhys = 10;
125
126 /// <summary>
127 /// Max prims an object will hold
128 /// </summary>
129 public int m_linksetCapacity = 0;
130
108 public bool m_clampPrimSize; 131 public bool m_clampPrimSize;
109 public bool m_trustBinaries; 132 public bool m_trustBinaries;
110 public bool m_allowScriptCrossings; 133 public bool m_allowScriptCrossings;
@@ -746,12 +769,24 @@ namespace OpenSim.Region.Framework.Scenes
746 PhysicalPrims = startupConfig.GetBoolean("physical_prim", true); 769 PhysicalPrims = startupConfig.GetBoolean("physical_prim", true);
747 CollidablePrims = startupConfig.GetBoolean("collidable_prim", true); 770 CollidablePrims = startupConfig.GetBoolean("collidable_prim", true);
748 771
772 m_minNonphys = startupConfig.GetFloat("NonphysicalPrimMin", m_minNonphys);
773 if (RegionInfo.NonphysPrimMin > 0)
774 {
775 m_minNonphys = RegionInfo.NonphysPrimMin;
776 }
777
749 m_maxNonphys = startupConfig.GetFloat("NonphysicalPrimMax", m_maxNonphys); 778 m_maxNonphys = startupConfig.GetFloat("NonphysicalPrimMax", m_maxNonphys);
750 if (RegionInfo.NonphysPrimMax > 0) 779 if (RegionInfo.NonphysPrimMax > 0)
751 { 780 {
752 m_maxNonphys = RegionInfo.NonphysPrimMax; 781 m_maxNonphys = RegionInfo.NonphysPrimMax;
753 } 782 }
754 783
784 m_minPhys = startupConfig.GetFloat("PhysicalPrimMin", m_minPhys);
785 if (RegionInfo.PhysPrimMin > 0)
786 {
787 m_minPhys = RegionInfo.PhysPrimMin;
788 }
789
755 m_maxPhys = startupConfig.GetFloat("PhysicalPrimMax", m_maxPhys); 790 m_maxPhys = startupConfig.GetFloat("PhysicalPrimMax", m_maxPhys);
756 791
757 if (RegionInfo.PhysPrimMax > 0) 792 if (RegionInfo.PhysPrimMax > 0)
@@ -759,6 +794,12 @@ namespace OpenSim.Region.Framework.Scenes
759 m_maxPhys = RegionInfo.PhysPrimMax; 794 m_maxPhys = RegionInfo.PhysPrimMax;
760 } 795 }
761 796
797 m_linksetCapacity = startupConfig.GetInt("LinksetPrims", m_linksetCapacity);
798 if (RegionInfo.LinksetCapacity > 0)
799 {
800 m_linksetCapacity = RegionInfo.LinksetCapacity;
801 }
802
762 SpawnPointRouting = startupConfig.GetString("SpawnPointRouting", "closest"); 803 SpawnPointRouting = startupConfig.GetString("SpawnPointRouting", "closest");
763 TelehubAllowLandmarks = startupConfig.GetBoolean("TelehubAllowLandmark", false); 804 TelehubAllowLandmarks = startupConfig.GetBoolean("TelehubAllowLandmark", false);
764 805
@@ -3715,7 +3756,7 @@ namespace OpenSim.Region.Framework.Scenes
3715 "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.", 3756 "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.",
3716 sp.Name, sp.UUID, RegionInfo.RegionName); 3757 sp.Name, sp.UUID, RegionInfo.RegionName);
3717 3758
3718 sp.ControllingClient.Close(); 3759 sp.ControllingClient.Close(true, true);
3719 sp = null; 3760 sp = null;
3720 } 3761 }
3721 3762
@@ -4318,15 +4359,18 @@ namespace OpenSim.Region.Framework.Scenes
4318 /// Tell a single agent to disconnect from the region. 4359 /// Tell a single agent to disconnect from the region.
4319 /// </summary> 4360 /// </summary>
4320 /// <param name="agentID"></param> 4361 /// <param name="agentID"></param>
4321 /// <param name="childOnly"></param> 4362 /// <param name="force">
4322 public bool IncomingCloseAgent(UUID agentID, bool childOnly) 4363 /// Force the agent to close even if it might be in the middle of some other operation. You do not want to
4364 /// force unless you are absolutely sure that the agent is dead and a normal close is not working.
4365 /// </param>
4366 public bool IncomingCloseAgent(UUID agentID, bool force)
4323 { 4367 {
4324 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID); 4368 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID);
4325 4369
4326 ScenePresence presence = m_sceneGraph.GetScenePresence(agentID); 4370 ScenePresence presence = m_sceneGraph.GetScenePresence(agentID);
4327 if (presence != null) 4371 if (presence != null)
4328 { 4372 {
4329 presence.ControllingClient.Close(); 4373 presence.ControllingClient.Close(true, force);
4330 return true; 4374 return true;
4331 } 4375 }
4332 4376
@@ -4532,6 +4576,16 @@ namespace OpenSim.Region.Framework.Scenes
4532 return LandChannel.GetLandObject(x, y).LandData; 4576 return LandChannel.GetLandObject(x, y).LandData;
4533 } 4577 }
4534 4578
4579 /// <summary>
4580 /// Get LandData by position.
4581 /// </summary>
4582 /// <param name="pos"></param>
4583 /// <returns></returns>
4584 public LandData GetLandData(Vector3 pos)
4585 {
4586 return GetLandData(pos.X, pos.Y);
4587 }
4588
4535 public LandData GetLandData(uint x, uint y) 4589 public LandData GetLandData(uint x, uint y)
4536 { 4590 {
4537 m_log.DebugFormat("[SCENE]: returning land for {0},{1}", x, y); 4591 m_log.DebugFormat("[SCENE]: returning land for {0},{1}", x, y);
@@ -4780,6 +4834,18 @@ namespace OpenSim.Region.Framework.Scenes
4780 } 4834 }
4781 4835
4782 /// <summary> 4836 /// <summary>
4837 /// Attempt to get the SOG via its UUID
4838 /// </summary>
4839 /// <param name="fullID"></param>
4840 /// <param name="sog"></param>
4841 /// <returns></returns>
4842 public bool TryGetSceneObjectGroup(UUID fullID, out SceneObjectGroup sog)
4843 {
4844 sog = GetSceneObjectGroup(fullID);
4845 return sog != null;
4846 }
4847
4848 /// <summary>
4783 /// Get a prim by name from the scene (will return the first 4849 /// Get a prim by name from the scene (will return the first
4784 /// found, if there are more than one prim with the same name) 4850 /// found, if there are more than one prim with the same name)
4785 /// </summary> 4851 /// </summary>
@@ -4811,6 +4877,18 @@ namespace OpenSim.Region.Framework.Scenes
4811 } 4877 }
4812 4878
4813 /// <summary> 4879 /// <summary>
4880 /// Attempt to get a prim via its UUID
4881 /// </summary>
4882 /// <param name="fullID"></param>
4883 /// <param name="sop"></param>
4884 /// <returns></returns>
4885 public bool TryGetSceneObjectPart(UUID fullID, out SceneObjectPart sop)
4886 {
4887 sop = GetSceneObjectPart(fullID);
4888 return sop != null;
4889 }
4890
4891 /// <summary>
4814 /// Get a scene object group that contains the prim with the given local id 4892 /// Get a scene object group that contains the prim with the given local id
4815 /// </summary> 4893 /// </summary>
4816 /// <param name="localID"></param> 4894 /// <param name="localID"></param>
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index e29b2c1..c4b7b27 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -342,7 +342,7 @@ namespace OpenSim.Region.Framework.Scenes
342 public bool AddNewSceneObject( 342 public bool AddNewSceneObject(
343 SceneObjectGroup sceneObject, bool attachToBackup, Vector3? pos, Quaternion? rot, Vector3 vel) 343 SceneObjectGroup sceneObject, bool attachToBackup, Vector3? pos, Quaternion? rot, Vector3 vel)
344 { 344 {
345 AddNewSceneObject(sceneObject, true, false); 345 AddNewSceneObject(sceneObject, attachToBackup, false);
346 346
347 if (pos != null) 347 if (pos != null)
348 sceneObject.AbsolutePosition = (Vector3)pos; 348 sceneObject.AbsolutePosition = (Vector3)pos;
@@ -421,12 +421,9 @@ namespace OpenSim.Region.Framework.Scenes
421 { 421 {
422 Vector3 scale = part.Shape.Scale; 422 Vector3 scale = part.Shape.Scale;
423 423
424 if (scale.X > m_parentScene.m_maxNonphys) 424 scale.X = Math.Max(m_parentScene.m_minNonphys, Math.Min(m_parentScene.m_maxNonphys, scale.X));
425 scale.X = m_parentScene.m_maxNonphys; 425 scale.Y = Math.Max(m_parentScene.m_minNonphys, Math.Min(m_parentScene.m_maxNonphys, scale.Y));
426 if (scale.Y > m_parentScene.m_maxNonphys) 426 scale.Z = Math.Max(m_parentScene.m_minNonphys, Math.Min(m_parentScene.m_maxNonphys, scale.Z));
427 scale.Y = m_parentScene.m_maxNonphys;
428 if (scale.Z > m_parentScene.m_maxNonphys)
429 scale.Z = m_parentScene.m_maxNonphys;
430 427
431 part.Shape.Scale = scale; 428 part.Shape.Scale = scale;
432 } 429 }
diff --git a/OpenSim/Region/Framework/Scenes/SceneManager.cs b/OpenSim/Region/Framework/Scenes/SceneManager.cs
index f1b09ca..dba3a61 100644
--- a/OpenSim/Region/Framework/Scenes/SceneManager.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneManager.cs
@@ -92,7 +92,11 @@ namespace OpenSim.Region.Framework.Scenes
92 private static SceneManager m_instance = null; 92 private static SceneManager m_instance = null;
93 public static SceneManager Instance 93 public static SceneManager Instance
94 { 94 {
95 get { return m_instance; } 95 get {
96 if (m_instance == null)
97 m_instance = new SceneManager();
98 return m_instance;
99 }
96 } 100 }
97 101
98 private readonly DoubleDictionary<UUID, string, Scene> m_localScenes = new DoubleDictionary<UUID, string, Scene>(); 102 private readonly DoubleDictionary<UUID, string, Scene> m_localScenes = new DoubleDictionary<UUID, string, Scene>();
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 4798481..f1df6d6 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -2742,6 +2742,25 @@ namespace OpenSim.Region.Framework.Scenes
2742 if (objectGroup == this) 2742 if (objectGroup == this)
2743 return; 2743 return;
2744 2744
2745 // If the configured linkset capacity is greater than zero,
2746 // and the new linkset would have a prim count higher than this
2747 // value, do not link it.
2748 if (m_scene.m_linksetCapacity > 0 &&
2749 (PrimCount + objectGroup.PrimCount) >
2750 m_scene.m_linksetCapacity)
2751 {
2752 m_log.DebugFormat(
2753 "[SCENE OBJECT GROUP]: Cannot link group with root" +
2754 " part {0}, {1} ({2} prims) to group with root part" +
2755 " {3}, {4} ({5} prims) because the new linkset" +
2756 " would exceed the configured maximum of {6}",
2757 objectGroup.RootPart.Name, objectGroup.RootPart.UUID,
2758 objectGroup.PrimCount, RootPart.Name, RootPart.UUID,
2759 PrimCount, m_scene.m_linksetCapacity);
2760
2761 return;
2762 }
2763
2745 // 'linkPart' == the root of the group being linked into this group 2764 // 'linkPart' == the root of the group being linked into this group
2746 SceneObjectPart linkPart = objectGroup.m_rootPart; 2765 SceneObjectPart linkPart = objectGroup.m_rootPart;
2747 2766
@@ -3464,17 +3483,17 @@ namespace OpenSim.Region.Framework.Scenes
3464 /// <param name="scale"></param> 3483 /// <param name="scale"></param>
3465 public void GroupResize(Vector3 scale) 3484 public void GroupResize(Vector3 scale)
3466 { 3485 {
3467 scale.X = Math.Min(scale.X, Scene.m_maxNonphys); 3486 scale.X = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.X));
3468 scale.Y = Math.Min(scale.Y, Scene.m_maxNonphys); 3487 scale.Y = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.Y));
3469 scale.Z = Math.Min(scale.Z, Scene.m_maxNonphys); 3488 scale.Z = Math.Max(Scene.m_minNonphys, Math.Min(Scene.m_maxNonphys, scale.Z));
3470 3489
3471 PhysicsActor pa = m_rootPart.PhysActor; 3490 PhysicsActor pa = m_rootPart.PhysActor;
3472 3491
3473 if (pa != null && pa.IsPhysical) 3492 if (pa != null && pa.IsPhysical)
3474 { 3493 {
3475 scale.X = Math.Min(scale.X, Scene.m_maxPhys); 3494 scale.X = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.X));
3476 scale.Y = Math.Min(scale.Y, Scene.m_maxPhys); 3495 scale.Y = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.Y));
3477 scale.Z = Math.Min(scale.Z, Scene.m_maxPhys); 3496 scale.Z = Math.Max(Scene.m_minPhys, Math.Min(Scene.m_maxPhys, scale.Z));
3478 } 3497 }
3479 3498
3480 float x = (scale.X / RootPart.Scale.X); 3499 float x = (scale.X / RootPart.Scale.X);
@@ -3505,6 +3524,14 @@ namespace OpenSim.Region.Framework.Scenes
3505 y *= a; 3524 y *= a;
3506 z *= a; 3525 z *= a;
3507 } 3526 }
3527 else if (oldSize.X * x < m_scene.m_minPhys)
3528 {
3529 f = m_scene.m_minPhys / oldSize.X;
3530 a = f / x;
3531 x *= a;
3532 y *= a;
3533 z *= a;
3534 }
3508 3535
3509 if (oldSize.Y * y > m_scene.m_maxPhys) 3536 if (oldSize.Y * y > m_scene.m_maxPhys)
3510 { 3537 {
@@ -3514,6 +3541,14 @@ namespace OpenSim.Region.Framework.Scenes
3514 y *= a; 3541 y *= a;
3515 z *= a; 3542 z *= a;
3516 } 3543 }
3544 else if (oldSize.Y * y < m_scene.m_minPhys)
3545 {
3546 f = m_scene.m_minPhys / oldSize.Y;
3547 a = f / y;
3548 x *= a;
3549 y *= a;
3550 z *= a;
3551 }
3517 3552
3518 if (oldSize.Z * z > m_scene.m_maxPhys) 3553 if (oldSize.Z * z > m_scene.m_maxPhys)
3519 { 3554 {
@@ -3523,6 +3558,14 @@ namespace OpenSim.Region.Framework.Scenes
3523 y *= a; 3558 y *= a;
3524 z *= a; 3559 z *= a;
3525 } 3560 }
3561 else if (oldSize.Z * z < m_scene.m_minPhys)
3562 {
3563 f = m_scene.m_minPhys / oldSize.Z;
3564 a = f / z;
3565 x *= a;
3566 y *= a;
3567 z *= a;
3568 }
3526 } 3569 }
3527 else 3570 else
3528 { 3571 {
@@ -3534,6 +3577,14 @@ namespace OpenSim.Region.Framework.Scenes
3534 y *= a; 3577 y *= a;
3535 z *= a; 3578 z *= a;
3536 } 3579 }
3580 else if (oldSize.X * x < m_scene.m_minNonphys)
3581 {
3582 f = m_scene.m_minNonphys / oldSize.X;
3583 a = f / x;
3584 x *= a;
3585 y *= a;
3586 z *= a;
3587 }
3537 3588
3538 if (oldSize.Y * y > m_scene.m_maxNonphys) 3589 if (oldSize.Y * y > m_scene.m_maxNonphys)
3539 { 3590 {
@@ -3543,6 +3594,14 @@ namespace OpenSim.Region.Framework.Scenes
3543 y *= a; 3594 y *= a;
3544 z *= a; 3595 z *= a;
3545 } 3596 }
3597 else if (oldSize.Y * y < m_scene.m_minNonphys)
3598 {
3599 f = m_scene.m_minNonphys / oldSize.Y;
3600 a = f / y;
3601 x *= a;
3602 y *= a;
3603 z *= a;
3604 }
3546 3605
3547 if (oldSize.Z * z > m_scene.m_maxNonphys) 3606 if (oldSize.Z * z > m_scene.m_maxNonphys)
3548 { 3607 {
@@ -3552,6 +3611,14 @@ namespace OpenSim.Region.Framework.Scenes
3552 y *= a; 3611 y *= a;
3553 z *= a; 3612 z *= a;
3554 } 3613 }
3614 else if (oldSize.Z * z < m_scene.m_minNonphys)
3615 {
3616 f = m_scene.m_minNonphys / oldSize.Z;
3617 a = f / z;
3618 x *= a;
3619 y *= a;
3620 z *= a;
3621 }
3555 } 3622 }
3556 } 3623 }
3557 } 3624 }
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 56d289f..4af508e 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -790,7 +790,7 @@ namespace OpenSim.Region.Framework.Scenes
790 } 790 }
791 catch (Exception e) 791 catch (Exception e)
792 { 792 {
793 m_log.Error("[SCENEOBJECTPART]: GROUP POSITION. " + e.Message); 793 m_log.ErrorFormat("[SCENEOBJECTPART]: GROUP POSITION. {0}", e);
794 } 794 }
795 } 795 }
796 } 796 }
@@ -2972,17 +2972,16 @@ namespace OpenSim.Region.Framework.Scenes
2972 /// <param name="scale"></param> 2972 /// <param name="scale"></param>
2973 public void Resize(Vector3 scale) 2973 public void Resize(Vector3 scale)
2974 { 2974 {
2975 scale.X = Math.Min(scale.X, ParentGroup.Scene.m_maxNonphys); 2975 scale.X = Math.Max(ParentGroup.Scene.m_minNonphys, Math.Min(ParentGroup.Scene.m_maxNonphys, scale.X));
2976 scale.Y = Math.Min(scale.Y, ParentGroup.Scene.m_maxNonphys); 2976 scale.Y = Math.Max(ParentGroup.Scene.m_minNonphys, Math.Min(ParentGroup.Scene.m_maxNonphys, scale.Y));
2977 scale.Z = Math.Min(scale.Z, ParentGroup.Scene.m_maxNonphys); 2977 scale.Z = Math.Max(ParentGroup.Scene.m_minNonphys, Math.Min(ParentGroup.Scene.m_maxNonphys, scale.Z));
2978 2978
2979 PhysicsActor pa = PhysActor; 2979 PhysicsActor pa = PhysActor;
2980
2981 if (pa != null && pa.IsPhysical) 2980 if (pa != null && pa.IsPhysical)
2982 { 2981 {
2983 scale.X = Math.Min(scale.X, ParentGroup.Scene.m_maxPhys); 2982 scale.X = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.X));
2984 scale.Y = Math.Min(scale.Y, ParentGroup.Scene.m_maxPhys); 2983 scale.Y = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.Y));
2985 scale.Z = Math.Min(scale.Z, ParentGroup.Scene.m_maxPhys); 2984 scale.Z = Math.Max(ParentGroup.Scene.m_minPhys, Math.Min(ParentGroup.Scene.m_maxPhys, scale.Z));
2986 } 2985 }
2987 2986
2988// m_log.DebugFormat("[SCENE OBJECT PART]: Resizing {0} {1} to {2}", Name, LocalId, scale); 2987// m_log.DebugFormat("[SCENE OBJECT PART]: Resizing {0} {1} to {2}", Name, LocalId, scale);
@@ -3567,23 +3566,32 @@ namespace OpenSim.Region.Framework.Scenes
3567 } 3566 }
3568 3567
3569 /// <summary> 3568 /// <summary>
3570 /// Set the color of prim faces 3569 /// Set the color & alpha of prim faces
3571 /// </summary> 3570 /// </summary>
3572 /// <param name="color"></param>
3573 /// <param name="face"></param> 3571 /// <param name="face"></param>
3574 public void SetFaceColor(Vector3 color, int face) 3572 /// <param name="color"></param>
3573 /// <param name="alpha"></param>
3574 public void SetFaceColorAlpha(int face, Vector3 color, double ?alpha)
3575 { 3575 {
3576 Vector3 clippedColor = Util.Clip(color, 0.0f, 1.0f);
3577 float clippedAlpha = alpha.HasValue ?
3578 Util.Clip((float)alpha.Value, 0.0f, 1.0f) : 0;
3579
3576 // The only way to get a deep copy/ If we don't do this, we can 3580 // The only way to get a deep copy/ If we don't do this, we can
3577 // mever detect color changes further down. 3581 // never detect color changes further down.
3578 Byte[] buf = Shape.Textures.GetBytes(); 3582 Byte[] buf = Shape.Textures.GetBytes();
3579 Primitive.TextureEntry tex = new Primitive.TextureEntry(buf, 0, buf.Length); 3583 Primitive.TextureEntry tex = new Primitive.TextureEntry(buf, 0, buf.Length);
3580 Color4 texcolor; 3584 Color4 texcolor;
3581 if (face >= 0 && face < GetNumberOfSides()) 3585 if (face >= 0 && face < GetNumberOfSides())
3582 { 3586 {
3583 texcolor = tex.CreateFace((uint)face).RGBA; 3587 texcolor = tex.CreateFace((uint)face).RGBA;
3584 texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f); 3588 texcolor.R = clippedColor.X;
3585 texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f); 3589 texcolor.G = clippedColor.Y;
3586 texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f); 3590 texcolor.B = clippedColor.Z;
3591 if (alpha.HasValue)
3592 {
3593 texcolor.A = clippedAlpha;
3594 }
3587 tex.FaceTextures[face].RGBA = texcolor; 3595 tex.FaceTextures[face].RGBA = texcolor;
3588 UpdateTextureEntry(tex.GetBytes()); 3596 UpdateTextureEntry(tex.GetBytes());
3589 return; 3597 return;
@@ -3595,15 +3603,23 @@ namespace OpenSim.Region.Framework.Scenes
3595 if (tex.FaceTextures[i] != null) 3603 if (tex.FaceTextures[i] != null)
3596 { 3604 {
3597 texcolor = tex.FaceTextures[i].RGBA; 3605 texcolor = tex.FaceTextures[i].RGBA;
3598 texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f); 3606 texcolor.R = clippedColor.X;
3599 texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f); 3607 texcolor.G = clippedColor.Y;
3600 texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f); 3608 texcolor.B = clippedColor.Z;
3609 if (alpha.HasValue)
3610 {
3611 texcolor.A = clippedAlpha;
3612 }
3601 tex.FaceTextures[i].RGBA = texcolor; 3613 tex.FaceTextures[i].RGBA = texcolor;
3602 } 3614 }
3603 texcolor = tex.DefaultTexture.RGBA; 3615 texcolor = tex.DefaultTexture.RGBA;
3604 texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f); 3616 texcolor.R = clippedColor.X;
3605 texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f); 3617 texcolor.G = clippedColor.Y;
3606 texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f); 3618 texcolor.B = clippedColor.Z;
3619 if (alpha.HasValue)
3620 {
3621 texcolor.A = clippedAlpha;
3622 }
3607 tex.DefaultTexture.RGBA = texcolor; 3623 tex.DefaultTexture.RGBA = texcolor;
3608 } 3624 }
3609 UpdateTextureEntry(tex.GetBytes()); 3625 UpdateTextureEntry(tex.GetBytes());
@@ -4891,6 +4907,57 @@ namespace OpenSim.Region.Framework.Scenes
4891 ScheduleFullUpdate(); 4907 ScheduleFullUpdate();
4892 } 4908 }
4893 4909
4910 public void UpdateSlice(float begin, float end)
4911 {
4912 if (end < begin)
4913 {
4914 float temp = begin;
4915 begin = end;
4916 end = temp;
4917 }
4918 end = Math.Min(1f, Math.Max(0f, end));
4919 begin = Math.Min(Math.Min(1f, Math.Max(0f, begin)), end - 0.02f);
4920 if (begin < 0.02f && end < 0.02f)
4921 {
4922 begin = 0f;
4923 end = 0.02f;
4924 }
4925
4926 ushort uBegin = (ushort)(50000.0 * begin);
4927 ushort uEnd = (ushort)(50000.0 * (1f - end));
4928 bool updatePossiblyNeeded = false;
4929 PrimType primType = GetPrimType();
4930 if (primType == PrimType.SPHERE || primType == PrimType.TORUS || primType == PrimType.TUBE || primType == PrimType.RING)
4931 {
4932 if (m_shape.ProfileBegin != uBegin || m_shape.ProfileEnd != uEnd)
4933 {
4934 m_shape.ProfileBegin = uBegin;
4935 m_shape.ProfileEnd = uEnd;
4936 updatePossiblyNeeded = true;
4937 }
4938 }
4939 else if (m_shape.PathBegin != uBegin || m_shape.PathEnd != uEnd)
4940 {
4941 m_shape.PathBegin = uBegin;
4942 m_shape.PathEnd = uEnd;
4943 updatePossiblyNeeded = true;
4944 }
4945
4946 if (updatePossiblyNeeded && ParentGroup != null)
4947 {
4948 ParentGroup.HasGroupChanged = true;
4949 }
4950 if (updatePossiblyNeeded && PhysActor != null)
4951 {
4952 PhysActor.Shape = m_shape;
4953 ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(PhysActor);
4954 }
4955 if (updatePossiblyNeeded)
4956 {
4957 ScheduleFullUpdate();
4958 }
4959 }
4960
4894 /// <summary> 4961 /// <summary>
4895 /// If the part is a sculpt/mesh, retrieve the mesh data and reinsert it into the shape so that the physics 4962 /// If the part is a sculpt/mesh, retrieve the mesh data and reinsert it into the shape so that the physics
4896 /// engine can use it. 4963 /// engine can use it.
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index a8aa551..adb3d38 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -974,7 +974,9 @@ namespace OpenSim.Region.Framework.Scenes
974 { 974 {
975 if (wasChild && HasAttachments()) 975 if (wasChild && HasAttachments())
976 { 976 {
977 m_log.DebugFormat("[SCENE PRESENCE]: Restarting scripts in attachments..."); 977 m_log.DebugFormat(
978 "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
979
978 // Resume scripts 980 // Resume scripts
979 Util.FireAndForget(delegate(object x) { 981 Util.FireAndForget(delegate(object x) {
980 foreach (SceneObjectGroup sog in m_attachments) 982 foreach (SceneObjectGroup sog in m_attachments)
@@ -1530,17 +1532,22 @@ namespace OpenSim.Region.Framework.Scenes
1530 bool DCFlagKeyPressed = false; 1532 bool DCFlagKeyPressed = false;
1531 Vector3 agent_control_v3 = Vector3.Zero; 1533 Vector3 agent_control_v3 = Vector3.Zero;
1532 1534
1533 bool oldflying = Flying; 1535 bool newFlying = actor.Flying;
1534 1536
1535 if (ForceFly) 1537 if (ForceFly)
1536 actor.Flying = true; 1538 newFlying = true;
1537 else if (FlyDisabled) 1539 else if (FlyDisabled)
1538 actor.Flying = false; 1540 newFlying = false;
1539 else 1541 else
1540 actor.Flying = ((flags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); 1542 newFlying = ((flags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
1541 1543
1542 if (actor.Flying != oldflying) 1544 if (actor.Flying != newFlying)
1545 {
1546 // Note: ScenePresence.Flying is actually fetched from the physical actor
1547 // so setting PhysActor.Flying here also sets the ScenePresence's value.
1548 actor.Flying = newFlying;
1543 update_movementflag = true; 1549 update_movementflag = true;
1550 }
1544 1551
1545 if (ParentID == 0) 1552 if (ParentID == 0)
1546 { 1553 {
@@ -3627,13 +3634,16 @@ namespace OpenSim.Region.Framework.Scenes
3627 public List<SceneObjectGroup> GetAttachments(uint attachmentPoint) 3634 public List<SceneObjectGroup> GetAttachments(uint attachmentPoint)
3628 { 3635 {
3629 List<SceneObjectGroup> attachments = new List<SceneObjectGroup>(); 3636 List<SceneObjectGroup> attachments = new List<SceneObjectGroup>();
3630 3637
3631 lock (m_attachments) 3638 if (attachmentPoint >= 0)
3632 { 3639 {
3633 foreach (SceneObjectGroup so in m_attachments) 3640 lock (m_attachments)
3634 { 3641 {
3635 if (attachmentPoint == so.AttachmentPoint) 3642 foreach (SceneObjectGroup so in m_attachments)
3636 attachments.Add(so); 3643 {
3644 if (attachmentPoint == so.AttachmentPoint)
3645 attachments.Add(so);
3646 }
3637 } 3647 }
3638 } 3648 }
3639 3649
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
index 5758869..5faf131 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
@@ -141,7 +141,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
141 TestScene scene = new SceneHelpers().SetupScene(); 141 TestScene scene = new SceneHelpers().SetupScene();
142 ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); 142 ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1));
143 143
144 scene.IncomingCloseAgent(sp.UUID); 144 scene.IncomingCloseAgent(sp.UUID, false);
145 145
146 Assert.That(scene.GetScenePresence(sp.UUID), Is.Null); 146 Assert.That(scene.GetScenePresence(sp.UUID), Is.Null);
147 Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(sp.UUID), Is.Null); 147 Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(sp.UUID), Is.Null);
diff --git a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
index 44d2d45..9457ebb 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs
@@ -50,9 +50,41 @@ using OpenSim.Tests.Common.Mock;
50namespace OpenSim.Region.Framework.Tests 50namespace OpenSim.Region.Framework.Tests
51{ 51{
52 [TestFixture] 52 [TestFixture]
53 public class UserInventoryTests 53 public class UserInventoryTests : OpenSimTestCase
54 { 54 {
55 [Test] 55 [Test]
56 public void TestCreateInventoryFolders()
57 {
58 TestHelpers.InMethod();
59// TestHelpers.EnableLogging();
60
61 // For this test both folders will have the same name which is legal in SL user inventories.
62 string foldersName = "f1";
63
64 Scene scene = new SceneHelpers().SetupScene();
65 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1001));
66
67 UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, foldersName);
68
69 List<InventoryFolderBase> oneFolder
70 = UserInventoryHelpers.GetInventoryFolders(scene.InventoryService, user1.PrincipalID, foldersName);
71
72 Assert.That(oneFolder.Count, Is.EqualTo(1));
73 InventoryFolderBase firstRetrievedFolder = oneFolder[0];
74 Assert.That(firstRetrievedFolder.Name, Is.EqualTo(foldersName));
75
76 UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, foldersName);
77
78 List<InventoryFolderBase> twoFolders
79 = UserInventoryHelpers.GetInventoryFolders(scene.InventoryService, user1.PrincipalID, foldersName);
80
81 Assert.That(twoFolders.Count, Is.EqualTo(2));
82 Assert.That(twoFolders[0].Name, Is.EqualTo(foldersName));
83 Assert.That(twoFolders[1].Name, Is.EqualTo(foldersName));
84 Assert.That(twoFolders[0].ID, Is.Not.EqualTo(twoFolders[1].ID));
85 }
86
87 [Test]
56 public void TestGiveInventoryItem() 88 public void TestGiveInventoryItem()
57 { 89 {
58 TestHelpers.InMethod(); 90 TestHelpers.InMethod();
@@ -83,7 +115,7 @@ namespace OpenSim.Region.Framework.Tests
83 public void TestGiveInventoryFolder() 115 public void TestGiveInventoryFolder()
84 { 116 {
85 TestHelpers.InMethod(); 117 TestHelpers.InMethod();
86// log4net.Config.XmlConfigurator.Configure(); 118// TestHelpers.EnableLogging();
87 119
88 Scene scene = new SceneHelpers().SetupScene(); 120 Scene scene = new SceneHelpers().SetupScene();
89 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1001)); 121 UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1001));
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
index 3b83e58..1660c45 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
@@ -890,10 +890,10 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
890 890
891 public void Close() 891 public void Close()
892 { 892 {
893 Close(true); 893 Close(true, false);
894 } 894 }
895 895
896 public void Close(bool sendStop) 896 public void Close(bool sendStop, bool force)
897 { 897 {
898 Disconnect(); 898 Disconnect();
899 } 899 }
diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
index 7b20446..f292a75 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
@@ -447,7 +447,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
447 // settings allow voice, then whether parcel allows 447 // settings allow voice, then whether parcel allows
448 // voice, if all do retrieve or obtain the parcel 448 // voice, if all do retrieve or obtain the parcel
449 // voice channel 449 // voice channel
450 LandData land = scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); 450 LandData land = scene.GetLandData(avatar.AbsolutePosition);
451 451
452 //m_log.DebugFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": request: {4}, path: {5}, param: {6}", 452 //m_log.DebugFormat("[FreeSwitchVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": request: {4}, path: {5}, param: {6}",
453 // scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, request, path, param); 453 // scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, request, path, param);
diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs
index a30a38d..8a8a31c 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs
@@ -623,7 +623,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
623 // settings allow voice, then whether parcel allows 623 // settings allow voice, then whether parcel allows
624 // voice, if all do retrieve or obtain the parcel 624 // voice, if all do retrieve or obtain the parcel
625 // voice channel 625 // voice channel
626 LandData land = scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); 626 LandData land = scene.GetLandData(avatar.AbsolutePosition);
627 627
628// m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": request: {4}, path: {5}, param: {6}", 628// m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": request: {4}, path: {5}, param: {6}",
629// scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, request, path, param); 629// scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, request, path, param);
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs
index 311531c..732c28f 100644
--- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreModule.cs
@@ -175,14 +175,15 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
175 /// 175 ///
176 /// </summary> 176 /// </summary>
177 // ----------------------------------------------------------------- 177 // -----------------------------------------------------------------
178 public bool CreateStore(string value, out UUID result) 178 public bool CreateStore(string value, ref UUID result)
179 { 179 {
180 result = UUID.Zero; 180 if (result == UUID.Zero)
181 result = UUID.Random();
182
183 JsonStore map = null;
181 184
182 if (! m_enabled) return false; 185 if (! m_enabled) return false;
183 186
184 UUID uuid = UUID.Random();
185 JsonStore map = null;
186 187
187 try 188 try
188 { 189 {
@@ -195,9 +196,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
195 } 196 }
196 197
197 lock (m_JsonValueStore) 198 lock (m_JsonValueStore)
198 m_JsonValueStore.Add(uuid,map); 199 m_JsonValueStore.Add(result,map);
199 200
200 result = uuid;
201 return true; 201 return true;
202 } 202 }
203 203
@@ -231,7 +231,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
231 if (! m_JsonValueStore.TryGetValue(storeID,out map)) 231 if (! m_JsonValueStore.TryGetValue(storeID,out map))
232 { 232 {
233 m_log.InfoFormat("[JsonStore] Missing store {0}",storeID); 233 m_log.InfoFormat("[JsonStore] Missing store {0}",storeID);
234 return true; 234 return false;
235 } 235 }
236 } 236 }
237 237
diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
index eaba816..6910d14 100644
--- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs
@@ -227,7 +227,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore
227 protected UUID JsonCreateStore(UUID hostID, UUID scriptID, string value) 227 protected UUID JsonCreateStore(UUID hostID, UUID scriptID, string value)
228 { 228 {
229 UUID uuid = UUID.Zero; 229 UUID uuid = UUID.Zero;
230 if (! m_store.CreateStore(value, out uuid)) 230 if (! m_store.CreateStore(value, ref uuid))
231 GenerateRuntimeError("Failed to create Json store"); 231 GenerateRuntimeError("Failed to create Json store");
232 232
233 return uuid; 233 return uuid;
diff --git a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs
index fff3a32..bad75f7 100644
--- a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs
@@ -181,7 +181,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
181 } 181 }
182 } 182 }
183 183
184 void OnOarFileLoaded(Guid requestId, string message) 184 void OnOarFileLoaded(Guid requestId, List<UUID> loadedScenes, string message)
185 { 185 {
186 m_oarFileLoading = true; 186 m_oarFileLoading = true;
187 187
diff --git a/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs b/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
index 705a847..23cc633 100644
--- a/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
@@ -130,13 +130,25 @@ namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms
130 m_scriptModule.PostScriptEvent(script, "link_message", args); 130 m_scriptModule.PostScriptEvent(script, "link_message", args);
131 } 131 }
132 132
133 private static MethodInfo GetMethodInfoFromType(Type target, string meth, bool searchInstanceMethods)
134 {
135 BindingFlags getMethodFlags =
136 BindingFlags.NonPublic | BindingFlags.Public;
137
138 if (searchInstanceMethods)
139 getMethodFlags |= BindingFlags.Instance;
140 else
141 getMethodFlags |= BindingFlags.Static;
142
143 return target.GetMethod(meth, getMethodFlags);
144 }
145
133 public void RegisterScriptInvocation(object target, string meth) 146 public void RegisterScriptInvocation(object target, string meth)
134 { 147 {
135 MethodInfo mi = target.GetType().GetMethod(meth, 148 MethodInfo mi = GetMethodInfoFromType(target.GetType(), meth, true);
136 BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
137 if (mi == null) 149 if (mi == null)
138 { 150 {
139 m_log.WarnFormat("[MODULE COMMANDS] Failed to register method {0}",meth); 151 m_log.WarnFormat("[MODULE COMMANDS] Failed to register method {0}", meth);
140 return; 152 return;
141 } 153 }
142 154
@@ -151,38 +163,54 @@ namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms
151 163
152 public void RegisterScriptInvocation(object target, MethodInfo mi) 164 public void RegisterScriptInvocation(object target, MethodInfo mi)
153 { 165 {
154 m_log.DebugFormat("[MODULE COMMANDS] Register method {0} from type {1}", mi.Name, target.GetType().Name); 166 m_log.DebugFormat("[MODULE COMMANDS] Register method {0} from type {1}", mi.Name, (target is Type) ? ((Type)target).Name : target.GetType().Name);
155 167
156 Type delegateType; 168 Type delegateType;
157 var typeArgs = mi.GetParameters() 169 List<Type> typeArgs = mi.GetParameters()
158 .Select(p => p.ParameterType) 170 .Select(p => p.ParameterType)
159 .ToList(); 171 .ToList();
160 172
161 if (mi.ReturnType == typeof(void)) 173 if (mi.ReturnType == typeof(void))
162 { 174 {
163 delegateType = Expression.GetActionType(typeArgs.ToArray()); 175 delegateType = Expression.GetActionType(typeArgs.ToArray());
164 } 176 }
165 else 177 else
166 { 178 {
167 typeArgs.Add(mi.ReturnType); 179 typeArgs.Add(mi.ReturnType);
168 delegateType = Expression.GetFuncType(typeArgs.ToArray()); 180 delegateType = Expression.GetFuncType(typeArgs.ToArray());
169 } 181 }
170 182
171 Delegate fcall = Delegate.CreateDelegate(delegateType, target, mi); 183 Delegate fcall;
184 if (!(target is Type))
185 fcall = Delegate.CreateDelegate(delegateType, target, mi);
186 else
187 fcall = Delegate.CreateDelegate(delegateType, (Type)target, mi.Name);
172 188
173 lock (m_scriptInvocation) 189 lock (m_scriptInvocation)
174 { 190 {
175 ParameterInfo[] parameters = fcall.Method.GetParameters (); 191 ParameterInfo[] parameters = fcall.Method.GetParameters();
176 if (parameters.Length < 2) // Must have two UUID params 192 if (parameters.Length < 2) // Must have two UUID params
177 return; 193 return;
178 194
179 // Hide the first two parameters 195 // Hide the first two parameters
180 Type[] parmTypes = new Type[parameters.Length - 2]; 196 Type[] parmTypes = new Type[parameters.Length - 2];
181 for (int i = 2 ; i < parameters.Length ; i++) 197 for (int i = 2; i < parameters.Length; i++)
182 parmTypes[i - 2] = parameters[i].ParameterType; 198 parmTypes[i - 2] = parameters[i].ParameterType;
183 m_scriptInvocation[fcall.Method.Name] = new ScriptInvocationData(fcall.Method.Name, fcall, parmTypes, fcall.Method.ReturnType); 199 m_scriptInvocation[fcall.Method.Name] = new ScriptInvocationData(fcall.Method.Name, fcall, parmTypes, fcall.Method.ReturnType);
184 } 200 }
185 } 201 }
202
203 public void RegisterScriptInvocation(Type target, string[] methods)
204 {
205 foreach (string method in methods)
206 {
207 MethodInfo mi = GetMethodInfoFromType(target, method, false);
208 if (mi == null)
209 m_log.WarnFormat("[MODULE COMMANDS] Failed to register method {0}", method);
210 else
211 RegisterScriptInvocation(target, mi);
212 }
213 }
186 214
187 public Delegate[] GetScriptInvocationList() 215 public Delegate[] GetScriptInvocationList()
188 { 216 {
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
index d00a6c0..625342e 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
@@ -905,11 +905,13 @@ namespace OpenSim.Region.OptionalModules.World.NPC
905 905
906 public void Close() 906 public void Close()
907 { 907 {
908 Close(true); 908 Close(true, false);
909 } 909 }
910 910
911 public void Close(bool sendStop) 911 public void Close(bool sendStop, bool force)
912 { 912 {
913 // Remove ourselves from the scene
914 m_scene.RemoveClient(AgentId, false);
913 } 915 }
914 916
915 public void Start() 917 public void Start()
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index e2f7af9..526dbad 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -34,13 +34,12 @@ using OpenSim.Region.Physics.Manager;
34 34
35namespace OpenSim.Region.Physics.BulletSPlugin 35namespace OpenSim.Region.Physics.BulletSPlugin
36{ 36{
37public class BSCharacter : PhysicsActor 37public class BSCharacter : BSPhysObject
38{ 38{
39 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 39 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
40 private static readonly string LogHeader = "[BULLETS CHAR]"; 40 private static readonly string LogHeader = "[BULLETS CHAR]";
41 41
42 private BSScene _scene; 42 public BSScene Scene { get; private set; }
43 public BSScene Scene { get { return _scene; } }
44 private String _avName; 43 private String _avName;
45 // private bool _stopped; 44 // private bool _stopped;
46 private Vector3 _size; 45 private Vector3 _size;
@@ -74,11 +73,9 @@ public class BSCharacter : PhysicsActor
74 private bool _kinematic; 73 private bool _kinematic;
75 private float _buoyancy; 74 private float _buoyancy;
76 75
77 private BulletBody m_body; 76 public override BulletBody BSBody { get; set; }
78 public BulletBody Body { 77 public override BulletShape BSShape { get; set; }
79 get { return m_body; } 78 public override BSLinkset Linkset { get; set; }
80 set { m_body = value; }
81 }
82 79
83 private int _subscribedEventsMs = 0; 80 private int _subscribedEventsMs = 0;
84 private int _nextCollisionOkTime = 0; 81 private int _nextCollisionOkTime = 0;
@@ -95,7 +92,8 @@ public class BSCharacter : PhysicsActor
95 { 92 {
96 _localID = localID; 93 _localID = localID;
97 _avName = avName; 94 _avName = avName;
98 _scene = parent_scene; 95 Scene = parent_scene;
96 _physicsActorType = (int)ActorTypes.Agent;
99 _position = pos; 97 _position = pos;
100 _size = size; 98 _size = size;
101 _flying = isFlying; 99 _flying = isFlying;
@@ -104,10 +102,12 @@ public class BSCharacter : PhysicsActor
104 _buoyancy = ComputeBuoyancyFromFlying(isFlying); 102 _buoyancy = ComputeBuoyancyFromFlying(isFlying);
105 // The dimensions of the avatar capsule are kept in the scale. 103 // The dimensions of the avatar capsule are kept in the scale.
106 // Physics creates a unit capsule which is scaled by the physics engine. 104 // Physics creates a unit capsule which is scaled by the physics engine.
107 _scale = new Vector3(_scene.Params.avatarCapsuleRadius, _scene.Params.avatarCapsuleRadius, size.Z); 105 _scale = new Vector3(Scene.Params.avatarCapsuleRadius, Scene.Params.avatarCapsuleRadius, size.Z);
108 _density = _scene.Params.avatarDensity; 106 _density = Scene.Params.avatarDensity;
109 ComputeAvatarVolumeAndMass(); // set _avatarVolume and _mass based on capsule size, _density and _scale 107 ComputeAvatarVolumeAndMass(); // set _avatarVolume and _mass based on capsule size, _density and _scale
110 108
109 Linkset = new BSLinkset(Scene, this);
110
111 ShapeData shapeData = new ShapeData(); 111 ShapeData shapeData = new ShapeData();
112 shapeData.ID = _localID; 112 shapeData.ID = _localID;
113 shapeData.Type = ShapeData.PhysicsShapeType.SHAPE_AVATAR; 113 shapeData.Type = ShapeData.PhysicsShapeType.SHAPE_AVATAR;
@@ -118,29 +118,31 @@ public class BSCharacter : PhysicsActor
118 shapeData.Mass = _mass; 118 shapeData.Mass = _mass;
119 shapeData.Buoyancy = _buoyancy; 119 shapeData.Buoyancy = _buoyancy;
120 shapeData.Static = ShapeData.numericFalse; 120 shapeData.Static = ShapeData.numericFalse;
121 shapeData.Friction = _scene.Params.avatarFriction; 121 shapeData.Friction = Scene.Params.avatarFriction;
122 shapeData.Restitution = _scene.Params.avatarRestitution; 122 shapeData.Restitution = Scene.Params.avatarRestitution;
123 123
124 // do actual create at taint time 124 // do actual create at taint time
125 _scene.TaintedObject("BSCharacter.create", delegate() 125 Scene.TaintedObject("BSCharacter.create", delegate()
126 { 126 {
127 BulletSimAPI.CreateObject(parent_scene.WorldID, shapeData); 127 DetailLog("{0},BSCharacter.create", _localID);
128 BulletSimAPI.CreateObject(Scene.WorldID, shapeData);
128 129
129 m_body = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID)); 130 // Set the buoyancy for flying. This will be refactored when all the settings happen in C#
130 // avatars get all collisions no matter what 131 BulletSimAPI.SetObjectBuoyancy(Scene.WorldID, LocalID, _buoyancy);
131 BulletSimAPI.AddToCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); 132
133 BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(Scene.World.Ptr, LocalID));
132 }); 134 });
133 135
134 return; 136 return;
135 } 137 }
136 138
137 // called when this character is being destroyed and the resources should be released 139 // called when this character is being destroyed and the resources should be released
138 public void Destroy() 140 public override void Destroy()
139 { 141 {
140 // DetailLog("{0},BSCharacter.Destroy", LocalID); 142 DetailLog("{0},BSCharacter.Destroy", LocalID);
141 _scene.TaintedObject("BSCharacter.destroy", delegate() 143 Scene.TaintedObject("BSCharacter.destroy", delegate()
142 { 144 {
143 BulletSimAPI.DestroyObject(_scene.WorldID, _localID); 145 BulletSimAPI.DestroyObject(Scene.WorldID, _localID);
144 }); 146 });
145 } 147 }
146 148
@@ -169,9 +171,9 @@ public class BSCharacter : PhysicsActor
169 171
170 ComputeAvatarVolumeAndMass(); 172 ComputeAvatarVolumeAndMass();
171 173
172 _scene.TaintedObject("BSCharacter.setSize", delegate() 174 Scene.TaintedObject("BSCharacter.setSize", delegate()
173 { 175 {
174 BulletSimAPI.SetObjectScaleMass(_scene.WorldID, LocalID, _scale, _mass, true); 176 BulletSimAPI.SetObjectScaleMass(Scene.WorldID, LocalID, _scale, _mass, true);
175 }); 177 });
176 178
177 } 179 }
@@ -200,17 +202,17 @@ public class BSCharacter : PhysicsActor
200 202
201 public override Vector3 Position { 203 public override Vector3 Position {
202 get { 204 get {
203 // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); 205 // _position = BulletSimAPI.GetObjectPosition(Scene.WorldID, _localID);
204 return _position; 206 return _position;
205 } 207 }
206 set { 208 set {
207 _position = value; 209 _position = value;
208 PositionSanityCheck(); 210 PositionSanityCheck();
209 211
210 _scene.TaintedObject("BSCharacter.setPosition", delegate() 212 Scene.TaintedObject("BSCharacter.setPosition", delegate()
211 { 213 {
212 DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); 214 DetailLog("{0},BSCharacter.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
213 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); 215 BulletSimAPI.SetObjectTranslation(Scene.WorldID, _localID, _position, _orientation);
214 }); 216 });
215 } 217 }
216 } 218 }
@@ -223,16 +225,35 @@ public class BSCharacter : PhysicsActor
223 bool ret = false; 225 bool ret = false;
224 226
225 // If below the ground, move the avatar up 227 // If below the ground, move the avatar up
226 float terrainHeight = Scene.GetTerrainHeightAtXYZ(_position); 228 float terrainHeight = Scene.TerrainManager.GetTerrainHeightAtXYZ(_position);
227 if (_position.Z < terrainHeight) 229 if (Position.Z < terrainHeight)
228 { 230 {
229 DetailLog("{0},BSCharacter.PositionAdjustUnderGround,call,pos={1},orient={2}", LocalID, _position, _orientation); 231 DetailLog("{0},BSCharacter.PositionAdjustUnderGround,call,pos={1},terrain={2}", LocalID, _position, terrainHeight);
230 _position.Z = terrainHeight + 2.0f; 232 _position.Z = terrainHeight + 2.0f;
231 ret = true; 233 ret = true;
232 } 234 }
233 235
234 // TODO: check for out of bounds 236 // TODO: check for out of bounds
237 return ret;
238 }
235 239
240 // A version of the sanity check that also makes sure a new position value is
241 // pushed back to the physics engine. This routine would be used by anyone
242 // who is not already pushing the value.
243 private bool PositionSanityCheck2()
244 {
245 bool ret = false;
246 if (PositionSanityCheck())
247 {
248 // The new position value must be pushed into the physics engine but we can't
249 // just assign to "Position" because of potential call loops.
250 Scene.TaintedObject("BSCharacter.PositionSanityCheck", delegate()
251 {
252 DetailLog("{0},BSCharacter.PositionSanityCheck,taint,pos={1},orient={2}", LocalID, _position, _orientation);
253 BulletSimAPI.SetObjectTranslation(Scene.WorldID, _localID, _position, _orientation);
254 });
255 ret = true;
256 }
236 return ret; 257 return ret;
237 } 258 }
238 259
@@ -241,6 +262,10 @@ public class BSCharacter : PhysicsActor
241 return _mass; 262 return _mass;
242 } 263 }
243 } 264 }
265
266 // used when we only want this prim's mass and not the linkset thing
267 public override float MassRaw { get {return _mass; } }
268
244 public override Vector3 Force { 269 public override Vector3 Force {
245 get { return _force; } 270 get { return _force; }
246 set { 271 set {
@@ -273,10 +298,10 @@ public class BSCharacter : PhysicsActor
273 set { 298 set {
274 _velocity = value; 299 _velocity = value;
275 // m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, _velocity); 300 // m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, _velocity);
276 _scene.TaintedObject("BSCharacter.setVelocity", delegate() 301 Scene.TaintedObject("BSCharacter.setVelocity", delegate()
277 { 302 {
278 DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, _velocity); 303 DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, _velocity);
279 BulletSimAPI.SetObjectVelocity(_scene.WorldID, _localID, _velocity); 304 BulletSimAPI.SetObjectVelocity(Scene.WorldID, _localID, _velocity);
280 }); 305 });
281 } 306 }
282 } 307 }
@@ -299,10 +324,10 @@ public class BSCharacter : PhysicsActor
299 set { 324 set {
300 _orientation = value; 325 _orientation = value;
301 // m_log.DebugFormat("{0}: set orientation to {1}", LogHeader, _orientation); 326 // m_log.DebugFormat("{0}: set orientation to {1}", LogHeader, _orientation);
302 _scene.TaintedObject("BSCharacter.setOrientation", delegate() 327 Scene.TaintedObject("BSCharacter.setOrientation", delegate()
303 { 328 {
304 // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); 329 // _position = BulletSimAPI.GetObjectPosition(Scene.WorldID, _localID);
305 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); 330 BulletSimAPI.SetObjectTranslation(Scene.WorldID, _localID, _position, _orientation);
306 }); 331 });
307 } 332 }
308 } 333 }
@@ -319,14 +344,13 @@ public class BSCharacter : PhysicsActor
319 public override bool Flying { 344 public override bool Flying {
320 get { return _flying; } 345 get { return _flying; }
321 set { 346 set {
322 if (_flying != value) 347 _flying = value;
323 { 348 // simulate flying by changing the effect of gravity
324 _flying = value; 349 this.Buoyancy = ComputeBuoyancyFromFlying(_flying);
325 // simulate flying by changing the effect of gravity
326 this.Buoyancy = ComputeBuoyancyFromFlying(_flying);
327 }
328 } 350 }
329 } 351 }
352 // Flying is implimented by changing the avatar's buoyancy.
353 // Would this be done better with a vehicle type?
330 private float ComputeBuoyancyFromFlying(bool ifFlying) { 354 private float ComputeBuoyancyFromFlying(bool ifFlying) {
331 return ifFlying ? 1f : 0f; 355 return ifFlying ? 1f : 0f;
332 } 356 }
@@ -340,11 +364,11 @@ public class BSCharacter : PhysicsActor
340 set { _throttleUpdates = value; } 364 set { _throttleUpdates = value; }
341 } 365 }
342 public override bool IsColliding { 366 public override bool IsColliding {
343 get { return (_collidingStep == _scene.SimulationStep); } 367 get { return (_collidingStep == Scene.SimulationStep); }
344 set { _isColliding = value; } 368 set { _isColliding = value; }
345 } 369 }
346 public override bool CollidingGround { 370 public override bool CollidingGround {
347 get { return (_collidingGroundStep == _scene.SimulationStep); } 371 get { return (_collidingGroundStep == Scene.SimulationStep); }
348 set { _collidingGround = value; } 372 set { _collidingGround = value; }
349 } 373 }
350 public override bool CollidingObj { 374 public override bool CollidingObj {
@@ -366,10 +390,10 @@ public class BSCharacter : PhysicsActor
366 public override float Buoyancy { 390 public override float Buoyancy {
367 get { return _buoyancy; } 391 get { return _buoyancy; }
368 set { _buoyancy = value; 392 set { _buoyancy = value;
369 _scene.TaintedObject("BSCharacter.setBuoyancy", delegate() 393 Scene.TaintedObject("BSCharacter.setBuoyancy", delegate()
370 { 394 {
371 DetailLog("{0},BSCharacter.setBuoyancy,taint,buoy={1}", LocalID, _buoyancy); 395 DetailLog("{0},BSCharacter.setBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
372 BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, LocalID, _buoyancy); 396 BulletSimAPI.SetObjectBuoyancy(Scene.WorldID, LocalID, _buoyancy);
373 }); 397 });
374 } 398 }
375 } 399 }
@@ -413,10 +437,10 @@ public class BSCharacter : PhysicsActor
413 _force.Y += force.Y; 437 _force.Y += force.Y;
414 _force.Z += force.Z; 438 _force.Z += force.Z;
415 // m_log.DebugFormat("{0}: AddForce. adding={1}, newForce={2}", LogHeader, force, _force); 439 // m_log.DebugFormat("{0}: AddForce. adding={1}, newForce={2}", LogHeader, force, _force);
416 _scene.TaintedObject("BSCharacter.AddForce", delegate() 440 Scene.TaintedObject("BSCharacter.AddForce", delegate()
417 { 441 {
418 DetailLog("{0},BSCharacter.setAddForce,taint,addedForce={1}", LocalID, _force); 442 DetailLog("{0},BSCharacter.setAddForce,taint,addedForce={1}", LocalID, _force);
419 BulletSimAPI.AddObjectForce2(Body.Ptr, _force); 443 BulletSimAPI.SetObjectForce2(BSBody.Ptr, _force);
420 }); 444 });
421 } 445 }
422 else 446 else
@@ -441,18 +465,23 @@ public class BSCharacter : PhysicsActor
441 465
442 Scene.TaintedObject("BSCharacter.SubscribeEvents", delegate() 466 Scene.TaintedObject("BSCharacter.SubscribeEvents", delegate()
443 { 467 {
444 BulletSimAPI.AddToCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); 468 BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
445 }); 469 });
446 } 470 }
447 } 471 }
472
473 public override void ZeroMotion()
474 {
475 return;
476 }
477
448 // Stop collision events 478 // Stop collision events
449 public override void UnSubscribeEvents() { 479 public override void UnSubscribeEvents() {
450 _subscribedEventsMs = 0; 480 _subscribedEventsMs = 0;
451 // Avatars get all their collision events 481 Scene.TaintedObject("BSCharacter.UnSubscribeEvents", delegate()
452 // Scene.TaintedObject("BSCharacter.UnSubscribeEvents", delegate() 482 {
453 // { 483 BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
454 // BulletSimAPI.RemoveFromCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); 484 });
455 // });
456 } 485 }
457 // Return 'true' if someone has subscribed to events 486 // Return 'true' if someone has subscribed to events
458 public override bool SubscribedEvents() { 487 public override bool SubscribedEvents() {
@@ -478,7 +507,7 @@ public class BSCharacter : PhysicsActor
478 507
479 // The physics engine says that properties have updated. Update same and inform 508 // The physics engine says that properties have updated. Update same and inform
480 // the world that things have changed. 509 // the world that things have changed.
481 public void UpdateProperties(EntityProperties entprop) 510 public override void UpdateProperties(EntityProperties entprop)
482 { 511 {
483 _position = entprop.Position; 512 _position = entprop.Position;
484 _orientation = entprop.Rotation; 513 _orientation = entprop.Rotation;
@@ -488,43 +517,46 @@ public class BSCharacter : PhysicsActor
488 // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop. 517 // Avatars don't report their changes the usual way. Changes are checked for in the heartbeat loop.
489 // base.RequestPhysicsterseUpdate(); 518 // base.RequestPhysicsterseUpdate();
490 519
491 /* 520 // Do some sanity checking for the avatar. Make sure it's above ground and inbounds.
492 DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", 521 PositionSanityCheck2();
493 LocalID, entprop.Position, entprop.Rotation, entprop.Velocity, 522
494 entprop.Acceleration, entprop.RotationalVelocity); 523 float heightHere = Scene.TerrainManager.GetTerrainHeightAtXYZ(_position); // only for debug
495 */ 524 DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5},terrain={6}",
525 LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity, heightHere);
496 } 526 }
497 527
498 // Called by the scene when a collision with this object is reported 528 // Called by the scene when a collision with this object is reported
499 // The collision, if it should be reported to the character, is placed in a collection 529 // The collision, if it should be reported to the character, is placed in a collection
500 // that will later be sent to the simulator when SendCollisions() is called. 530 // that will later be sent to the simulator when SendCollisions() is called.
501 CollisionEventUpdate collisionCollection = null; 531 CollisionEventUpdate collisionCollection = null;
502 public void Collide(uint collidingWith, ActorTypes type, Vector3 contactPoint, Vector3 contactNormal, float pentrationDepth) 532 public override bool Collide(uint collidingWith, BSPhysObject collidee, Vector3 contactPoint, Vector3 contactNormal, float pentrationDepth)
503 { 533 {
504 // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith); 534 bool ret = false;
505 535
506 // The following makes IsColliding() and IsCollidingGround() work 536 // The following makes IsColliding() and IsCollidingGround() work
507 _collidingStep = _scene.SimulationStep; 537 _collidingStep = Scene.SimulationStep;
508 if (collidingWith == BSScene.TERRAIN_ID || collidingWith == BSScene.GROUNDPLANE_ID) 538 if (collidingWith <= Scene.TerrainManager.HighestTerrainID)
509 { 539 {
510 _collidingGroundStep = _scene.SimulationStep; 540 _collidingGroundStep = Scene.SimulationStep;
511 } 541 }
512 // DetailLog("{0},BSCharacter.Collison,call,with={1}", LocalID, collidingWith); 542 // DetailLog("{0},BSCharacter.Collison,call,with={1}", LocalID, collidingWith);
513 543
514 // throttle collisions to the rate specified in the subscription 544 // throttle collisions to the rate specified in the subscription
515 if (_subscribedEventsMs != 0) { 545 if (SubscribedEvents()) {
516 int nowTime = _scene.SimulationNowTime; 546 int nowTime = Scene.SimulationNowTime;
517 if (nowTime >= _nextCollisionOkTime) { 547 if (nowTime >= _nextCollisionOkTime) {
518 _nextCollisionOkTime = nowTime + _subscribedEventsMs; 548 _nextCollisionOkTime = nowTime + _subscribedEventsMs;
519 549
520 if (collisionCollection == null) 550 if (collisionCollection == null)
521 collisionCollection = new CollisionEventUpdate(); 551 collisionCollection = new CollisionEventUpdate();
522 collisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); 552 collisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
553 ret = true;
523 } 554 }
524 } 555 }
556 return ret;
525 } 557 }
526 558
527 public void SendCollisions() 559 public override void SendCollisions()
528 { 560 {
529 /* 561 /*
530 if (collisionCollection != null && collisionCollection.Count > 0) 562 if (collisionCollection != null && collisionCollection.Count > 0)
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs
index 25084d8..1376a29 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSConstraint.cs
@@ -48,11 +48,10 @@ public abstract class BSConstraint : IDisposable
48 { 48 {
49 if (m_enabled) 49 if (m_enabled)
50 { 50 {
51 // BulletSimAPI.RemoveConstraint(m_world.ID, m_body1.ID, m_body2.ID); 51 m_enabled = false;
52 bool success = BulletSimAPI.DestroyConstraint2(m_world.Ptr, m_constraint.Ptr); 52 bool success = BulletSimAPI.DestroyConstraint2(m_world.Ptr, m_constraint.Ptr);
53 m_world.scene.DetailLog("{0},BSConstraint.Dispose,taint,body1={1},body2={2},success={3}", BSScene.DetailLogZero, m_body1.ID, m_body2.ID, success); 53 m_world.scene.DetailLog("{0},BSConstraint.Dispose,taint,body1={1},body2={2},success={3}", BSScene.DetailLogZero, m_body1.ID, m_body2.ID, success);
54 m_constraint.Ptr = System.IntPtr.Zero; 54 m_constraint.Ptr = System.IntPtr.Zero;
55 m_enabled = false;
56 } 55 }
57 } 56 }
58 57
@@ -75,6 +74,17 @@ public abstract class BSConstraint : IDisposable
75 return ret; 74 return ret;
76 } 75 }
77 76
77 public virtual bool SetSolverIterations(float cnt)
78 {
79 bool ret = false;
80 if (m_enabled)
81 {
82 BulletSimAPI.SetConstraintNumSolverIterations2(m_constraint.Ptr, cnt);
83 ret = true;
84 }
85 return ret;
86 }
87
78 public virtual bool CalculateTransforms() 88 public virtual bool CalculateTransforms()
79 { 89 {
80 bool ret = false; 90 bool ret = false;
@@ -97,8 +107,9 @@ public abstract class BSConstraint : IDisposable
97 ret = CalculateTransforms(); 107 ret = CalculateTransforms();
98 if (ret) 108 if (ret)
99 { 109 {
100 // m_world.scene.PhysicsLogging.Write("{0},BSConstraint.RecomputeConstraintVariables,taint,enabling,A={1},B={2}", 110 // Setting an object's mass to zero (making it static like when it's selected)
101 // BSScene.DetailLogZero, Body1.ID, Body2.ID); 111 // automatically disables the constraints.
112 // If the link is enabled, be sure to set the constraint itself to enabled.
102 BulletSimAPI.SetConstraintEnable2(m_constraint.Ptr, m_world.scene.NumericBool(true)); 113 BulletSimAPI.SetConstraintEnable2(m_constraint.Ptr, m_world.scene.NumericBool(true));
103 } 114 }
104 else 115 else
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
index 5a9f135..61006f0 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
@@ -57,6 +57,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
57 private int frcount = 0; // Used to limit dynamics debug output to 57 private int frcount = 0; // Used to limit dynamics debug output to
58 // every 100th frame 58 // every 100th frame
59 59
60 private BSScene m_physicsScene;
60 private BSPrim m_prim; // the prim this dynamic controller belongs to 61 private BSPrim m_prim; // the prim this dynamic controller belongs to
61 62
62 // Vehicle properties 63 // Vehicle properties
@@ -74,13 +75,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
74 // HOVER_UP_ONLY 75 // HOVER_UP_ONLY
75 // LIMIT_MOTOR_UP 76 // LIMIT_MOTOR_UP
76 // LIMIT_ROLL_ONLY 77 // LIMIT_ROLL_ONLY
77 private VehicleFlag m_Hoverflags = (VehicleFlag)0;
78 private Vector3 m_BlockingEndPoint = Vector3.Zero; 78 private Vector3 m_BlockingEndPoint = Vector3.Zero;
79 private Quaternion m_RollreferenceFrame = Quaternion.Identity; 79 private Quaternion m_RollreferenceFrame = Quaternion.Identity;
80 // Linear properties 80 // Linear properties
81 private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time 81 private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time
82 private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; // velocity requested by LSL 82 private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; // velocity requested by LSL
83 private Vector3 m_dir = Vector3.Zero; // velocity applied to body 83 private Vector3 m_newVelocity = Vector3.Zero; // velocity computed to be applied to body
84 private Vector3 m_linearFrictionTimescale = Vector3.Zero; 84 private Vector3 m_linearFrictionTimescale = Vector3.Zero;
85 private float m_linearMotorDecayTimescale = 0; 85 private float m_linearMotorDecayTimescale = 0;
86 private float m_linearMotorTimescale = 0; 86 private float m_linearMotorTimescale = 0;
@@ -124,15 +124,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin
124 private float m_verticalAttractionEfficiency = 1.0f; // damped 124 private float m_verticalAttractionEfficiency = 1.0f; // damped
125 private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor. 125 private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor.
126 126
127 public BSDynamics(BSPrim myPrim) 127 public BSDynamics(BSScene myScene, BSPrim myPrim)
128 { 128 {
129 m_physicsScene = myScene;
129 m_prim = myPrim; 130 m_prim = myPrim;
130 m_type = Vehicle.TYPE_NONE; 131 m_type = Vehicle.TYPE_NONE;
131 } 132 }
132 133
133 internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue, float timestep) 134 internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
134 { 135 {
135 DetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue); 136 VDetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue);
136 switch (pParam) 137 switch (pParam)
137 { 138 {
138 case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY: 139 case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY:
@@ -229,9 +230,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin
229 } 230 }
230 }//end ProcessFloatVehicleParam 231 }//end ProcessFloatVehicleParam
231 232
232 internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue, float timestep) 233 internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue)
233 { 234 {
234 DetailLog("{0},ProcessVectorVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue); 235 VDetailLog("{0},ProcessVectorVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue);
235 switch (pParam) 236 switch (pParam)
236 { 237 {
237 case Vehicle.ANGULAR_FRICTION_TIMESCALE: 238 case Vehicle.ANGULAR_FRICTION_TIMESCALE:
@@ -266,7 +267,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
266 267
267 internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue) 268 internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue)
268 { 269 {
269 DetailLog("{0},ProcessRotationalVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue); 270 VDetailLog("{0},ProcessRotationalVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue);
270 switch (pParam) 271 switch (pParam)
271 { 272 {
272 case Vehicle.REFERENCE_FRAME: 273 case Vehicle.REFERENCE_FRAME:
@@ -280,164 +281,27 @@ namespace OpenSim.Region.Physics.BulletSPlugin
280 281
281 internal void ProcessVehicleFlags(int pParam, bool remove) 282 internal void ProcessVehicleFlags(int pParam, bool remove)
282 { 283 {
283 DetailLog("{0},ProcessVehicleFlags,param={1},remove={2}", m_prim.LocalID, pParam, remove); 284 VDetailLog("{0},ProcessVehicleFlags,param={1},remove={2}", m_prim.LocalID, pParam, remove);
285 VehicleFlag parm = (VehicleFlag)pParam;
284 if (remove) 286 if (remove)
285 { 287 {
286 if (pParam == -1) 288 if (pParam == -1)
287 { 289 {
288 m_flags = (VehicleFlag)0; 290 m_flags = (VehicleFlag)0;
289 m_Hoverflags = (VehicleFlag)0;
290 return;
291 } 291 }
292 if ((pParam & (int)VehicleFlag.HOVER_GLOBAL_HEIGHT) == (int)VehicleFlag.HOVER_GLOBAL_HEIGHT) 292 else
293 {
294 if ((m_Hoverflags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != (VehicleFlag)0)
295 m_Hoverflags &= ~(VehicleFlag.HOVER_GLOBAL_HEIGHT);
296 }
297 if ((pParam & (int)VehicleFlag.HOVER_TERRAIN_ONLY) == (int)VehicleFlag.HOVER_TERRAIN_ONLY)
298 {
299 if ((m_Hoverflags & VehicleFlag.HOVER_TERRAIN_ONLY) != (VehicleFlag)0)
300 m_Hoverflags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY);
301 }
302 if ((pParam & (int)VehicleFlag.HOVER_UP_ONLY) == (int)VehicleFlag.HOVER_UP_ONLY)
303 {
304 if ((m_Hoverflags & VehicleFlag.HOVER_UP_ONLY) != (VehicleFlag)0)
305 m_Hoverflags &= ~(VehicleFlag.HOVER_UP_ONLY);
306 }
307 if ((pParam & (int)VehicleFlag.HOVER_WATER_ONLY) == (int)VehicleFlag.HOVER_WATER_ONLY)
308 {
309 if ((m_Hoverflags & VehicleFlag.HOVER_WATER_ONLY) != (VehicleFlag)0)
310 m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY);
311 }
312 if ((pParam & (int)VehicleFlag.LIMIT_MOTOR_UP) == (int)VehicleFlag.LIMIT_MOTOR_UP)
313 {
314 if ((m_flags & VehicleFlag.LIMIT_MOTOR_UP) != (VehicleFlag)0)
315 m_flags &= ~(VehicleFlag.LIMIT_MOTOR_UP);
316 }
317 if ((pParam & (int)VehicleFlag.LIMIT_ROLL_ONLY) == (int)VehicleFlag.LIMIT_ROLL_ONLY)
318 {
319 if ((m_flags & VehicleFlag.LIMIT_ROLL_ONLY) != (VehicleFlag)0)
320 m_flags &= ~(VehicleFlag.LIMIT_ROLL_ONLY);
321 }
322 if ((pParam & (int)VehicleFlag.MOUSELOOK_BANK) == (int)VehicleFlag.MOUSELOOK_BANK)
323 {
324 if ((m_flags & VehicleFlag.MOUSELOOK_BANK) != (VehicleFlag)0)
325 m_flags &= ~(VehicleFlag.MOUSELOOK_BANK);
326 }
327 if ((pParam & (int)VehicleFlag.MOUSELOOK_STEER) == (int)VehicleFlag.MOUSELOOK_STEER)
328 {
329 if ((m_flags & VehicleFlag.MOUSELOOK_STEER) != (VehicleFlag)0)
330 m_flags &= ~(VehicleFlag.MOUSELOOK_STEER);
331 }
332 if ((pParam & (int)VehicleFlag.NO_DEFLECTION_UP) == (int)VehicleFlag.NO_DEFLECTION_UP)
333 {
334 if ((m_flags & VehicleFlag.NO_DEFLECTION_UP) != (VehicleFlag)0)
335 m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP);
336 }
337 if ((pParam & (int)VehicleFlag.CAMERA_DECOUPLED) == (int)VehicleFlag.CAMERA_DECOUPLED)
338 {
339 if ((m_flags & VehicleFlag.CAMERA_DECOUPLED) != (VehicleFlag)0)
340 m_flags &= ~(VehicleFlag.CAMERA_DECOUPLED);
341 }
342 if ((pParam & (int)VehicleFlag.NO_X) == (int)VehicleFlag.NO_X)
343 {
344 if ((m_flags & VehicleFlag.NO_X) != (VehicleFlag)0)
345 m_flags &= ~(VehicleFlag.NO_X);
346 }
347 if ((pParam & (int)VehicleFlag.NO_Y) == (int)VehicleFlag.NO_Y)
348 {
349 if ((m_flags & VehicleFlag.NO_Y) != (VehicleFlag)0)
350 m_flags &= ~(VehicleFlag.NO_Y);
351 }
352 if ((pParam & (int)VehicleFlag.NO_Z) == (int)VehicleFlag.NO_Z)
353 {
354 if ((m_flags & VehicleFlag.NO_Z) != (VehicleFlag)0)
355 m_flags &= ~(VehicleFlag.NO_Z);
356 }
357 if ((pParam & (int)VehicleFlag.LOCK_HOVER_HEIGHT) == (int)VehicleFlag.LOCK_HOVER_HEIGHT)
358 {
359 if ((m_Hoverflags & VehicleFlag.LOCK_HOVER_HEIGHT) != (VehicleFlag)0)
360 m_Hoverflags &= ~(VehicleFlag.LOCK_HOVER_HEIGHT);
361 }
362 if ((pParam & (int)VehicleFlag.NO_DEFLECTION) == (int)VehicleFlag.NO_DEFLECTION)
363 {
364 if ((m_flags & VehicleFlag.NO_DEFLECTION) != (VehicleFlag)0)
365 m_flags &= ~(VehicleFlag.NO_DEFLECTION);
366 }
367 if ((pParam & (int)VehicleFlag.LOCK_ROTATION) == (int)VehicleFlag.LOCK_ROTATION)
368 { 293 {
369 if ((m_flags & VehicleFlag.LOCK_ROTATION) != (VehicleFlag)0) 294 m_flags &= ~parm;
370 m_flags &= ~(VehicleFlag.LOCK_ROTATION);
371 } 295 }
372 } 296 }
373 else 297 else {
374 { 298 m_flags |= parm;
375 if ((pParam & (int)VehicleFlag.HOVER_GLOBAL_HEIGHT) == (int)VehicleFlag.HOVER_GLOBAL_HEIGHT)
376 {
377 m_Hoverflags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT | m_flags);
378 }
379 if ((pParam & (int)VehicleFlag.HOVER_TERRAIN_ONLY) == (int)VehicleFlag.HOVER_TERRAIN_ONLY)
380 {
381 m_Hoverflags |= (VehicleFlag.HOVER_TERRAIN_ONLY | m_flags);
382 }
383 if ((pParam & (int)VehicleFlag.HOVER_UP_ONLY) == (int)VehicleFlag.HOVER_UP_ONLY)
384 {
385 m_Hoverflags |= (VehicleFlag.HOVER_UP_ONLY | m_flags);
386 }
387 if ((pParam & (int)VehicleFlag.HOVER_WATER_ONLY) == (int)VehicleFlag.HOVER_WATER_ONLY)
388 {
389 m_Hoverflags |= (VehicleFlag.HOVER_WATER_ONLY | m_flags);
390 }
391 if ((pParam & (int)VehicleFlag.LIMIT_MOTOR_UP) == (int)VehicleFlag.LIMIT_MOTOR_UP)
392 {
393 m_flags |= (VehicleFlag.LIMIT_MOTOR_UP | m_flags);
394 }
395 if ((pParam & (int)VehicleFlag.MOUSELOOK_BANK) == (int)VehicleFlag.MOUSELOOK_BANK)
396 {
397 m_flags |= (VehicleFlag.MOUSELOOK_BANK | m_flags);
398 }
399 if ((pParam & (int)VehicleFlag.MOUSELOOK_STEER) == (int)VehicleFlag.MOUSELOOK_STEER)
400 {
401 m_flags |= (VehicleFlag.MOUSELOOK_STEER | m_flags);
402 }
403 if ((pParam & (int)VehicleFlag.NO_DEFLECTION_UP) == (int)VehicleFlag.NO_DEFLECTION_UP)
404 {
405 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | m_flags);
406 }
407 if ((pParam & (int)VehicleFlag.CAMERA_DECOUPLED) == (int)VehicleFlag.CAMERA_DECOUPLED)
408 {
409 m_flags |= (VehicleFlag.CAMERA_DECOUPLED | m_flags);
410 }
411 if ((pParam & (int)VehicleFlag.NO_X) == (int)VehicleFlag.NO_X)
412 {
413 m_flags |= (VehicleFlag.NO_X);
414 }
415 if ((pParam & (int)VehicleFlag.NO_Y) == (int)VehicleFlag.NO_Y)
416 {
417 m_flags |= (VehicleFlag.NO_Y);
418 }
419 if ((pParam & (int)VehicleFlag.NO_Z) == (int)VehicleFlag.NO_Z)
420 {
421 m_flags |= (VehicleFlag.NO_Z);
422 }
423 if ((pParam & (int)VehicleFlag.LOCK_HOVER_HEIGHT) == (int)VehicleFlag.LOCK_HOVER_HEIGHT)
424 {
425 m_Hoverflags |= (VehicleFlag.LOCK_HOVER_HEIGHT);
426 }
427 if ((pParam & (int)VehicleFlag.NO_DEFLECTION) == (int)VehicleFlag.NO_DEFLECTION)
428 {
429 m_flags |= (VehicleFlag.NO_DEFLECTION);
430 }
431 if ((pParam & (int)VehicleFlag.LOCK_ROTATION) == (int)VehicleFlag.LOCK_ROTATION)
432 {
433 m_flags |= (VehicleFlag.LOCK_ROTATION);
434 }
435 } 299 }
436 }//end ProcessVehicleFlags 300 }//end ProcessVehicleFlags
437 301
438 internal void ProcessTypeChange(Vehicle pType) 302 internal void ProcessTypeChange(Vehicle pType)
439 { 303 {
440 DetailLog("{0},ProcessTypeChange,type={1}", m_prim.LocalID, pType); 304 VDetailLog("{0},ProcessTypeChange,type={1}", m_prim.LocalID, pType);
441 // Set Defaults For Type 305 // Set Defaults For Type
442 m_type = pType; 306 m_type = pType;
443 switch (pType) 307 switch (pType)
@@ -478,10 +342,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
478 // m_bankingMix = 1; 342 // m_bankingMix = 1;
479 // m_bankingTimescale = 10; 343 // m_bankingTimescale = 10;
480 // m_referenceFrame = Quaternion.Identity; 344 // m_referenceFrame = Quaternion.Identity;
481 m_Hoverflags &= 345 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
346 m_flags &=
482 ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | 347 ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
483 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); 348 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
484 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
485 break; 349 break;
486 case Vehicle.TYPE_CAR: 350 case Vehicle.TYPE_CAR:
487 m_linearFrictionTimescale = new Vector3(100, 2, 1000); 351 m_linearFrictionTimescale = new Vector3(100, 2, 1000);
@@ -506,10 +370,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
506 // m_bankingMix = 1; 370 // m_bankingMix = 1;
507 // m_bankingTimescale = 1; 371 // m_bankingTimescale = 1;
508 // m_referenceFrame = Quaternion.Identity; 372 // m_referenceFrame = Quaternion.Identity;
509 m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
510 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | 373 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY |
511 VehicleFlag.LIMIT_MOTOR_UP); 374 VehicleFlag.LIMIT_MOTOR_UP);
512 m_Hoverflags |= (VehicleFlag.HOVER_UP_ONLY); 375 m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
376 m_flags |= (VehicleFlag.HOVER_UP_ONLY);
513 break; 377 break;
514 case Vehicle.TYPE_BOAT: 378 case Vehicle.TYPE_BOAT:
515 m_linearFrictionTimescale = new Vector3(10, 3, 2); 379 m_linearFrictionTimescale = new Vector3(10, 3, 2);
@@ -534,12 +398,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
534 // m_bankingMix = 0.8f; 398 // m_bankingMix = 0.8f;
535 // m_bankingTimescale = 1; 399 // m_bankingTimescale = 1;
536 // m_referenceFrame = Quaternion.Identity; 400 // m_referenceFrame = Quaternion.Identity;
537 m_Hoverflags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY | 401 m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY |
538 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); 402 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
539 m_flags &= ~(VehicleFlag.LIMIT_ROLL_ONLY); 403 m_flags &= ~(VehicleFlag.LIMIT_ROLL_ONLY);
540 m_flags |= (VehicleFlag.NO_DEFLECTION_UP | 404 m_flags |= (VehicleFlag.NO_DEFLECTION_UP |
541 VehicleFlag.LIMIT_MOTOR_UP); 405 VehicleFlag.LIMIT_MOTOR_UP);
542 m_Hoverflags |= (VehicleFlag.HOVER_WATER_ONLY); 406 m_flags |= (VehicleFlag.HOVER_WATER_ONLY);
543 break; 407 break;
544 case Vehicle.TYPE_AIRPLANE: 408 case Vehicle.TYPE_AIRPLANE:
545 m_linearFrictionTimescale = new Vector3(200, 10, 5); 409 m_linearFrictionTimescale = new Vector3(200, 10, 5);
@@ -564,7 +428,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
564 // m_bankingMix = 0.7f; 428 // m_bankingMix = 0.7f;
565 // m_bankingTimescale = 2; 429 // m_bankingTimescale = 2;
566 // m_referenceFrame = Quaternion.Identity; 430 // m_referenceFrame = Quaternion.Identity;
567 m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | 431 m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
568 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); 432 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
569 m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP); 433 m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP);
570 m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY); 434 m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
@@ -592,15 +456,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin
592 // m_bankingMix = 0.7f; 456 // m_bankingMix = 0.7f;
593 // m_bankingTimescale = 5; 457 // m_bankingTimescale = 5;
594 // m_referenceFrame = Quaternion.Identity; 458 // m_referenceFrame = Quaternion.Identity;
595 m_Hoverflags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | 459 m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
596 VehicleFlag.HOVER_UP_ONLY); 460 VehicleFlag.HOVER_UP_ONLY);
597 m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP); 461 m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_MOTOR_UP);
598 m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY); 462 m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
599 m_Hoverflags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT); 463 m_flags |= (VehicleFlag.HOVER_GLOBAL_HEIGHT);
600 break; 464 break;
601 } 465 }
602 }//end SetDefaultsForType 466 }//end SetDefaultsForType
603 467
468 // One step of the vehicle properties for the next 'pTimestep' seconds.
604 internal void Step(float pTimestep) 469 internal void Step(float pTimestep)
605 { 470 {
606 if (m_type == Vehicle.TYPE_NONE) return; 471 if (m_type == Vehicle.TYPE_NONE) return;
@@ -613,29 +478,30 @@ namespace OpenSim.Region.Physics.BulletSPlugin
613 MoveAngular(pTimestep); 478 MoveAngular(pTimestep);
614 LimitRotation(pTimestep); 479 LimitRotation(pTimestep);
615 480
616 DetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}", 481 // remember the position so next step we can limit absolute movement effects
482 m_lastPositionVector = m_prim.Position;
483
484 VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}",
617 m_prim.LocalID, m_prim.Position, m_prim.Force, m_prim.Velocity, m_prim.RotationalVelocity); 485 m_prim.LocalID, m_prim.Position, m_prim.Force, m_prim.Velocity, m_prim.RotationalVelocity);
618 }// end Step 486 }// end Step
619 487
620 private void MoveLinear(float pTimestep) 488 private void MoveLinear(float pTimestep)
621 { 489 {
622 // requested m_linearMotorDirection is significant 490 // m_linearMotorDirection is the direction we are moving relative to the vehicle coordinates
623 // if (!m_linearMotorDirection.ApproxEquals(Vector3.Zero, 0.01f)) 491 // m_lastLinearVelocityVector is the speed we are moving in that direction
624 if (m_linearMotorDirection.LengthSquared() > 0.0001f) 492 if (m_linearMotorDirection.LengthSquared() > 0.001f)
625 { 493 {
626 Vector3 origDir = m_linearMotorDirection; 494 Vector3 origDir = m_linearMotorDirection;
627 Vector3 origVel = m_lastLinearVelocityVector; 495 Vector3 origVel = m_lastLinearVelocityVector;
628 496
629 // add drive to body 497 // add drive to body
630 // Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale/pTimestep); 498 // Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale / pTimestep);
631 Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale); 499 Vector3 addAmount = (m_linearMotorDirection - m_lastLinearVelocityVector)/(m_linearMotorTimescale / pTimestep);
632 // lastLinearVelocityVector is the current body velocity vector? 500 // lastLinearVelocityVector is the current body velocity vector
633 // RA: Not sure what the *10 is for. A correction for pTimestep? 501 // RA: Not sure what the *10 is for. A correction for pTimestep?
634 // m_lastLinearVelocityVector += (addAmount*10); 502 // m_lastLinearVelocityVector += (addAmount*10);
635 m_lastLinearVelocityVector += addAmount; 503 m_lastLinearVelocityVector += addAmount;
636 504
637 // This will work temporarily, but we really need to compare speed on an axis
638 // KF: Limit body velocity to applied velocity?
639 // Limit the velocity vector to less than the last set linear motor direction 505 // Limit the velocity vector to less than the last set linear motor direction
640 if (Math.Abs(m_lastLinearVelocityVector.X) > Math.Abs(m_linearMotorDirectionLASTSET.X)) 506 if (Math.Abs(m_lastLinearVelocityVector.X) > Math.Abs(m_linearMotorDirectionLASTSET.X))
641 m_lastLinearVelocityVector.X = m_linearMotorDirectionLASTSET.X; 507 m_lastLinearVelocityVector.X = m_linearMotorDirectionLASTSET.X;
@@ -644,120 +510,83 @@ namespace OpenSim.Region.Physics.BulletSPlugin
644 if (Math.Abs(m_lastLinearVelocityVector.Z) > Math.Abs(m_linearMotorDirectionLASTSET.Z)) 510 if (Math.Abs(m_lastLinearVelocityVector.Z) > Math.Abs(m_linearMotorDirectionLASTSET.Z))
645 m_lastLinearVelocityVector.Z = m_linearMotorDirectionLASTSET.Z; 511 m_lastLinearVelocityVector.Z = m_linearMotorDirectionLASTSET.Z;
646 512
513 /*
647 // decay applied velocity 514 // decay applied velocity
648 Vector3 decayfraction = ((Vector3.One/(m_linearMotorDecayTimescale/pTimestep))); 515 Vector3 decayfraction = Vector3.One/(m_linearMotorDecayTimescale / pTimestep);
516 // (RA: do not know where the 0.5f comes from)
649 m_linearMotorDirection -= m_linearMotorDirection * decayfraction * 0.5f; 517 m_linearMotorDirection -= m_linearMotorDirection * decayfraction * 0.5f;
650
651 /*
652 Vector3 addAmount = (m_linearMotorDirection - m_lastLinearVelocityVector)/m_linearMotorTimescale;
653 m_lastLinearVelocityVector += addAmount;
654
655 float decayfraction = (1.0f - 1.0f / m_linearMotorDecayTimescale);
656 m_linearMotorDirection *= decayfraction;
657
658 */ 518 */
519 float keepfraction = 1.0f - (1.0f / (m_linearMotorDecayTimescale / pTimestep));
520 m_linearMotorDirection *= keepfraction;
659 521
660 DetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},add={3},decay={4},dir={5},vel={6}", 522 VDetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},add={3},notDecay={4},dir={5},vel={6}",
661 m_prim.LocalID, origDir, origVel, addAmount, decayfraction, m_linearMotorDirection, m_lastLinearVelocityVector); 523 m_prim.LocalID, origDir, origVel, addAmount, keepfraction, m_linearMotorDirection, m_lastLinearVelocityVector);
662 } 524 }
663 else 525 else
664 { 526 {
665 // if what remains of applied is small, zero it. 527 // if what remains of direction is very small, zero it.
666 // if (m_lastLinearVelocityVector.ApproxEquals(Vector3.Zero, 0.01f))
667 // m_lastLinearVelocityVector = Vector3.Zero;
668 m_linearMotorDirection = Vector3.Zero; 528 m_linearMotorDirection = Vector3.Zero;
669 m_lastLinearVelocityVector = Vector3.Zero; 529 m_lastLinearVelocityVector = Vector3.Zero;
530 VDetailLog("{0},MoveLinear,zeroed", m_prim.LocalID);
670 } 531 }
671 532
672 // convert requested object velocity to world-referenced vector 533 // convert requested object velocity to object relative vector
673 Quaternion rotq = m_prim.Orientation; 534 Quaternion rotq = m_prim.Orientation;
674 m_dir = m_lastLinearVelocityVector * rotq; 535 m_newVelocity = m_lastLinearVelocityVector * rotq;
675 536
676 // Add the various forces into m_dir which will be our new direction vector (velocity) 537 // Add the various forces into m_dir which will be our new direction vector (velocity)
677 538
678 // add Gravity and Buoyancy 539 // add Gravity and Buoyancy
679 // KF: So far I have found no good method to combine a script-requested
680 // .Z velocity and gravity. Therefore only 0g will used script-requested
681 // .Z velocity. >0g (m_VehicleBuoyancy < 1) will used modified gravity only.
682 Vector3 grav = Vector3.Zero;
683 // There is some gravity, make a gravity force vector that is applied after object velocity. 540 // There is some gravity, make a gravity force vector that is applied after object velocity.
684 // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; 541 // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g;
685 grav.Z = m_prim.Scene.DefaultGravity.Z * m_prim.Mass * (1f - m_VehicleBuoyancy); 542 Vector3 grav = m_prim.Scene.DefaultGravity * (m_prim.Mass * (1f - m_VehicleBuoyancy));
543
544 /*
545 * RA: Not sure why one would do this
686 // Preserve the current Z velocity 546 // Preserve the current Z velocity
687 Vector3 vel_now = m_prim.Velocity; 547 Vector3 vel_now = m_prim.Velocity;
688 m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity 548 m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity
549 */
689 550
690 Vector3 pos = m_prim.Position; 551 Vector3 pos = m_prim.Position;
691 Vector3 posChange = pos;
692// Vector3 accel = new Vector3(-(m_dir.X - m_lastLinearVelocityVector.X / 0.1f), -(m_dir.Y - m_lastLinearVelocityVector.Y / 0.1f), m_dir.Z - m_lastLinearVelocityVector.Z / 0.1f); 552// Vector3 accel = new Vector3(-(m_dir.X - m_lastLinearVelocityVector.X / 0.1f), -(m_dir.Y - m_lastLinearVelocityVector.Y / 0.1f), m_dir.Z - m_lastLinearVelocityVector.Z / 0.1f);
693 double Zchange = Math.Abs(posChange.Z);
694 if (m_BlockingEndPoint != Vector3.Zero)
695 {
696 bool changed = false;
697 if (pos.X >= (m_BlockingEndPoint.X - (float)1))
698 {
699 pos.X -= posChange.X + 1;
700 changed = true;
701 }
702 if (pos.Y >= (m_BlockingEndPoint.Y - (float)1))
703 {
704 pos.Y -= posChange.Y + 1;
705 changed = true;
706 }
707 if (pos.Z >= (m_BlockingEndPoint.Z - (float)1))
708 {
709 pos.Z -= posChange.Z + 1;
710 changed = true;
711 }
712 if (pos.X <= 0)
713 {
714 pos.X += posChange.X + 1;
715 changed = true;
716 }
717 if (pos.Y <= 0)
718 {
719 pos.Y += posChange.Y + 1;
720 changed = true;
721 }
722 if (changed)
723 {
724 m_prim.Position = pos;
725 DetailLog("{0},MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}",
726 m_prim.LocalID, m_BlockingEndPoint, posChange, pos);
727 }
728 }
729 553
730 // If below the terrain, move us above the ground a little. 554 // If below the terrain, move us above the ground a little.
731 if (pos.Z < m_prim.Scene.GetTerrainHeightAtXYZ(pos)) 555 float terrainHeight = m_prim.Scene.TerrainManager.GetTerrainHeightAtXYZ(pos);
556 // Taking the rotated size doesn't work here because m_prim.Size is the size of the root prim and not the linkset.
557 // Need to add a m_prim.LinkSet.Size similar to m_prim.LinkSet.Mass.
558 // Vector3 rotatedSize = m_prim.Size * m_prim.Orientation;
559 // if (rotatedSize.Z < terrainHeight)
560 if (pos.Z < terrainHeight)
732 { 561 {
733 pos.Z = m_prim.Scene.GetTerrainHeightAtXYZ(pos) + 2; 562 pos.Z = terrainHeight + 2;
734 m_prim.Position = pos; 563 m_prim.Position = pos;
735 DetailLog("{0},MoveLinear,terrainHeight,pos={1}", m_prim.LocalID, pos); 564 VDetailLog("{0},MoveLinear,terrainHeight,terrainHeight={1},pos={2}", m_prim.LocalID, terrainHeight, pos);
736 } 565 }
737 566
738 // Check if hovering 567 // Check if hovering
739 if ((m_Hoverflags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0) 568 if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0)
740 { 569 {
741 // We should hover, get the target height 570 // We should hover, get the target height
742 if ((m_Hoverflags & VehicleFlag.HOVER_WATER_ONLY) != 0) 571 if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0)
743 { 572 {
744 m_VhoverTargetHeight = m_prim.Scene.GetWaterLevel() + m_VhoverHeight; 573 m_VhoverTargetHeight = m_prim.Scene.GetWaterLevelAtXYZ(pos) + m_VhoverHeight;
745 } 574 }
746 if ((m_Hoverflags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0) 575 if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0)
747 { 576 {
748 m_VhoverTargetHeight = m_prim.Scene.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight; 577 m_VhoverTargetHeight = terrainHeight + m_VhoverHeight;
749 } 578 }
750 if ((m_Hoverflags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0) 579 if ((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0)
751 { 580 {
752 m_VhoverTargetHeight = m_VhoverHeight; 581 m_VhoverTargetHeight = m_VhoverHeight;
753 } 582 }
754 583
755 if ((m_Hoverflags & VehicleFlag.HOVER_UP_ONLY) != 0) 584 if ((m_flags & VehicleFlag.HOVER_UP_ONLY) != 0)
756 { 585 {
757 // If body is aready heigher, use its height as target height 586 // If body is aready heigher, use its height as target height
758 if (pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z; 587 if (pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z;
759 } 588 }
760 if ((m_Hoverflags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0) 589 if ((m_flags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0)
761 { 590 {
762 if ((pos.Z - m_VhoverTargetHeight) > .2 || (pos.Z - m_VhoverTargetHeight) < -.2) 591 if ((pos.Z - m_VhoverTargetHeight) > .2 || (pos.Z - m_VhoverTargetHeight) < -.2)
763 { 592 {
@@ -770,82 +599,92 @@ namespace OpenSim.Region.Physics.BulletSPlugin
770 // Replace Vertical speed with correction figure if significant 599 // Replace Vertical speed with correction figure if significant
771 if (Math.Abs(herr0) > 0.01f) 600 if (Math.Abs(herr0) > 0.01f)
772 { 601 {
773 m_dir.Z = -((herr0 * pTimestep * 50.0f) / m_VhoverTimescale); 602 m_newVelocity.Z = -((herr0 * pTimestep * 50.0f) / m_VhoverTimescale);
774 //KF: m_VhoverEfficiency is not yet implemented 603 //KF: m_VhoverEfficiency is not yet implemented
775 } 604 }
776 else 605 else
777 { 606 {
778 m_dir.Z = 0f; 607 m_newVelocity.Z = 0f;
779 } 608 }
780 } 609 }
781 610
782 DetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", m_prim.LocalID, pos, m_dir, m_VhoverHeight, m_VhoverTargetHeight); 611 VDetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", m_prim.LocalID, pos, m_newVelocity, m_VhoverHeight, m_VhoverTargetHeight);
612 }
783 613
784// m_VhoverEfficiency = 0f; // 0=boucy, 1=Crit.damped 614 Vector3 posChange = pos - m_lastPositionVector;
785// m_VhoverTimescale = 0f; // time to acheive height 615 if (m_BlockingEndPoint != Vector3.Zero)
786// pTimestep is time since last frame,in secs 616 {
617 bool changed = false;
618 if (pos.X >= (m_BlockingEndPoint.X - (float)1))
619 {
620 pos.X -= posChange.X + 1;
621 changed = true;
622 }
623 if (pos.Y >= (m_BlockingEndPoint.Y - (float)1))
624 {
625 pos.Y -= posChange.Y + 1;
626 changed = true;
627 }
628 if (pos.Z >= (m_BlockingEndPoint.Z - (float)1))
629 {
630 pos.Z -= posChange.Z + 1;
631 changed = true;
632 }
633 if (pos.X <= 0)
634 {
635 pos.X += posChange.X + 1;
636 changed = true;
637 }
638 if (pos.Y <= 0)
639 {
640 pos.Y += posChange.Y + 1;
641 changed = true;
642 }
643 if (changed)
644 {
645 m_prim.Position = pos;
646 VDetailLog("{0},MoveLinear,blockingEndPoint,block={1},origPos={2},pos={3}",
647 m_prim.LocalID, m_BlockingEndPoint, posChange, pos);
648 }
787 } 649 }
788 650
651 float Zchange = Math.Abs(posChange.Z);
789 if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0) 652 if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0)
790 { 653 {
791 //Start Experimental Values
792 if (Zchange > .3) 654 if (Zchange > .3)
793 {
794 grav.Z = (float)(grav.Z * 3); 655 grav.Z = (float)(grav.Z * 3);
795 }
796 if (Zchange > .15) 656 if (Zchange > .15)
797 {
798 grav.Z = (float)(grav.Z * 2); 657 grav.Z = (float)(grav.Z * 2);
799 }
800 if (Zchange > .75) 658 if (Zchange > .75)
801 {
802 grav.Z = (float)(grav.Z * 1.5); 659 grav.Z = (float)(grav.Z * 1.5);
803 }
804 if (Zchange > .05) 660 if (Zchange > .05)
805 {
806 grav.Z = (float)(grav.Z * 1.25); 661 grav.Z = (float)(grav.Z * 1.25);
807 }
808 if (Zchange > .025) 662 if (Zchange > .025)
809 {
810 grav.Z = (float)(grav.Z * 1.125); 663 grav.Z = (float)(grav.Z * 1.125);
811 } 664 float postemp = (pos.Z - terrainHeight);
812 float terraintemp = m_prim.Scene.GetTerrainHeightAtXYZ(pos);
813 float postemp = (pos.Z - terraintemp);
814 if (postemp > 2.5f) 665 if (postemp > 2.5f)
815 {
816 grav.Z = (float)(grav.Z * 1.037125); 666 grav.Z = (float)(grav.Z * 1.037125);
817 } 667 VDetailLog("{0},MoveLinear,limitMotorUp,grav={1}", m_prim.LocalID, grav);
818 DetailLog("{0},MoveLinear,limitMotorUp,grav={1}", m_prim.LocalID, grav);
819 //End Experimental Values
820 } 668 }
821 if ((m_flags & (VehicleFlag.NO_X)) != 0) 669 if ((m_flags & (VehicleFlag.NO_X)) != 0)
822 { 670 m_newVelocity.X = 0;
823 m_dir.X = 0;
824 }
825 if ((m_flags & (VehicleFlag.NO_Y)) != 0) 671 if ((m_flags & (VehicleFlag.NO_Y)) != 0)
826 { 672 m_newVelocity.Y = 0;
827 m_dir.Y = 0;
828 }
829 if ((m_flags & (VehicleFlag.NO_Z)) != 0) 673 if ((m_flags & (VehicleFlag.NO_Z)) != 0)
830 { 674 m_newVelocity.Z = 0;
831 m_dir.Z = 0;
832 }
833
834 m_lastPositionVector = m_prim.Position;
835 675
836 // Apply velocity 676 // Apply velocity
837 m_prim.Velocity = m_dir; 677 m_prim.Velocity = m_newVelocity;
838 // apply gravity force 678 // apply gravity force
839 // Why is this set here? The physics engine already does gravity. 679 // Why is this set here? The physics engine already does gravity.
840 // m_prim.AddForce(grav, false); 680 // m_prim.AddForce(grav, false);
841 // m_prim.Force = grav;
842 681
843 // Apply friction 682 // Apply friction
844 Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep); 683 Vector3 keepFraction = Vector3.One - (Vector3.One / (m_linearFrictionTimescale / pTimestep));
845 m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount; 684 m_lastLinearVelocityVector *= keepFraction;
846 685
847 DetailLog("{0},MoveLinear,done,pos={1},vel={2},force={3},decay={4}", 686 VDetailLog("{0},MoveLinear,done,lmDir={1},lmVel={2},newVel={3},grav={4},1Mdecay={5}",
848 m_prim.LocalID, m_lastPositionVector, m_dir, grav, decayamount); 687 m_prim.LocalID, m_linearMotorDirection, m_lastLinearVelocityVector, m_newVelocity, grav, keepFraction);
849 688
850 } // end MoveLinear() 689 } // end MoveLinear()
851 690
@@ -870,30 +709,33 @@ namespace OpenSim.Region.Physics.BulletSPlugin
870 // There are m_angularMotorApply steps. 709 // There are m_angularMotorApply steps.
871 Vector3 origAngularVelocity = m_angularMotorVelocity; 710 Vector3 origAngularVelocity = m_angularMotorVelocity;
872 // ramp up to new value 711 // ramp up to new value
873 // current velocity += error / (time to get there / step interval) 712 // current velocity += error / ( time to get there / step interval)
874 // requested speed - last motor speed 713 // requested speed - last motor speed
875 m_angularMotorVelocity.X += (m_angularMotorDirection.X - m_angularMotorVelocity.X) / (m_angularMotorTimescale / pTimestep); 714 m_angularMotorVelocity.X += (m_angularMotorDirection.X - m_angularMotorVelocity.X) / (m_angularMotorTimescale / pTimestep);
876 m_angularMotorVelocity.Y += (m_angularMotorDirection.Y - m_angularMotorVelocity.Y) / (m_angularMotorTimescale / pTimestep); 715 m_angularMotorVelocity.Y += (m_angularMotorDirection.Y - m_angularMotorVelocity.Y) / (m_angularMotorTimescale / pTimestep);
877 m_angularMotorVelocity.Z += (m_angularMotorDirection.Z - m_angularMotorVelocity.Z) / (m_angularMotorTimescale / pTimestep); 716 m_angularMotorVelocity.Z += (m_angularMotorDirection.Z - m_angularMotorVelocity.Z) / (m_angularMotorTimescale / pTimestep);
878 717
879 DetailLog("{0},MoveAngular,angularMotorApply,apply={1},origvel={2},dir={3},vel={4}", 718 VDetailLog("{0},MoveAngular,angularMotorApply,apply={1},angTScale={2},timeStep={3},origvel={4},dir={5},vel={6}",
880 m_prim.LocalID,m_angularMotorApply,origAngularVelocity, m_angularMotorDirection, m_angularMotorVelocity); 719 m_prim.LocalID, m_angularMotorApply, m_angularMotorTimescale, pTimestep, origAngularVelocity, m_angularMotorDirection, m_angularMotorVelocity);
881 720
882 m_angularMotorApply--; // This is done so that if script request rate is less than phys frame rate the expected 721 // This is done so that if script request rate is less than phys frame rate the expected
883 // velocity may still be acheived. 722 // velocity may still be acheived.
723 m_angularMotorApply--;
884 } 724 }
885 else 725 else
886 { 726 {
887 // No motor recently applied, keep the body velocity 727 // No motor recently applied, keep the body velocity
888 // and decay the velocity 728 // and decay the velocity
889 m_angularMotorVelocity -= m_angularMotorVelocity / (m_angularMotorDecayTimescale / pTimestep); 729 m_angularMotorVelocity -= m_angularMotorVelocity / (m_angularMotorDecayTimescale / pTimestep);
730 if (m_angularMotorVelocity.LengthSquared() < 0.00001)
731 m_angularMotorVelocity = Vector3.Zero;
890 } // end motor section 732 } // end motor section
891 733
892 // Vertical attractor section 734 // Vertical attractor section
893 Vector3 vertattr = Vector3.Zero; 735 Vector3 vertattr = Vector3.Zero;
894 if (m_verticalAttractionTimescale < 300) 736 if (m_verticalAttractionTimescale < 300)
895 { 737 {
896 float VAservo = 0.2f / (m_verticalAttractionTimescale * pTimestep); 738 float VAservo = 0.2f / (m_verticalAttractionTimescale / pTimestep);
897 // get present body rotation 739 // get present body rotation
898 Quaternion rotq = m_prim.Orientation; 740 Quaternion rotq = m_prim.Orientation;
899 // make a vector pointing up 741 // make a vector pointing up
@@ -924,7 +766,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
924 vertattr.X += bounce * angularVelocity.X; 766 vertattr.X += bounce * angularVelocity.X;
925 vertattr.Y += bounce * angularVelocity.Y; 767 vertattr.Y += bounce * angularVelocity.Y;
926 768
927 DetailLog("{0},MoveAngular,verticalAttraction,verterr={1},bounce={2},vertattr={3}", 769 VDetailLog("{0},MoveAngular,verticalAttraction,verterr={1},bounce={2},vertattr={3}",
928 m_prim.LocalID, verterr, bounce, vertattr); 770 m_prim.LocalID, verterr, bounce, vertattr);
929 771
930 } // else vertical attractor is off 772 } // else vertical attractor is off
@@ -942,13 +784,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
942 { 784 {
943 m_lastAngularVelocity.X = 0; 785 m_lastAngularVelocity.X = 0;
944 m_lastAngularVelocity.Y = 0; 786 m_lastAngularVelocity.Y = 0;
945 DetailLog("{0},MoveAngular,noDeflectionUp,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity); 787 VDetailLog("{0},MoveAngular,noDeflectionUp,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity);
946 } 788 }
947 789
948 if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) 790 if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f))
949 { 791 {
950 m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. 792 m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero.
951 DetailLog("{0},MoveAngular,zeroSmallValues,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity); 793 VDetailLog("{0},MoveAngular,zeroSmallValues,lastAngular={1}", m_prim.LocalID, m_lastAngularVelocity);
952 } 794 }
953 795
954 // apply friction 796 // apply friction
@@ -958,7 +800,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
958 // Apply to the body 800 // Apply to the body
959 m_prim.RotationalVelocity = m_lastAngularVelocity; 801 m_prim.RotationalVelocity = m_lastAngularVelocity;
960 802
961 DetailLog("{0},MoveAngular,done,decay={1},lastAngular={2}", m_prim.LocalID, decayamount, m_lastAngularVelocity); 803 VDetailLog("{0},MoveAngular,done,decay={1},lastAngular={2}", m_prim.LocalID, decayamount, m_lastAngularVelocity);
962 } //end MoveAngular 804 } //end MoveAngular
963 805
964 internal void LimitRotation(float timestep) 806 internal void LimitRotation(float timestep)
@@ -996,20 +838,16 @@ namespace OpenSim.Region.Physics.BulletSPlugin
996 m_rot.Y = 0; 838 m_rot.Y = 0;
997 changed = true; 839 changed = true;
998 } 840 }
999 if ((m_flags & VehicleFlag.LOCK_ROTATION) != 0)
1000 {
1001 m_rot.X = 0;
1002 m_rot.Y = 0;
1003 changed = true;
1004 }
1005 if (changed) 841 if (changed)
842 {
1006 m_prim.Orientation = m_rot; 843 m_prim.Orientation = m_rot;
844 VDetailLog("{0},LimitRotation,done,orig={1},new={2}", m_prim.LocalID, rotq, m_rot);
845 }
1007 846
1008 DetailLog("{0},LimitRotation,done,changed={1},orig={2},new={3}", m_prim.LocalID, changed, rotq, m_rot);
1009 } 847 }
1010 848
1011 // Invoke the detailed logger and output something if it's enabled. 849 // Invoke the detailed logger and output something if it's enabled.
1012 private void DetailLog(string msg, params Object[] args) 850 private void VDetailLog(string msg, params Object[] args)
1013 { 851 {
1014 if (m_prim.Scene.VehicleLoggingEnabled) 852 if (m_prim.Scene.VehicleLoggingEnabled)
1015 m_prim.Scene.PhysicsLogging.Write(msg, args); 853 m_prim.Scene.PhysicsLogging.Write(msg, args);
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
index 087b9bb..7e784eb 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs
@@ -36,14 +36,17 @@ public class BSLinkset
36{ 36{
37 private static string LogHeader = "[BULLETSIM LINKSET]"; 37 private static string LogHeader = "[BULLETSIM LINKSET]";
38 38
39 private BSPrim m_linksetRoot; 39 private BSPhysObject m_linksetRoot;
40 public BSPrim LinksetRoot { get { return m_linksetRoot; } } 40 public BSPhysObject LinksetRoot { get { return m_linksetRoot; } }
41 41
42 private BSScene m_physicsScene; 42 private BSScene m_physicsScene;
43 public BSScene PhysicsScene { get { return m_physicsScene; } } 43 public BSScene PhysicsScene { get { return m_physicsScene; } }
44 44
45 static int m_nextLinksetID = 1;
46 public int LinksetID { get; private set; }
47
45 // The children under the root in this linkset 48 // The children under the root in this linkset
46 private List<BSPrim> m_children; 49 private List<BSPhysObject> m_children;
47 50
48 // We lock the diddling of linkset classes to prevent any badness. 51 // We lock the diddling of linkset classes to prevent any badness.
49 // This locks the modification of the instances of this class. Changes 52 // This locks the modification of the instances of this class. Changes
@@ -71,19 +74,23 @@ public class BSLinkset
71 get { return ComputeLinksetGeometricCenter(); } 74 get { return ComputeLinksetGeometricCenter(); }
72 } 75 }
73 76
74 public BSLinkset(BSScene scene, BSPrim parent) 77 public BSLinkset(BSScene scene, BSPhysObject parent)
75 { 78 {
76 // A simple linkset of one (no children) 79 // A simple linkset of one (no children)
80 LinksetID = m_nextLinksetID++;
81 // We create LOTS of linksets.
82 if (m_nextLinksetID < 0)
83 m_nextLinksetID = 1;
77 m_physicsScene = scene; 84 m_physicsScene = scene;
78 m_linksetRoot = parent; 85 m_linksetRoot = parent;
79 m_children = new List<BSPrim>(); 86 m_children = new List<BSPhysObject>();
80 m_mass = parent.MassRaw; 87 m_mass = parent.MassRaw;
81 } 88 }
82 89
83 // Link to a linkset where the child knows the parent. 90 // Link to a linkset where the child knows the parent.
84 // Parent changing should not happen so do some sanity checking. 91 // Parent changing should not happen so do some sanity checking.
85 // We return the parent's linkset so the child can track its membership. 92 // We return the parent's linkset so the child can track its membership.
86 public BSLinkset AddMeToLinkset(BSPrim child) 93 public BSLinkset AddMeToLinkset(BSPhysObject child)
87 { 94 {
88 lock (m_linksetActivityLock) 95 lock (m_linksetActivityLock)
89 { 96 {
@@ -95,7 +102,7 @@ public class BSLinkset
95 // Remove a child from a linkset. 102 // Remove a child from a linkset.
96 // Returns a new linkset for the child which is a linkset of one (just the 103 // Returns a new linkset for the child which is a linkset of one (just the
97 // orphened child). 104 // orphened child).
98 public BSLinkset RemoveMeFromLinkset(BSPrim child) 105 public BSLinkset RemoveMeFromLinkset(BSPhysObject child)
99 { 106 {
100 lock (m_linksetActivityLock) 107 lock (m_linksetActivityLock)
101 { 108 {
@@ -122,7 +129,7 @@ public class BSLinkset
122 } 129 }
123 130
124 // Return 'true' if the passed object is the root object of this linkset 131 // Return 'true' if the passed object is the root object of this linkset
125 public bool IsRoot(BSPrim requestor) 132 public bool IsRoot(BSPhysObject requestor)
126 { 133 {
127 return (requestor.LocalID == m_linksetRoot.LocalID); 134 return (requestor.LocalID == m_linksetRoot.LocalID);
128 } 135 }
@@ -133,12 +140,12 @@ public class BSLinkset
133 public bool HasAnyChildren { get { return (m_children.Count > 0); } } 140 public bool HasAnyChildren { get { return (m_children.Count > 0); } }
134 141
135 // Return 'true' if this child is in this linkset 142 // Return 'true' if this child is in this linkset
136 public bool HasChild(BSPrim child) 143 public bool HasChild(BSPhysObject child)
137 { 144 {
138 bool ret = false; 145 bool ret = false;
139 lock (m_linksetActivityLock) 146 lock (m_linksetActivityLock)
140 { 147 {
141 foreach (BSPrim bp in m_children) 148 foreach (BSPhysObject bp in m_children)
142 { 149 {
143 if (child.LocalID == bp.LocalID) 150 if (child.LocalID == bp.LocalID)
144 { 151 {
@@ -153,7 +160,7 @@ public class BSLinkset
153 private float ComputeLinksetMass() 160 private float ComputeLinksetMass()
154 { 161 {
155 float mass = m_linksetRoot.MassRaw; 162 float mass = m_linksetRoot.MassRaw;
156 foreach (BSPrim bp in m_children) 163 foreach (BSPhysObject bp in m_children)
157 { 164 {
158 mass += bp.MassRaw; 165 mass += bp.MassRaw;
159 } 166 }
@@ -167,7 +174,7 @@ public class BSLinkset
167 174
168 lock (m_linksetActivityLock) 175 lock (m_linksetActivityLock)
169 { 176 {
170 foreach (BSPrim bp in m_children) 177 foreach (BSPhysObject bp in m_children)
171 { 178 {
172 com += bp.Position * bp.MassRaw; 179 com += bp.Position * bp.MassRaw;
173 totalMass += bp.MassRaw; 180 totalMass += bp.MassRaw;
@@ -185,7 +192,7 @@ public class BSLinkset
185 192
186 lock (m_linksetActivityLock) 193 lock (m_linksetActivityLock)
187 { 194 {
188 foreach (BSPrim bp in m_children) 195 foreach (BSPhysObject bp in m_children)
189 { 196 {
190 com += bp.Position * bp.MassRaw; 197 com += bp.Position * bp.MassRaw;
191 } 198 }
@@ -195,11 +202,33 @@ public class BSLinkset
195 return com; 202 return com;
196 } 203 }
197 204
205 // The object is going dynamic (physical). Do any setup necessary
206 // for a dynamic linkset.
207 // Only the state of the passed object can be modified. The rest of the linkset
208 // has not yet been fully constructed.
209 // Return 'true' if any properties updated on the passed object.
210 // Called at taint-time!
211 public bool MakeDynamic(BSPhysObject child)
212 {
213 bool ret = false;
214 return ret;
215 }
216
217 // The object is going static (non-physical). Do any setup necessary
218 // for a static linkset.
219 // Return 'true' if any properties updated on the passed object.
220 // Called at taint-time!
221 public bool MakeStatic(BSPhysObject child)
222 {
223 // What is done for each object in BSPrim is what we want.
224 return false;
225 }
226
198 // When physical properties are changed the linkset needs to recalculate 227 // When physical properties are changed the linkset needs to recalculate
199 // its internal properties. 228 // its internal properties.
200 public void Refresh(BSPrim requestor) 229 public void Refresh(BSPhysObject requestor)
201 { 230 {
202 // If there are no children, there aren't any constraints to recompute 231 // If there are no children, there can't be any constraints to recompute
203 if (!HasAnyChildren) 232 if (!HasAnyChildren)
204 return; 233 return;
205 234
@@ -218,15 +247,16 @@ public class BSLinkset
218 // from a linkset to make sure the constraints know about the new mass and 247 // from a linkset to make sure the constraints know about the new mass and
219 // geometry. 248 // geometry.
220 // Must only be called at taint time!! 249 // Must only be called at taint time!!
221 private bool RecomputeLinksetConstraintVariables() 250 private void RecomputeLinksetConstraintVariables()
222 { 251 {
223 float linksetMass = LinksetMass; 252 float linksetMass = LinksetMass;
224 lock (m_linksetActivityLock) 253 lock (m_linksetActivityLock)
225 { 254 {
226 foreach (BSPrim child in m_children) 255 bool somethingMissing = false;
256 foreach (BSPhysObject child in m_children)
227 { 257 {
228 BSConstraint constrain; 258 BSConstraint constrain;
229 if (m_physicsScene.Constraints.TryGetConstraint(LinksetRoot.Body, child.Body, out constrain)) 259 if (m_physicsScene.Constraints.TryGetConstraint(LinksetRoot.BSBody, child.BSBody, out constrain))
230 { 260 {
231 // DetailLog("{0},BSLinkset.RecomputeLinksetConstraintVariables,taint,child={1},mass={2},A={3},B={4}", 261 // DetailLog("{0},BSLinkset.RecomputeLinksetConstraintVariables,taint,child={1},mass={2},A={3},B={4}",
232 // LinksetRoot.LocalID, child.LocalID, linksetMass, constrain.Body1.ID, constrain.Body2.ID); 262 // LinksetRoot.LocalID, child.LocalID, linksetMass, constrain.Body1.ID, constrain.Body2.ID);
@@ -234,32 +264,51 @@ public class BSLinkset
234 } 264 }
235 else 265 else
236 { 266 {
237 // Non-fatal error that can happen when children are being added to the linkset but 267 // Non-fatal error that happens when children are being added to the linkset but
238 // their constraints have not been created yet. 268 // their constraints have not been created yet.
239 // Caused by the fact that m_children is built at run time but building constraints 269 // Caused by the fact that m_children is built at run time but building constraints
240 // happens at taint time. 270 // happens at taint time.
241 // m_physicsScene.Logger.ErrorFormat("[BULLETSIM LINKSET] RecomputeLinksetConstraintVariables: constraint not found for root={0}, child={1}", 271 somethingMissing = true;
242 // m_linksetRoot.Body.ID, child.Body.ID); 272 break;
243 } 273 }
244 } 274 }
275
276 // If the whole linkset is not here, doesn't make sense to recompute linkset wide values
277 if (!somethingMissing)
278 {
279 // If this is a multiple object linkset, set everybody's center of mass to the set's center of mass
280 OMV.Vector3 centerOfMass = ComputeLinksetCenterOfMass();
281 BulletSimAPI.SetCenterOfMassByPosRot2(LinksetRoot.BSBody.Ptr, centerOfMass, OMV.Quaternion.Identity);
282 foreach (BSPhysObject child in m_children)
283 {
284 BulletSimAPI.SetCenterOfMassByPosRot2(child.BSBody.Ptr, centerOfMass, OMV.Quaternion.Identity);
285 }
286 /*
287 // The root prim takes on the weight of the whole linkset
288 OMV.Vector3 inertia = BulletSimAPI.CalculateLocalInertia2(LinksetRoot.BSShape.Ptr, linksetMass);
289 BulletSimAPI.SetMassProps2(LinksetRoot.BSBody.Ptr, linksetMass, inertia);
290 OMV.Vector3 centerOfMass = ComputeLinksetCenterOfMass();
291 BulletSimAPI.SetCenterOfMassByPosRot2(LinksetRoot.BSBody.Ptr, centerOfMass, OMV.Quaternion.Identity);
292 BulletSimAPI.UpdateInertiaTensor2(LinksetRoot.BSBody.Ptr);
293 */
294 }
245 } 295 }
246 return false; 296 return;
247 } 297 }
248 298
249 // I am the root of a linkset and a new child is being added 299 // I am the root of a linkset and a new child is being added
250 // Called while LinkActivity is locked. 300 // Called while LinkActivity is locked.
251 private void AddChildToLinkset(BSPrim child) 301 private void AddChildToLinkset(BSPhysObject child)
252 { 302 {
253 if (!HasChild(child)) 303 if (!HasChild(child))
254 { 304 {
255 m_children.Add(child); 305 m_children.Add(child);
256 306
257 BSPrim rootx = LinksetRoot; // capture the root as of now 307 BSPhysObject rootx = LinksetRoot; // capture the root as of now
258 BSPrim childx = child; 308 BSPhysObject childx = child;
259 m_physicsScene.TaintedObject("AddChildToLinkset", delegate() 309 m_physicsScene.TaintedObject("AddChildToLinkset", delegate()
260 { 310 {
261 // DebugLog("{0}: AddChildToLinkset: adding child {1} to {2}", LogHeader, child.LocalID, m_linksetRoot.LocalID); 311 DetailLog("{0},AddChildToLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID);
262 // DetailLog("{0},AddChildToLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID);
263 PhysicallyLinkAChildToRoot(rootx, childx); // build the physical binding between me and the child 312 PhysicallyLinkAChildToRoot(rootx, childx); // build the physical binding between me and the child
264 }); 313 });
265 } 314 }
@@ -271,7 +320,7 @@ public class BSLinkset
271 // it's still connected to the linkset. 320 // it's still connected to the linkset.
272 // Normal OpenSimulator operation will never do this because other SceneObjectPart information 321 // Normal OpenSimulator operation will never do this because other SceneObjectPart information
273 // has to be updated also (like pointer to prim's parent). 322 // has to be updated also (like pointer to prim's parent).
274 private void RemoveChildFromOtherLinkset(BSPrim pchild) 323 private void RemoveChildFromOtherLinkset(BSPhysObject pchild)
275 { 324 {
276 pchild.Linkset = new BSLinkset(m_physicsScene, pchild); 325 pchild.Linkset = new BSLinkset(m_physicsScene, pchild);
277 RemoveChildFromLinkset(pchild); 326 RemoveChildFromLinkset(pchild);
@@ -279,21 +328,20 @@ public class BSLinkset
279 328
280 // I am the root of a linkset and one of my children is being removed. 329 // I am the root of a linkset and one of my children is being removed.
281 // Safe to call even if the child is not really in my linkset. 330 // Safe to call even if the child is not really in my linkset.
282 private void RemoveChildFromLinkset(BSPrim child) 331 private void RemoveChildFromLinkset(BSPhysObject child)
283 { 332 {
284 if (m_children.Remove(child)) 333 if (m_children.Remove(child))
285 { 334 {
286 BSPrim rootx = LinksetRoot; // capture the root as of now 335 BSPhysObject rootx = LinksetRoot; // capture the root as of now
287 BSPrim childx = child; 336 BSPhysObject childx = child;
288 m_physicsScene.TaintedObject("RemoveChildFromLinkset", delegate() 337 m_physicsScene.TaintedObject("RemoveChildFromLinkset", delegate()
289 { 338 {
290 // DebugLog("{0}: RemoveChildFromLinkset: Removing constraint to {1}", LogHeader, child.LocalID); 339 DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID);
291 // DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID);
292 340
293 PhysicallyUnlinkAChildFromRoot(rootx, childx); 341 PhysicallyUnlinkAChildFromRoot(rootx, childx);
342 RecomputeLinksetConstraintVariables();
294 }); 343 });
295 344
296 RecomputeLinksetConstraintVariables();
297 } 345 }
298 else 346 else
299 { 347 {
@@ -305,7 +353,7 @@ public class BSLinkset
305 353
306 // Create a constraint between me (root of linkset) and the passed prim (the child). 354 // Create a constraint between me (root of linkset) and the passed prim (the child).
307 // Called at taint time! 355 // Called at taint time!
308 private void PhysicallyLinkAChildToRoot(BSPrim rootPrim, BSPrim childPrim) 356 private void PhysicallyLinkAChildToRoot(BSPhysObject rootPrim, BSPhysObject childPrim)
309 { 357 {
310 // Zero motion for children so they don't interpolate 358 // Zero motion for children so they don't interpolate
311 childPrim.ZeroMotion(); 359 childPrim.ZeroMotion();
@@ -319,19 +367,18 @@ public class BSLinkset
319 367
320 // create a constraint that allows no freedom of movement between the two objects 368 // create a constraint that allows no freedom of movement between the two objects
321 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 369 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
322 // DebugLog("{0}: CreateLinkset: Adding a constraint between root prim {1} and child prim {2}", LogHeader, LocalID, childPrim.LocalID);
323 DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},child={2},rLoc={3},cLoc={4},midLoc={5}", 370 DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},child={2},rLoc={3},cLoc={4},midLoc={5}",
324 rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID, rootPrim.Position, childPrim.Position, midPoint); 371 rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID, rootPrim.Position, childPrim.Position, midPoint);
325 BS6DofConstraint constrain = new BS6DofConstraint( 372 BS6DofConstraint constrain = new BS6DofConstraint(
326 m_physicsScene.World, rootPrim.Body, childPrim.Body, 373 m_physicsScene.World, rootPrim.BSBody, childPrim.BSBody,
327 midPoint, 374 midPoint,
328 true, 375 true,
329 true 376 true
330 ); 377 );
331 /* NOTE: attempt to build constraint with full frame computation, etc. 378 /* NOTE: below is an attempt to build constraint with full frame computation, etc.
332 * Using the midpoint is easier since it lets the Bullet code use the transforms 379 * Using the midpoint is easier since it lets the Bullet code use the transforms
333 * of the objects. 380 * of the objects.
334 * Code left here as an example. 381 * Code left as a warning to future programmers.
335 // ================================================================================== 382 // ==================================================================================
336 // relative position normalized to the root prim 383 // relative position normalized to the root prim
337 OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(rootPrim.Orientation); 384 OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(rootPrim.Orientation);
@@ -343,7 +390,6 @@ public class BSLinkset
343 390
344 // create a constraint that allows no freedom of movement between the two objects 391 // create a constraint that allows no freedom of movement between the two objects
345 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 392 // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818
346 // DebugLog("{0}: CreateLinkset: Adding a constraint between root prim {1} and child prim {2}", LogHeader, LocalID, childPrim.LocalID);
347 DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID); 393 DetailLog("{0},PhysicallyLinkAChildToRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID);
348 BS6DofConstraint constrain = new BS6DofConstraint( 394 BS6DofConstraint constrain = new BS6DofConstraint(
349 PhysicsScene.World, rootPrim.Body, childPrim.Body, 395 PhysicsScene.World, rootPrim.Body, childPrim.Body,
@@ -374,40 +420,34 @@ public class BSLinkset
374 PhysicsScene.Params.linkConstraintTransMotorMaxVel, 420 PhysicsScene.Params.linkConstraintTransMotorMaxVel,
375 PhysicsScene.Params.linkConstraintTransMotorMaxForce); 421 PhysicsScene.Params.linkConstraintTransMotorMaxForce);
376 constrain.SetCFMAndERP(PhysicsScene.Params.linkConstraintCFM, PhysicsScene.Params.linkConstraintERP); 422 constrain.SetCFMAndERP(PhysicsScene.Params.linkConstraintCFM, PhysicsScene.Params.linkConstraintERP);
423 if (PhysicsScene.Params.linkConstraintSolverIterations != 0f)
424 {
425 constrain.SetSolverIterations(PhysicsScene.Params.linkConstraintSolverIterations);
426 }
377 427
378 RecomputeLinksetConstraintVariables(); 428 RecomputeLinksetConstraintVariables();
379 } 429 }
380 430
381 // Remove linkage between myself and a particular child 431 // Remove linkage between myself and a particular child
382 // Called at taint time! 432 // Called at taint time!
383 private void PhysicallyUnlinkAChildFromRoot(BSPrim rootPrim, BSPrim childPrim) 433 private void PhysicallyUnlinkAChildFromRoot(BSPhysObject rootPrim, BSPhysObject childPrim)
384 { 434 {
385 // DebugLog("{0}: PhysicallyUnlinkAChildFromRoot: RemoveConstraint between root prim {1} and child prim {2}",
386 // LogHeader, rootPrim.LocalID, childPrim.LocalID);
387 DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID); 435 DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},child={2}", rootPrim.LocalID, rootPrim.LocalID, childPrim.LocalID);
388 436
389 // Find the constraint for this link and get rid of it from the overall collection and from my list 437 // Find the constraint for this link and get rid of it from the overall collection and from my list
390 m_physicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.Body, childPrim.Body); 438 m_physicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.BSBody, childPrim.BSBody);
391 439
392 // Make the child refresh its location 440 // Make the child refresh its location
393 BulletSimAPI.PushUpdate2(childPrim.Body.Ptr); 441 BulletSimAPI.PushUpdate2(childPrim.BSBody.Ptr);
394 } 442 }
395 443
396 // Remove linkage between myself and any possible children I might have 444 // Remove linkage between myself and any possible children I might have
397 // Called at taint time! 445 // Called at taint time!
398 private void PhysicallyUnlinkAllChildrenFromRoot(BSPrim rootPrim) 446 private void PhysicallyUnlinkAllChildrenFromRoot(BSPhysObject rootPrim)
399 { 447 {
400 // DebugLog("{0}: PhysicallyUnlinkAllChildren:", LogHeader);
401 DetailLog("{0},PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID); 448 DetailLog("{0},PhysicallyUnlinkAllChildren,taint", rootPrim.LocalID);
402 449
403 m_physicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.Body); 450 m_physicsScene.Constraints.RemoveAndDestroyConstraint(rootPrim.BSBody);
404 }
405
406 // Invoke the detailed logger and output something if it's enabled.
407 private void DebugLog(string msg, params Object[] args)
408 {
409 if (m_physicsScene.ShouldDebugLog)
410 m_physicsScene.Logger.DebugFormat(msg, args);
411 } 451 }
412 452
413 // Invoke the detailed logger and output something if it's enabled. 453 // Invoke the detailed logger and output something if it's enabled.
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
new file mode 100755
index 0000000..3fe71e1
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
@@ -0,0 +1,64 @@
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 copyrightD
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 */
27using System;
28using System.Collections.Generic;
29using System.Text;
30
31using OMV = OpenMetaverse;
32using OpenSim.Framework;
33using OpenSim.Region.Physics.Manager;
34
35namespace OpenSim.Region.Physics.BulletSPlugin
36{
37// Class to wrap all objects.
38// The rest of BulletSim doesn't need to keep checking for avatars or prims
39// unless the difference is significant.
40public abstract class BSPhysObject : PhysicsActor
41{
42 public abstract BSLinkset Linkset { get; set; }
43
44 public abstract bool Collide(uint collidingWith, BSPhysObject collidee,
45 OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth);
46 public abstract void SendCollisions();
47
48 // Return the object mass without calculating it or side effects
49 public abstract float MassRaw { get; }
50
51 // Reference to the physical body (btCollisionObject) of this object
52 public abstract BulletBody BSBody { get; set; }
53 // Reference to the physical shape (btCollisionShape) of this object
54 public abstract BulletShape BSShape { get; set; }
55
56 public abstract void ZeroMotion();
57
58 public virtual void StepVehicle(float timeStep) { }
59
60 public abstract void UpdateProperties(EntityProperties entprop);
61
62 public abstract void Destroy();
63}
64}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index 9c20004..26a581f 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -37,13 +37,11 @@ using OpenSim.Region.Physics.ConvexDecompositionDotNet;
37namespace OpenSim.Region.Physics.BulletSPlugin 37namespace OpenSim.Region.Physics.BulletSPlugin
38{ 38{
39 [Serializable] 39 [Serializable]
40public sealed class BSPrim : PhysicsActor 40public sealed class BSPrim : BSPhysObject
41{ 41{
42 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 42 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
43 private static readonly string LogHeader = "[BULLETS PRIM]"; 43 private static readonly string LogHeader = "[BULLETS PRIM]";
44 44
45 private void DebugLog(string mm, params Object[] xx) { if (_scene.ShouldDebugLog) m_log.DebugFormat(mm, xx); }
46
47 private IMesh _mesh; 45 private IMesh _mesh;
48 private PrimitiveBaseShape _pbs; 46 private PrimitiveBaseShape _pbs;
49 private ShapeData.PhysicsShapeType _shapeType; 47 private ShapeData.PhysicsShapeType _shapeType;
@@ -90,23 +88,16 @@ public sealed class BSPrim : PhysicsActor
90 private float _buoyancy; 88 private float _buoyancy;
91 89
92 // Membership in a linkset is controlled by this class. 90 // Membership in a linkset is controlled by this class.
93 private BSLinkset _linkset; 91 public override BSLinkset Linkset { get; set; }
94 public BSLinkset Linkset
95 {
96 get { return _linkset; }
97 set { _linkset = value; }
98 }
99 92
100 private int _subscribedEventsMs = 0; 93 private int _subscribedEventsMs = 0;
101 private int _nextCollisionOkTime = 0; 94 private int _nextCollisionOkTime = 0;
102 long _collidingStep; 95 long _collidingStep;
103 long _collidingGroundStep; 96 long _collidingGroundStep;
97 CollisionFlags m_currentCollisionFlags = 0;
104 98
105 private BulletBody m_body; 99 public override BulletBody BSBody { get; set; }
106 public BulletBody Body { 100 public override BulletShape BSShape { get; set; }
107 get { return m_body; }
108 set { m_body = value; }
109 }
110 101
111 private BSDynamics _vehicle; 102 private BSDynamics _vehicle;
112 103
@@ -124,6 +115,7 @@ public sealed class BSPrim : PhysicsActor
124 // m_log.DebugFormat("{0}: BSPrim creation of {1}, id={2}", LogHeader, primName, localID); 115 // m_log.DebugFormat("{0}: BSPrim creation of {1}, id={2}", LogHeader, primName, localID);
125 _localID = localID; 116 _localID = localID;
126 _avName = primName; 117 _avName = primName;
118 _physicsActorType = (int)ActorTypes.Prim;
127 _scene = parent_scene; 119 _scene = parent_scene;
128 _position = pos; 120 _position = pos;
129 _size = size; 121 _size = size;
@@ -141,35 +133,37 @@ public sealed class BSPrim : PhysicsActor
141 _friction = _scene.Params.defaultFriction; // TODO: compute based on object material 133 _friction = _scene.Params.defaultFriction; // TODO: compute based on object material
142 _density = _scene.Params.defaultDensity; // TODO: compute based on object material 134 _density = _scene.Params.defaultDensity; // TODO: compute based on object material
143 _restitution = _scene.Params.defaultRestitution; 135 _restitution = _scene.Params.defaultRestitution;
144 _linkset = new BSLinkset(_scene, this); // a linkset of one 136 Linkset = new BSLinkset(Scene, this); // a linkset of one
145 _vehicle = new BSDynamics(this); // add vehicleness 137 _vehicle = new BSDynamics(Scene, this); // add vehicleness
146 _mass = CalculateMass(); 138 _mass = CalculateMass();
147 // do the actual object creation at taint time
148 DetailLog("{0},BSPrim.constructor,call", LocalID); 139 DetailLog("{0},BSPrim.constructor,call", LocalID);
140 // do the actual object creation at taint time
149 _scene.TaintedObject("BSPrim.create", delegate() 141 _scene.TaintedObject("BSPrim.create", delegate()
150 { 142 {
151 RecreateGeomAndObject(); 143 CreateGeomAndObject(true);
152 144
153 // Get the pointer to the physical body for this object. 145 // Get the pointer to the physical body for this object.
154 // At the moment, we're still letting BulletSim manage the creation and destruction 146 // At the moment, we're still letting BulletSim manage the creation and destruction
155 // of the object. Someday we'll move that into the C# code. 147 // of the object. Someday we'll move that into the C# code.
156 m_body = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID)); 148 BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID));
149 BSShape = new BulletShape(BulletSimAPI.GetCollisionShape2(BSBody.Ptr));
150 m_currentCollisionFlags = BulletSimAPI.GetCollisionFlags2(BSBody.Ptr);
157 }); 151 });
158 } 152 }
159 153
160 // called when this prim is being destroyed and we should free all the resources 154 // called when this prim is being destroyed and we should free all the resources
161 public void Destroy() 155 public override void Destroy()
162 { 156 {
163 // m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID); 157 // m_log.DebugFormat("{0}: Destroy, id={1}", LogHeader, LocalID);
164 158
165 // Undo any links between me and any other object 159 // Undo any links between me and any other object
166 BSPrim parentBefore = _linkset.LinksetRoot; 160 BSPhysObject parentBefore = Linkset.LinksetRoot;
167 int childrenBefore = _linkset.NumberOfChildren; 161 int childrenBefore = Linkset.NumberOfChildren;
168 162
169 _linkset = _linkset.RemoveMeFromLinkset(this); 163 Linkset = Linkset.RemoveMeFromLinkset(this);
170 164
171 DetailLog("{0},BSPrim.Destroy,call,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}", 165 DetailLog("{0},BSPrim.Destroy,call,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}",
172 LocalID, parentBefore.LocalID, childrenBefore, _linkset.LinksetRoot.LocalID, _linkset.NumberOfChildren); 166 LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
173 167
174 // Undo any vehicle properties 168 // Undo any vehicle properties
175 this.VehicleType = (int)Vehicle.TYPE_NONE; 169 this.VehicleType = (int)Vehicle.TYPE_NONE;
@@ -192,9 +186,10 @@ public sealed class BSPrim : PhysicsActor
192 _scene.TaintedObject("BSPrim.setSize", delegate() 186 _scene.TaintedObject("BSPrim.setSize", delegate()
193 { 187 {
194 _mass = CalculateMass(); // changing size changes the mass 188 _mass = CalculateMass(); // changing size changes the mass
195 BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, (IsPhysical ? _mass : 0f), IsPhysical); 189 // Since _size changed, the mesh needs to be rebuilt. If rebuilt, all the correct
196 // DetailLog("{0}: BSPrim.setSize: size={1}, mass={2}, physical={3}", LocalID, _size, _mass, IsPhysical); 190 // scale and margins are set.
197 RecreateGeomAndObject(); 191 CreateGeomAndObject(true);
192 DetailLog("{0}: BSPrim.setSize: size={1}, scale={2}, mass={3}, physical={4}", LocalID, _size, _scale, _mass, IsPhysical);
198 }); 193 });
199 } 194 }
200 } 195 }
@@ -204,7 +199,7 @@ public sealed class BSPrim : PhysicsActor
204 _scene.TaintedObject("BSPrim.setShape", delegate() 199 _scene.TaintedObject("BSPrim.setShape", delegate()
205 { 200 {
206 _mass = CalculateMass(); // changing the shape changes the mass 201 _mass = CalculateMass(); // changing the shape changes the mass
207 RecreateGeomAndObject(); 202 CreateGeomAndObject(false);
208 }); 203 });
209 } 204 }
210 } 205 }
@@ -232,14 +227,13 @@ public sealed class BSPrim : PhysicsActor
232 BSPrim parent = obj as BSPrim; 227 BSPrim parent = obj as BSPrim;
233 if (parent != null) 228 if (parent != null)
234 { 229 {
235 DebugLog("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, parent.LocalID); 230 BSPhysObject parentBefore = Linkset.LinksetRoot;
236 BSPrim parentBefore = _linkset.LinksetRoot; 231 int childrenBefore = Linkset.NumberOfChildren;
237 int childrenBefore = _linkset.NumberOfChildren;
238 232
239 _linkset = parent.Linkset.AddMeToLinkset(this); 233 Linkset = parent.Linkset.AddMeToLinkset(this);
240 234
241 DetailLog("{0},BSPrim.link,call,parentBefore={1}, childrenBefore=={2}, parentAfter={3}, childrenAfter={4}", 235 DetailLog("{0},BSPrim.link,call,parentBefore={1}, childrenBefore=={2}, parentAfter={3}, childrenAfter={4}",
242 LocalID, parentBefore.LocalID, childrenBefore, _linkset.LinksetRoot.LocalID, _linkset.NumberOfChildren); 236 LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
243 } 237 }
244 return; 238 return;
245 } 239 }
@@ -248,16 +242,14 @@ public sealed class BSPrim : PhysicsActor
248 public override void delink() { 242 public override void delink() {
249 // TODO: decide if this parent checking needs to happen at taint time 243 // TODO: decide if this parent checking needs to happen at taint time
250 // Race condition here: if link() and delink() in same simulation tick, the delink will not happen 244 // Race condition here: if link() and delink() in same simulation tick, the delink will not happen
251 DebugLog("{0}: delink {1}/{2}. Parent={3}", LogHeader, _avName, _localID,
252 _linkset.LinksetRoot._avName+"/"+_linkset.LinksetRoot.LocalID.ToString());
253 245
254 BSPrim parentBefore = _linkset.LinksetRoot; 246 BSPhysObject parentBefore = Linkset.LinksetRoot;
255 int childrenBefore = _linkset.NumberOfChildren; 247 int childrenBefore = Linkset.NumberOfChildren;
256 248
257 _linkset = _linkset.RemoveMeFromLinkset(this); 249 Linkset = Linkset.RemoveMeFromLinkset(this);
258 250
259 DetailLog("{0},BSPrim.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ", 251 DetailLog("{0},BSPrim.delink,parentBefore={1},childrenBefore={2},parentAfter={3},childrenAfter={4}, ",
260 LocalID, parentBefore.LocalID, childrenBefore, _linkset.LinksetRoot.LocalID, _linkset.NumberOfChildren); 252 LocalID, parentBefore.LocalID, childrenBefore, Linkset.LinksetRoot.LocalID, Linkset.NumberOfChildren);
261 return; 253 return;
262 } 254 }
263 255
@@ -265,30 +257,30 @@ public sealed class BSPrim : PhysicsActor
265 // Do it to the properties so the values get set in the physics engine. 257 // Do it to the properties so the values get set in the physics engine.
266 // Push the setting of the values to the viewer. 258 // Push the setting of the values to the viewer.
267 // Called at taint time! 259 // Called at taint time!
268 public void ZeroMotion() 260 public override void ZeroMotion()
269 { 261 {
270 _velocity = OMV.Vector3.Zero; 262 _velocity = OMV.Vector3.Zero;
271 _acceleration = OMV.Vector3.Zero; 263 _acceleration = OMV.Vector3.Zero;
272 _rotationalVelocity = OMV.Vector3.Zero; 264 _rotationalVelocity = OMV.Vector3.Zero;
273 265
274 // Zero some other properties directly into the physics engine 266 // Zero some other properties directly into the physics engine
275 BulletSimAPI.SetVelocity2(Body.Ptr, OMV.Vector3.Zero); 267 BulletSimAPI.SetLinearVelocity2(BSBody.Ptr, OMV.Vector3.Zero);
276 BulletSimAPI.SetAngularVelocity2(Body.Ptr, OMV.Vector3.Zero); 268 BulletSimAPI.SetAngularVelocity2(BSBody.Ptr, OMV.Vector3.Zero);
277 BulletSimAPI.SetInterpolation2(Body.Ptr, OMV.Vector3.Zero, OMV.Vector3.Zero); 269 BulletSimAPI.SetInterpolationVelocity2(BSBody.Ptr, OMV.Vector3.Zero, OMV.Vector3.Zero);
278 BulletSimAPI.ClearForces2(Body.Ptr); 270 BulletSimAPI.ClearForces2(BSBody.Ptr);
279 } 271 }
280 272
281 public override void LockAngularMotion(OMV.Vector3 axis) 273 public override void LockAngularMotion(OMV.Vector3 axis)
282 { 274 {
283 // DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis); 275 DetailLog("{0},BSPrim.LockAngularMotion,call,axis={1}", LocalID, axis);
284 return; 276 return;
285 } 277 }
286 278
287 public override OMV.Vector3 Position { 279 public override OMV.Vector3 Position {
288 get { 280 get {
289 if (!_linkset.IsRoot(this)) 281 if (!Linkset.IsRoot(this))
290 // child prims move around based on their parent. Need to get the latest location 282 // child prims move around based on their parent. Need to get the latest location
291 _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); 283 _position = BulletSimAPI.GetPosition2(BSBody.Ptr);
292 284
293 // don't do the GetObjectPosition for root elements because this function is called a zillion times 285 // don't do the GetObjectPosition for root elements because this function is called a zillion times
294 // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); 286 // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
@@ -299,8 +291,8 @@ public sealed class BSPrim : PhysicsActor
299 // TODO: what does it mean to set the position of a child prim?? Rebuild the constraint? 291 // TODO: what does it mean to set the position of a child prim?? Rebuild the constraint?
300 _scene.TaintedObject("BSPrim.setPosition", delegate() 292 _scene.TaintedObject("BSPrim.setPosition", delegate()
301 { 293 {
302 // DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation); 294 DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
303 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); 295 BulletSimAPI.SetTranslation2(BSBody.Ptr, _position, _orientation);
304 }); 296 });
305 } 297 }
306 } 298 }
@@ -311,23 +303,24 @@ public sealed class BSPrim : PhysicsActor
311 { 303 {
312 get 304 get
313 { 305 {
314 return _linkset.LinksetMass; 306 // return Linkset.LinksetMass;
307 return _mass;
315 } 308 }
316 } 309 }
317 310
318 // used when we only want this prim's mass and not the linkset thing 311 // used when we only want this prim's mass and not the linkset thing
319 public float MassRaw { get { return _mass; } } 312 public override float MassRaw { get { return _mass; } }
320 313
321 // Is this used? 314 // Is this used?
322 public override OMV.Vector3 CenterOfMass 315 public override OMV.Vector3 CenterOfMass
323 { 316 {
324 get { return _linkset.CenterOfMass; } 317 get { return Linkset.CenterOfMass; }
325 } 318 }
326 319
327 // Is this used? 320 // Is this used?
328 public override OMV.Vector3 GeometricCenter 321 public override OMV.Vector3 GeometricCenter
329 { 322 {
330 get { return _linkset.GeometricCenter; } 323 get { return Linkset.GeometricCenter; }
331 } 324 }
332 325
333 public override OMV.Vector3 Force { 326 public override OMV.Vector3 Force {
@@ -336,9 +329,8 @@ public sealed class BSPrim : PhysicsActor
336 _force = value; 329 _force = value;
337 _scene.TaintedObject("BSPrim.setForce", delegate() 330 _scene.TaintedObject("BSPrim.setForce", delegate()
338 { 331 {
339 // DetailLog("{0},BSPrim.setForce,taint,force={1}", LocalID, _force); 332 DetailLog("{0},BSPrim.setForce,taint,force={1}", LocalID, _force);
340 // BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force); 333 BulletSimAPI.SetObjectForce2(BSBody.Ptr, _force);
341 BulletSimAPI.SetObjectForce2(Body.Ptr, _force);
342 }); 334 });
343 } 335 }
344 } 336 }
@@ -364,14 +356,14 @@ public sealed class BSPrim : PhysicsActor
364 { 356 {
365 _scene.TaintedObject("BSPrim.VehicleFloatParam", delegate() 357 _scene.TaintedObject("BSPrim.VehicleFloatParam", delegate()
366 { 358 {
367 _vehicle.ProcessFloatVehicleParam((Vehicle)param, value, _scene.LastSimulatedTimestep); 359 _vehicle.ProcessFloatVehicleParam((Vehicle)param, value);
368 }); 360 });
369 } 361 }
370 public override void VehicleVectorParam(int param, OMV.Vector3 value) 362 public override void VehicleVectorParam(int param, OMV.Vector3 value)
371 { 363 {
372 _scene.TaintedObject("BSPrim.VehicleVectorParam", delegate() 364 _scene.TaintedObject("BSPrim.VehicleVectorParam", delegate()
373 { 365 {
374 _vehicle.ProcessVectorVehicleParam((Vehicle)param, value, _scene.LastSimulatedTimestep); 366 _vehicle.ProcessVectorVehicleParam((Vehicle)param, value);
375 }); 367 });
376 } 368 }
377 public override void VehicleRotationParam(int param, OMV.Quaternion rotation) 369 public override void VehicleRotationParam(int param, OMV.Quaternion rotation)
@@ -391,7 +383,7 @@ public sealed class BSPrim : PhysicsActor
391 383
392 // Called each simulation step to advance vehicle characteristics. 384 // Called each simulation step to advance vehicle characteristics.
393 // Called from Scene when doing simulation step so we're in taint processing time. 385 // Called from Scene when doing simulation step so we're in taint processing time.
394 public void StepVehicle(float timeStep) 386 public override void StepVehicle(float timeStep)
395 { 387 {
396 if (IsPhysical) 388 if (IsPhysical)
397 _vehicle.Step(timeStep); 389 _vehicle.Step(timeStep);
@@ -414,15 +406,15 @@ public sealed class BSPrim : PhysicsActor
414 _velocity = value; 406 _velocity = value;
415 _scene.TaintedObject("BSPrim.setVelocity", delegate() 407 _scene.TaintedObject("BSPrim.setVelocity", delegate()
416 { 408 {
417 // DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity); 409 DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity);
418 BulletSimAPI.SetObjectVelocity(_scene.WorldID, LocalID, _velocity); 410 BulletSimAPI.SetLinearVelocity2(BSBody.Ptr, _velocity);
419 }); 411 });
420 } 412 }
421 } 413 }
422 public override OMV.Vector3 Torque { 414 public override OMV.Vector3 Torque {
423 get { return _torque; } 415 get { return _torque; }
424 set { _torque = value; 416 set { _torque = value;
425 // DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, _torque); 417 DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, _torque);
426 } 418 }
427 } 419 }
428 public override float CollisionScore { 420 public override float CollisionScore {
@@ -436,10 +428,10 @@ public sealed class BSPrim : PhysicsActor
436 } 428 }
437 public override OMV.Quaternion Orientation { 429 public override OMV.Quaternion Orientation {
438 get { 430 get {
439 if (!_linkset.IsRoot(this)) 431 if (!Linkset.IsRoot(this))
440 { 432 {
441 // Children move around because tied to parent. Get a fresh value. 433 // Children move around because tied to parent. Get a fresh value.
442 _orientation = BulletSimAPI.GetObjectOrientation(_scene.WorldID, LocalID); 434 _orientation = BulletSimAPI.GetOrientation2(BSBody.Ptr);
443 } 435 }
444 return _orientation; 436 return _orientation;
445 } 437 }
@@ -449,15 +441,14 @@ public sealed class BSPrim : PhysicsActor
449 _scene.TaintedObject("BSPrim.setOrientation", delegate() 441 _scene.TaintedObject("BSPrim.setOrientation", delegate()
450 { 442 {
451 // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); 443 // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
452 // DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation); 444 DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation);
453 BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation); 445 BulletSimAPI.SetTranslation2(BSBody.Ptr, _position, _orientation);
454 }); 446 });
455 } 447 }
456 } 448 }
457 public override int PhysicsActorType { 449 public override int PhysicsActorType {
458 get { return _physicsActorType; } 450 get { return _physicsActorType; }
459 set { _physicsActorType = value; 451 set { _physicsActorType = value; }
460 }
461 } 452 }
462 public override bool IsPhysical { 453 public override bool IsPhysical {
463 get { return _isPhysical; } 454 get { return _isPhysical; }
@@ -484,30 +475,139 @@ public sealed class BSPrim : PhysicsActor
484 475
485 // Make gravity work if the object is physical and not selected 476 // Make gravity work if the object is physical and not selected
486 // No locking here because only called when it is safe 477 // No locking here because only called when it is safe
478 // There are four flags we're interested in:
479 // IsStatic: Object does not move, otherwise the object has mass and moves
480 // isSolid: other objects bounce off of this object
481 // isVolumeDetect: other objects pass through but can generate collisions
482 // collisionEvents: whether this object returns collision events
487 private void SetObjectDynamic() 483 private void SetObjectDynamic()
488 { 484 {
489 // RA: remove this for the moment. 485 // If it's becoming dynamic, it will need hullness
490 // The problem is that dynamic objects are hulls so if we are becoming physical 486 VerifyCorrectPhysicalShape();
491 // the shape has to be checked and possibly built. 487 UpdatePhysicalParameters();
492 // Maybe a VerifyCorrectPhysicalShape() routine? 488 }
493 // RecreateGeomAndObject();
494 489
490 private void UpdatePhysicalParameters()
491 {
492 /*
495 // Bullet wants static objects to have a mass of zero 493 // Bullet wants static objects to have a mass of zero
496 float mass = IsStatic ? 0f : _mass; 494 float mass = IsStatic ? 0f : _mass;
497 495
498 BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), mass); 496 BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), mass);
497 */
498 BulletSimAPI.RemoveObjectFromWorld2(Scene.World.Ptr, BSBody.Ptr);
499
500 // Set up the object physicalness (does gravity and collisions move this object)
501 MakeDynamic(IsStatic);
502
503 // Make solid or not (do things bounce off or pass through this object)
504 MakeSolid(IsSolid);
505
506 // Arrange for collisions events if the simulator wants them
507 EnableCollisions(SubscribedEvents());
508
509 BulletSimAPI.AddObjectToWorld2(Scene.World.Ptr, BSBody.Ptr);
499 510
500 // recompute any linkset parameters 511 // Recompute any linkset parameters.
501 _linkset.Refresh(this); 512 // When going from non-physical to physical, this re-enables the constraints that
513 // had been automatically disabled when the mass was set to zero.
514 Linkset.Refresh(this);
502 515
503 CollisionFlags cf = BulletSimAPI.GetCollisionFlags2(Body.Ptr); 516 DetailLog("{0},BSPrim.UpdatePhysicalParameters,taint,static={1},solid={2},mass={3}, cf={4}",
504 // DetailLog("{0},BSPrim.SetObjectDynamic,taint,static={1},solid={2},mass={3}, cf={4}", LocalID, IsStatic, IsSolid, mass, cf); 517 LocalID, IsStatic, IsSolid, _mass, m_currentCollisionFlags);
518 }
519
520 // "Making dynamic" means changing to and from static.
521 // When static, gravity does not effect the object and it is fixed in space.
522 // When dynamic, the object can fall and be pushed by others.
523 // This is independent of its 'solidness' which controls what passes through
524 // this object and what interacts with it.
525 private void MakeDynamic(bool makeStatic)
526 {
527 if (makeStatic)
528 {
529 // Become a Bullet 'static' object type
530 m_currentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_STATIC_OBJECT);
531 // Stop all movement
532 BulletSimAPI.ClearAllForces2(BSBody.Ptr);
533 // Center of mass is at the center of the object
534 BulletSimAPI.SetCenterOfMassByPosRot2(Linkset.LinksetRoot.BSBody.Ptr, _position, _orientation);
535 // Mass is zero which disables a bunch of physics stuff in Bullet
536 BulletSimAPI.SetMassProps2(BSBody.Ptr, 0f, OMV.Vector3.Zero);
537 // There is no inertia in a static object
538 BulletSimAPI.UpdateInertiaTensor2(BSBody.Ptr);
539 // There can be special things needed for implementing linksets
540 Linkset.MakeStatic(this);
541 // The activation state is 'sleeping' so Bullet will not try to act on it
542 BulletSimAPI.ForceActivationState2(BSBody.Ptr, ActivationState.ISLAND_SLEEPING);
543 }
544 else
545 {
546 // Not a Bullet static object
547 m_currentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_STATIC_OBJECT);
548
549 // Set various physical properties so internal things will get computed correctly as they are set
550 BulletSimAPI.SetFriction2(BSBody.Ptr, Scene.Params.defaultFriction);
551 BulletSimAPI.SetRestitution2(BSBody.Ptr, Scene.Params.defaultRestitution);
552 // per http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=3382
553 BulletSimAPI.SetInterpolationLinearVelocity2(BSBody.Ptr, OMV.Vector3.Zero);
554 BulletSimAPI.SetInterpolationAngularVelocity2(BSBody.Ptr, OMV.Vector3.Zero);
555 BulletSimAPI.SetInterpolationVelocity2(BSBody.Ptr, OMV.Vector3.Zero, OMV.Vector3.Zero);
556
557 // A dynamic object has mass
558 IntPtr collisionShapePtr = BulletSimAPI.GetCollisionShape2(BSBody.Ptr);
559 OMV.Vector3 inertia = BulletSimAPI.CalculateLocalInertia2(collisionShapePtr, Linkset.LinksetMass);
560 BulletSimAPI.SetMassProps2(BSBody.Ptr, _mass, inertia);
561 // Inertia is based on our new mass
562 BulletSimAPI.UpdateInertiaTensor2(BSBody.Ptr);
563
564 // Various values for simulation limits
565 BulletSimAPI.SetDamping2(BSBody.Ptr, Scene.Params.linearDamping, Scene.Params.angularDamping);
566 BulletSimAPI.SetDeactivationTime2(BSBody.Ptr, Scene.Params.deactivationTime);
567 BulletSimAPI.SetSleepingThresholds2(BSBody.Ptr, Scene.Params.linearSleepingThreshold, Scene.Params.angularSleepingThreshold);
568 BulletSimAPI.SetContactProcessingThreshold2(BSBody.Ptr, Scene.Params.contactProcessingThreshold);
569
570 // There can be special things needed for implementing linksets
571 Linkset.MakeDynamic(this);
572
573 // Force activation of the object so Bullet will act on it.
574 BulletSimAPI.Activate2(BSBody.Ptr, true);
575 }
576 }
577
578 // "Making solid" means that other object will not pass through this object.
579 private void MakeSolid(bool makeSolid)
580 {
581 if (makeSolid)
582 {
583 // Easy in Bullet -- just remove the object flag that controls collision response
584 m_currentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE);
585 }
586 else
587 {
588 m_currentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE);
589 }
590 }
591
592 // Turn on or off the flag controlling whether collision events are returned to the simulator.
593 private void EnableCollisions(bool wantsCollisionEvents)
594 {
595 if (wantsCollisionEvents)
596 {
597 m_currentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
598 }
599 else
600 {
601 m_currentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
602 }
505 } 603 }
506 604
507 // prims don't fly 605 // prims don't fly
508 public override bool Flying { 606 public override bool Flying {
509 get { return _flying; } 607 get { return _flying; }
510 set { _flying = value; } 608 set {
609 _flying = value;
610 }
511 } 611 }
512 public override bool SetAlwaysRun { 612 public override bool SetAlwaysRun {
513 get { return _setAlwaysRun; } 613 get { return _setAlwaysRun; }
@@ -558,8 +658,8 @@ public sealed class BSPrim : PhysicsActor
558 // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity); 658 // m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity);
559 _scene.TaintedObject("BSPrim.setRotationalVelocity", delegate() 659 _scene.TaintedObject("BSPrim.setRotationalVelocity", delegate()
560 { 660 {
561 // DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity); 661 DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity);
562 BulletSimAPI.SetObjectAngularVelocity(_scene.WorldID, LocalID, _rotationalVelocity); 662 BulletSimAPI.SetAngularVelocity2(BSBody.Ptr, _rotationalVelocity);
563 }); 663 });
564 } 664 }
565 } 665 }
@@ -575,8 +675,11 @@ public sealed class BSPrim : PhysicsActor
575 _buoyancy = value; 675 _buoyancy = value;
576 _scene.TaintedObject("BSPrim.setBuoyancy", delegate() 676 _scene.TaintedObject("BSPrim.setBuoyancy", delegate()
577 { 677 {
578 // DetailLog("{0},BSPrim.SetBuoyancy,taint,buoy={1}", LocalID, _buoyancy); 678 DetailLog("{0},BSPrim.SetBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
579 BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, _localID, _buoyancy); 679 // Buoyancy is faked by changing the gravity applied to the object
680 float grav = Scene.Params.gravity * (1f - _buoyancy);
681 BulletSimAPI.SetGravity2(BSBody.Ptr, new OMV.Vector3(0f, 0f, grav));
682 // BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, _localID, _buoyancy);
580 }); 683 });
581 } 684 }
582 } 685 }
@@ -624,7 +727,7 @@ public sealed class BSPrim : PhysicsActor
624 } 727 }
625 else 728 else
626 { 729 {
627 m_log.WarnFormat("{0}: Got a NaN force applied to a Character", LogHeader); 730 m_log.WarnFormat("{0}: Got a NaN force applied to a prim. LocalID={1}", LogHeader, LocalID);
628 return; 731 return;
629 } 732 }
630 _scene.TaintedObject("BSPrim.AddForce", delegate() 733 _scene.TaintedObject("BSPrim.AddForce", delegate()
@@ -638,17 +741,18 @@ public sealed class BSPrim : PhysicsActor
638 } 741 }
639 m_accumulatedForces.Clear(); 742 m_accumulatedForces.Clear();
640 } 743 }
641 // DetailLog("{0},BSPrim.AddObjectForce,taint,force={1}", LocalID, _force); 744 DetailLog("{0},BSPrim.AddObjectForce,taint,force={1}", LocalID, fSum);
642 BulletSimAPI.AddObjectForce2(Body.Ptr, fSum); 745 // For unknown reasons, "ApplyCentralForce" adds this force to the total force on the object.
746 BulletSimAPI.ApplyCentralForce2(BSBody.Ptr, fSum);
643 }); 747 });
644 } 748 }
645 749
646 public override void AddAngularForce(OMV.Vector3 force, bool pushforce) { 750 public override void AddAngularForce(OMV.Vector3 force, bool pushforce) {
647 // DetailLog("{0},BSPrim.AddAngularForce,call,angForce={1},push={2}", LocalID, force, pushforce); 751 DetailLog("{0},BSPrim.AddAngularForce,call,angForce={1},push={2}", LocalID, force, pushforce);
648 // m_log.DebugFormat("{0}: AddAngularForce. f={1}, push={2}", LogHeader, force, pushforce); 752 // m_log.DebugFormat("{0}: AddAngularForce. f={1}, push={2}", LogHeader, force, pushforce);
649 } 753 }
650 public override void SetMomentum(OMV.Vector3 momentum) { 754 public override void SetMomentum(OMV.Vector3 momentum) {
651 // DetailLog("{0},BSPrim.SetMomentum,call,mom={1}", LocalID, momentum); 755 DetailLog("{0},BSPrim.SetMomentum,call,mom={1}", LocalID, momentum);
652 } 756 }
653 public override void SubscribeEvents(int ms) { 757 public override void SubscribeEvents(int ms) {
654 _subscribedEventsMs = ms; 758 _subscribedEventsMs = ms;
@@ -659,7 +763,7 @@ public sealed class BSPrim : PhysicsActor
659 763
660 Scene.TaintedObject("BSPrim.SubscribeEvents", delegate() 764 Scene.TaintedObject("BSPrim.SubscribeEvents", delegate()
661 { 765 {
662 BulletSimAPI.AddToCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); 766 m_currentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
663 }); 767 });
664 } 768 }
665 } 769 }
@@ -667,7 +771,7 @@ public sealed class BSPrim : PhysicsActor
667 _subscribedEventsMs = 0; 771 _subscribedEventsMs = 0;
668 Scene.TaintedObject("BSPrim.UnSubscribeEvents", delegate() 772 Scene.TaintedObject("BSPrim.UnSubscribeEvents", delegate()
669 { 773 {
670 BulletSimAPI.RemoveFromCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); 774 m_currentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
671 }); 775 });
672 } 776 }
673 public override bool SubscribedEvents() { 777 public override bool SubscribedEvents() {
@@ -974,39 +1078,47 @@ public sealed class BSPrim : PhysicsActor
974 }// end CalculateMass 1078 }// end CalculateMass
975 #endregion Mass Calculation 1079 #endregion Mass Calculation
976 1080
977 // Create the geometry information in Bullet for later use 1081 // Create the geometry information in Bullet for later use.
978 // The objects needs a hull if it's physical otherwise a mesh is enough 1082 // The objects needs a hull if it's physical otherwise a mesh is enough.
979 // No locking here because this is done when we know physics is not simulating 1083 // No locking here because this is done when we know physics is not simulating.
980 // if 'forceRebuild' is true, the geometry is rebuilt. Otherwise a previously built version is used 1084 // if 'forceRebuild' is true, the geometry is rebuilt. Otherwise a previously built version is used.
981 // Returns 'true' if the geometry was rebuilt 1085 // Returns 'true' if the geometry was rebuilt.
1086 // Called at taint-time!
982 private bool CreateGeom(bool forceRebuild) 1087 private bool CreateGeom(bool forceRebuild)
983 { 1088 {
984 // the mesher thought this was too simple to mesh. Use a native Bullet collision shape.
985 bool ret = false; 1089 bool ret = false;
986 if (!_scene.NeedsMeshing(_pbs)) 1090 bool haveShape = false;
1091
1092 // If the prim attributes are simple, this could be a simple Bullet native shape
1093 if ((_pbs.SculptEntry && !Scene.ShouldMeshSculptedPrim)
1094 || (_pbs.ProfileBegin == 0 && _pbs.ProfileEnd == 0
1095 && _pbs.ProfileHollow == 0
1096 && _pbs.PathTwist == 0 && _pbs.PathTwistBegin == 0
1097 && _pbs.PathBegin == 0 && _pbs.PathEnd == 0
1098 && _pbs.PathTaperX == 0 && _pbs.PathTaperY == 0
1099 && _pbs.PathScaleX == 100 && _pbs.PathScaleY == 100
1100 && _pbs.PathShearX == 0 && _pbs.PathShearY == 0) )
987 { 1101 {
988 if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1) 1102 if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1)
989 { 1103 {
990 // if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z) 1104 haveShape = true;
991 // { 1105 if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_SPHERE))
992 // m_log.DebugFormat("{0}: CreateGeom: Defaulting to sphere of size {1}", LogHeader, _size); 1106 {
993 if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_SPHERE)) 1107 DetailLog("{0},BSPrim.CreateGeom,sphere (force={1}", LocalID, forceRebuild);
994 { 1108 _shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE;
995 // DetailLog("{0},BSPrim.CreateGeom,sphere (force={1}", LocalID, forceRebuild); 1109 // Bullet native objects are scaled by the Bullet engine so pass the size in
996 _shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE; 1110 _scale = _size;
997 // Bullet native objects are scaled by the Bullet engine so pass the size in 1111 // TODO: do we need to check for and destroy a mesh or hull that might have been left from before?
998 _scale = _size; 1112 ret = true;
999 // TODO: do we need to check for and destroy a mesh or hull that might have been left from before? 1113 }
1000 ret = true;
1001 }
1002 // }
1003 } 1114 }
1004 else 1115 else
1005 { 1116 {
1006 // m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, type={2}, size={3}", LogHeader, LocalID, _shapeType, _size); 1117 // m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, type={2}, size={3}", LogHeader, LocalID, _shapeType, _size);
1118 haveShape = true;
1007 if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_BOX)) 1119 if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_BOX))
1008 { 1120 {
1009 // DetailLog("{0},BSPrim.CreateGeom,box (force={1})", LocalID, forceRebuild); 1121 DetailLog("{0},BSPrim.CreateGeom,box (force={1})", LocalID, forceRebuild);
1010 _shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX; 1122 _shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX;
1011 _scale = _size; 1123 _scale = _size;
1012 // TODO: do we need to check for and destroy a mesh or hull that might have been left from before? 1124 // TODO: do we need to check for and destroy a mesh or hull that might have been left from before?
@@ -1014,16 +1126,16 @@ public sealed class BSPrim : PhysicsActor
1014 } 1126 }
1015 } 1127 }
1016 } 1128 }
1017 else 1129 // If a simple shape isn't happening, create a mesh and possibly a hull
1130 if (!haveShape)
1018 { 1131 {
1019 if (IsPhysical) 1132 if (IsPhysical)
1020 { 1133 {
1021 if (forceRebuild || _hullKey == 0) 1134 if (forceRebuild || _hullKey == 0)
1022 { 1135 {
1023 // physical objects require a hull for interaction. 1136 // physical objects require a hull for interaction.
1024 // This will create the mesh if it doesn't already exist 1137 // This also creates the mesh if it doesn't already exist
1025 CreateGeomHull(); 1138 ret = CreateGeomHull();
1026 ret = true;
1027 } 1139 }
1028 } 1140 }
1029 else 1141 else
@@ -1031,8 +1143,7 @@ public sealed class BSPrim : PhysicsActor
1031 if (forceRebuild || _meshKey == 0) 1143 if (forceRebuild || _meshKey == 0)
1032 { 1144 {
1033 // Static (non-physical) objects only need a mesh for bumping into 1145 // Static (non-physical) objects only need a mesh for bumping into
1034 CreateGeomMesh(); 1146 ret = CreateGeomMesh();
1035 ret = true;
1036 } 1147 }
1037 } 1148 }
1038 } 1149 }
@@ -1040,21 +1151,30 @@ public sealed class BSPrim : PhysicsActor
1040 } 1151 }
1041 1152
1042 // No locking here because this is done when we know physics is not simulating 1153 // No locking here because this is done when we know physics is not simulating
1043 private void CreateGeomMesh() 1154 // Returns 'true' of a mesh was actually rebuild (we could also have one of these specs).
1155 // Called at taint-time!
1156 private bool CreateGeomMesh()
1044 { 1157 {
1045 float lod = _pbs.SculptEntry ? _scene.SculptLOD : _scene.MeshLOD; 1158 // level of detail based on size and type of the object
1159 float lod = _scene.MeshLOD;
1160 if (_pbs.SculptEntry)
1161 lod = _scene.SculptLOD;
1162 float maxAxis = Math.Max(_size.X, Math.Max(_size.Y, _size.Z));
1163 if (maxAxis > _scene.MeshMegaPrimThreshold)
1164 lod = _scene.MeshMegaPrimLOD;
1165
1046 ulong newMeshKey = (ulong)_pbs.GetMeshKey(_size, lod); 1166 ulong newMeshKey = (ulong)_pbs.GetMeshKey(_size, lod);
1047 // m_log.DebugFormat("{0}: CreateGeomMesh: lID={1}, oldKey={2}, newKey={3}", LogHeader, _localID, _meshKey, newMeshKey); 1167 // m_log.DebugFormat("{0}: CreateGeomMesh: lID={1}, oldKey={2}, newKey={3}", LogHeader, _localID, _meshKey, newMeshKey);
1048 1168
1049 // if this new shape is the same as last time, don't recreate the mesh 1169 // if this new shape is the same as last time, don't recreate the mesh
1050 if (_meshKey == newMeshKey) return; 1170 if (_meshKey == newMeshKey) return false;
1051 1171
1052 // DetailLog("{0},BSPrim.CreateGeomMesh,create,key={1}", LocalID, newMeshKey); 1172 DetailLog("{0},BSPrim.CreateGeomMesh,create,key={1}", LocalID, newMeshKey);
1053 // Since we're recreating new, get rid of any previously generated shape 1173 // Since we're recreating new, get rid of any previously generated shape
1054 if (_meshKey != 0) 1174 if (_meshKey != 0)
1055 { 1175 {
1056 // m_log.DebugFormat("{0}: CreateGeom: deleting old mesh. lID={1}, Key={2}", LogHeader, _localID, _meshKey); 1176 // m_log.DebugFormat("{0}: CreateGeom: deleting old mesh. lID={1}, Key={2}", LogHeader, _localID, _meshKey);
1057 // DetailLog("{0},BSPrim.CreateGeomMesh,deleteOld,key={1}", LocalID, _meshKey); 1177 DetailLog("{0},BSPrim.CreateGeomMesh,deleteOld,key={1}", LocalID, _meshKey);
1058 BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey); 1178 BulletSimAPI.DestroyMesh(_scene.WorldID, _meshKey);
1059 _mesh = null; 1179 _mesh = null;
1060 _meshKey = 0; 1180 _meshKey = 0;
@@ -1084,27 +1204,27 @@ public sealed class BSPrim : PhysicsActor
1084 _shapeType = ShapeData.PhysicsShapeType.SHAPE_MESH; 1204 _shapeType = ShapeData.PhysicsShapeType.SHAPE_MESH;
1085 // meshes are already scaled by the meshmerizer 1205 // meshes are already scaled by the meshmerizer
1086 _scale = new OMV.Vector3(1f, 1f, 1f); 1206 _scale = new OMV.Vector3(1f, 1f, 1f);
1087 // DetailLog("{0},BSPrim.CreateGeomMesh,done", LocalID); 1207 return true;
1088 return;
1089 } 1208 }
1090 1209
1091 // No locking here because this is done when we know physics is not simulating 1210 // No locking here because this is done when we know physics is not simulating
1092 private void CreateGeomHull() 1211 // Returns 'true' of a mesh was actually rebuild (we could also have one of these specs).
1212 private bool CreateGeomHull()
1093 { 1213 {
1094 float lod = _pbs.SculptEntry ? _scene.SculptLOD : _scene.MeshLOD; 1214 float lod = _pbs.SculptEntry ? _scene.SculptLOD : _scene.MeshLOD;
1095 ulong newHullKey = (ulong)_pbs.GetMeshKey(_size, lod); 1215 ulong newHullKey = (ulong)_pbs.GetMeshKey(_size, lod);
1096 // m_log.DebugFormat("{0}: CreateGeomHull: lID={1}, oldKey={2}, newKey={3}", LogHeader, _localID, _hullKey, newHullKey); 1216 // m_log.DebugFormat("{0}: CreateGeomHull: lID={1}, oldKey={2}, newKey={3}", LogHeader, _localID, _hullKey, newHullKey);
1097 1217
1098 // if the hull hasn't changed, don't rebuild it 1218 // if the hull hasn't changed, don't rebuild it
1099 if (newHullKey == _hullKey) return; 1219 if (newHullKey == _hullKey) return false;
1100 1220
1101 // DetailLog("{0},BSPrim.CreateGeomHull,create,oldKey={1},newKey={2}", LocalID, _hullKey, newHullKey); 1221 DetailLog("{0},BSPrim.CreateGeomHull,create,oldKey={1},newKey={2}", LocalID, _hullKey, newHullKey);
1102 1222
1103 // Since we're recreating new, get rid of any previously generated shape 1223 // Since we're recreating new, get rid of any previously generated shape
1104 if (_hullKey != 0) 1224 if (_hullKey != 0)
1105 { 1225 {
1106 // m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _hullKey); 1226 // m_log.DebugFormat("{0}: CreateGeom: deleting old hull. Key={1}", LogHeader, _hullKey);
1107 // DetailLog("{0},BSPrim.CreateGeomHull,deleteOldHull,key={1}", LocalID, _hullKey); 1227 DetailLog("{0},BSPrim.CreateGeomHull,deleteOldHull,key={1}", LocalID, _hullKey);
1108 BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey); 1228 BulletSimAPI.DestroyHull(_scene.WorldID, _hullKey);
1109 _hullKey = 0; 1229 _hullKey = 0;
1110 } 1230 }
@@ -1198,8 +1318,8 @@ public sealed class BSPrim : PhysicsActor
1198 _shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL; 1318 _shapeType = ShapeData.PhysicsShapeType.SHAPE_HULL;
1199 // meshes are already scaled by the meshmerizer 1319 // meshes are already scaled by the meshmerizer
1200 _scale = new OMV.Vector3(1f, 1f, 1f); 1320 _scale = new OMV.Vector3(1f, 1f, 1f);
1201 // DetailLog("{0},BSPrim.CreateGeomHull,done", LocalID); 1321 DetailLog("{0},BSPrim.CreateGeomHull,done", LocalID);
1202 return; 1322 return true;
1203 } 1323 }
1204 1324
1205 // Callback from convex hull creater with a newly created hull. 1325 // Callback from convex hull creater with a newly created hull.
@@ -1210,6 +1330,19 @@ public sealed class BSPrim : PhysicsActor
1210 return; 1330 return;
1211 } 1331 }
1212 1332
1333 private void VerifyCorrectPhysicalShape()
1334 {
1335 if (!IsStatic)
1336 {
1337 // if not static, it will need a hull to efficiently collide with things
1338 if (_hullKey == 0)
1339 {
1340 CreateGeomAndObject(false);
1341 }
1342
1343 }
1344 }
1345
1213 // Create an object in Bullet if it has not already been created 1346 // Create an object in Bullet if it has not already been created
1214 // No locking here because this is done when the physics engine is not simulating 1347 // No locking here because this is done when the physics engine is not simulating
1215 // Returns 'true' if an object was actually created. 1348 // Returns 'true' if an object was actually created.
@@ -1223,8 +1356,9 @@ public sealed class BSPrim : PhysicsActor
1223 // m_log.DebugFormat("{0}: CreateObject: lID={1}, shape={2}", LogHeader, _localID, shape.Type); 1356 // m_log.DebugFormat("{0}: CreateObject: lID={1}, shape={2}", LogHeader, _localID, shape.Type);
1224 bool ret = BulletSimAPI.CreateObject(_scene.WorldID, shape); 1357 bool ret = BulletSimAPI.CreateObject(_scene.WorldID, shape);
1225 1358
1226 // the CreateObject() may have recreated the rigid body. Make sure we have the latest. 1359 // the CreateObject() may have recreated the rigid body. Make sure we have the latest address.
1227 Body = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID)); 1360 BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID));
1361 BSShape = new BulletShape(BulletSimAPI.GetCollisionShape2(BSBody.Ptr));
1228 1362
1229 return ret; 1363 return ret;
1230 } 1364 }
@@ -1248,15 +1382,20 @@ public sealed class BSPrim : PhysicsActor
1248 shape.Static = _isPhysical ? ShapeData.numericFalse : ShapeData.numericTrue; 1382 shape.Static = _isPhysical ? ShapeData.numericFalse : ShapeData.numericTrue;
1249 } 1383 }
1250 1384
1251
1252 // Rebuild the geometry and object. 1385 // Rebuild the geometry and object.
1253 // This is called when the shape changes so we need to recreate the mesh/hull. 1386 // This is called when the shape changes so we need to recreate the mesh/hull.
1254 // No locking here because this is done when the physics engine is not simulating 1387 // No locking here because this is done when the physics engine is not simulating
1255 private void RecreateGeomAndObject() 1388 private void CreateGeomAndObject(bool forceRebuild)
1256 { 1389 {
1257 // m_log.DebugFormat("{0}: RecreateGeomAndObject. lID={1}", LogHeader, _localID); 1390 // m_log.DebugFormat("{0}: CreateGeomAndObject. lID={1}, force={2}", LogHeader, _localID, forceRebuild);
1258 if (CreateGeom(true)) 1391 // Create the geometry that will make up the object
1392 if (CreateGeom(forceRebuild))
1393 {
1394 // Create the object and place it into the world
1259 CreateObject(); 1395 CreateObject();
1396 // Make sure the properties are set on the new object
1397 UpdatePhysicalParameters();
1398 }
1260 return; 1399 return;
1261 } 1400 }
1262 1401
@@ -1277,7 +1416,7 @@ public sealed class BSPrim : PhysicsActor
1277 const float ACCELERATION_TOLERANCE = 0.01f; 1416 const float ACCELERATION_TOLERANCE = 0.01f;
1278 const float ROTATIONAL_VELOCITY_TOLERANCE = 0.01f; 1417 const float ROTATIONAL_VELOCITY_TOLERANCE = 0.01f;
1279 1418
1280 public void UpdateProperties(EntityProperties entprop) 1419 public override void UpdateProperties(EntityProperties entprop)
1281 { 1420 {
1282 /* 1421 /*
1283 UpdatedProperties changed = 0; 1422 UpdatedProperties changed = 0;
@@ -1325,7 +1464,7 @@ public sealed class BSPrim : PhysicsActor
1325 // Don't check for damping here -- it's done in BulletSim and SceneObjectPart. 1464 // Don't check for damping here -- it's done in BulletSim and SceneObjectPart.
1326 1465
1327 // Updates only for individual prims and for the root object of a linkset. 1466 // Updates only for individual prims and for the root object of a linkset.
1328 if (_linkset.IsRoot(this)) 1467 if (Linkset.IsRoot(this))
1329 { 1468 {
1330 // Assign to the local variables so the normal set action does not happen 1469 // Assign to the local variables so the normal set action does not happen
1331 _position = entprop.Position; 1470 _position = entprop.Position;
@@ -1334,17 +1473,17 @@ public sealed class BSPrim : PhysicsActor
1334 _acceleration = entprop.Acceleration; 1473 _acceleration = entprop.Acceleration;
1335 _rotationalVelocity = entprop.RotationalVelocity; 1474 _rotationalVelocity = entprop.RotationalVelocity;
1336 1475
1337 // m_log.DebugFormat("{0}: RequestTerseUpdate. id={1}, ch={2}, pos={3}, rot={4}, vel={5}, acc={6}, rvel={7}", 1476 DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
1338 // LogHeader, LocalID, changed, _position, _orientation, _velocity, _acceleration, _rotationalVelocity); 1477 LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity);
1339 // DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", 1478
1340 // LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity); 1479 // BulletSimAPI.DumpRigidBody2(Scene.World.Ptr, BSBody.Ptr);
1341 1480
1342 base.RequestPhysicsterseUpdate(); 1481 base.RequestPhysicsterseUpdate();
1343 } 1482 }
1344 /* 1483 /*
1345 else 1484 else
1346 { 1485 {
1347 // For debugging, we also report the movement of children 1486 // For debugging, we can also report the movement of children
1348 DetailLog("{0},BSPrim.UpdateProperties,child,pos={1},orient={2},vel={3},accel={4},rotVel={5}", 1487 DetailLog("{0},BSPrim.UpdateProperties,child,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
1349 LocalID, entprop.Position, entprop.Rotation, entprop.Velocity, 1488 LocalID, entprop.Position, entprop.Rotation, entprop.Velocity,
1350 entprop.Acceleration, entprop.RotationalVelocity); 1489 entprop.Acceleration, entprop.RotationalVelocity);
@@ -1353,36 +1492,45 @@ public sealed class BSPrim : PhysicsActor
1353 } 1492 }
1354 1493
1355 // I've collided with something 1494 // I've collided with something
1495 // Called at taint time from within the Step() function
1356 CollisionEventUpdate collisionCollection; 1496 CollisionEventUpdate collisionCollection;
1357 public void Collide(uint collidingWith, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) 1497 public override bool Collide(uint collidingWith, BSPhysObject collidee, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
1358 { 1498 {
1359 // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith); 1499 bool ret = false;
1360 1500
1361 // The following lines make IsColliding() and IsCollidingGround() work 1501 // The following lines make IsColliding() and IsCollidingGround() work
1362 _collidingStep = _scene.SimulationStep; 1502 _collidingStep = Scene.SimulationStep;
1363 if (collidingWith == BSScene.TERRAIN_ID || collidingWith == BSScene.GROUNDPLANE_ID) 1503 if (collidingWith <= Scene.TerrainManager.HighestTerrainID)
1364 { 1504 {
1365 _collidingGroundStep = _scene.SimulationStep; 1505 _collidingGroundStep = Scene.SimulationStep;
1366 } 1506 }
1367 1507
1368 // DetailLog("{0},BSPrim.Collison,call,with={1}", LocalID, collidingWith); 1508 // DetailLog("{0},BSPrim.Collison,call,with={1}", LocalID, collidingWith);
1369 1509
1370 // if someone is subscribed to collision events.... 1510 // prims in the same linkset cannot collide with each other
1371 if (_subscribedEventsMs != 0) { 1511 if (collidee != null && (this.Linkset.LinksetID == collidee.Linkset.LinksetID))
1512 {
1513 return ret;
1514 }
1515
1516 // if someone has subscribed for collision events....
1517 if (SubscribedEvents()) {
1372 // throttle the collisions to the number of milliseconds specified in the subscription 1518 // throttle the collisions to the number of milliseconds specified in the subscription
1373 int nowTime = _scene.SimulationNowTime; 1519 int nowTime = Scene.SimulationNowTime;
1374 if (nowTime >= _nextCollisionOkTime) { 1520 if (nowTime >= _nextCollisionOkTime) {
1375 _nextCollisionOkTime = nowTime + _subscribedEventsMs; 1521 _nextCollisionOkTime = nowTime + _subscribedEventsMs;
1376 1522
1377 if (collisionCollection == null) 1523 if (collisionCollection == null)
1378 collisionCollection = new CollisionEventUpdate(); 1524 collisionCollection = new CollisionEventUpdate();
1379 collisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); 1525 collisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
1526 ret = true;
1380 } 1527 }
1381 } 1528 }
1529 return ret;
1382 } 1530 }
1383 1531
1384 // The scene is telling us it's time to pass our collected collisions into the simulator 1532 // The scene is telling us it's time to pass our collected collisions into the simulator
1385 public void SendCollisions() 1533 public override void SendCollisions()
1386 { 1534 {
1387 if (collisionCollection != null && collisionCollection.Count > 0) 1535 if (collisionCollection != null && collisionCollection.Count > 0)
1388 { 1536 {
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index a31c578..52997dd 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -39,8 +39,6 @@ using log4net;
39using OpenMetaverse; 39using OpenMetaverse;
40 40
41// TODOs for BulletSim (for BSScene, BSPrim, BSCharacter and BulletSim) 41// TODOs for BulletSim (for BSScene, BSPrim, BSCharacter and BulletSim)
42// Debug linkset
43// Test with multiple regions in one simulator
44// Adjust character capsule size when height is adjusted (ScenePresence.SetHeight) 42// Adjust character capsule size when height is adjusted (ScenePresence.SetHeight)
45// Test sculpties 43// Test sculpties
46// Compute physics FPS reasonably 44// Compute physics FPS reasonably
@@ -54,13 +52,10 @@ using OpenMetaverse;
54// Use collision masks for collision with terrain and phantom objects 52// Use collision masks for collision with terrain and phantom objects
55// Check out llVolumeDetect. Must do something for that. 53// Check out llVolumeDetect. Must do something for that.
56// Should prim.link() and prim.delink() membership checking happen at taint time? 54// Should prim.link() and prim.delink() membership checking happen at taint time?
57// changing the position and orientation of a linked prim must rebuild the constraint with the root.
58// Mesh sharing. Use meshHash to tell if we already have a hull of that shape and only create once 55// Mesh sharing. Use meshHash to tell if we already have a hull of that shape and only create once
59// Do attachments need to be handled separately? Need collision events. Do not collide with VolumeDetect 56// Do attachments need to be handled separately? Need collision events. Do not collide with VolumeDetect
60// Implement the genCollisions feature in BulletSim::SetObjectProperties (don't pass up unneeded collisions)
61// Implement LockAngularMotion 57// Implement LockAngularMotion
62// Decide if clearing forces is the right thing to do when setting position (BulletSim::SetObjectTranslation) 58// Decide if clearing forces is the right thing to do when setting position (BulletSim::SetObjectTranslation)
63// Does NeedsMeshing() really need to exclude all the different shapes?
64// Remove mesh and Hull stuff. Use mesh passed to bullet and use convexdecom from bullet. 59// Remove mesh and Hull stuff. Use mesh passed to bullet and use convexdecom from bullet.
65// Add PID movement operations. What does ScenePresence.MoveToTarget do? 60// Add PID movement operations. What does ScenePresence.MoveToTarget do?
66// Check terrain size. 128 or 127? 61// Check terrain size. 128 or 127?
@@ -73,62 +68,56 @@ public class BSScene : PhysicsScene, IPhysicsParameters
73 private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 68 private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
74 private static readonly string LogHeader = "[BULLETS SCENE]"; 69 private static readonly string LogHeader = "[BULLETS SCENE]";
75 70
76 public void DebugLog(string mm, params Object[] xx) { if (ShouldDebugLog) m_log.DebugFormat(mm, xx); } 71 // The name of the region we're working for.
72 public string RegionName { get; private set; }
77 73
78 public string BulletSimVersion = "?"; 74 public string BulletSimVersion = "?";
79 75
80 private Dictionary<uint, BSCharacter> m_avatars = new Dictionary<uint, BSCharacter>(); 76 public Dictionary<uint, BSPhysObject> PhysObjects = new Dictionary<uint, BSPhysObject>();
81 private Dictionary<uint, BSPrim> m_prims = new Dictionary<uint, BSPrim>(); 77
82 private HashSet<BSCharacter> m_avatarsWithCollisions = new HashSet<BSCharacter>(); 78 private HashSet<BSPhysObject> m_objectsWithCollisions = new HashSet<BSPhysObject>();
83 private HashSet<BSPrim> m_primsWithCollisions = new HashSet<BSPrim>(); 79 // Following is a kludge and can be removed when avatar animation updating is
84 private List<BSPrim> m_vehicles = new List<BSPrim>(); 80 // moved to a better place.
85 private float[] m_heightMap; 81 private HashSet<BSPhysObject> m_avatarsWithCollisions = new HashSet<BSPhysObject>();
86 private float m_waterLevel; 82
87 private uint m_worldID; 83 // List of all the objects that have vehicle properties and should be called
88 public uint WorldID { get { return m_worldID; } } 84 // to update each physics step.
85 private List<BSPhysObject> m_vehicles = new List<BSPhysObject>();
89 86
90 // let my minuions use my logger 87 // let my minuions use my logger
91 public ILog Logger { get { return m_log; } } 88 public ILog Logger { get { return m_log; } }
92 89
93 private bool m_initialized = false; 90 // If non-zero, the number of simulation steps between calls to the physics
94 91 // engine to output detailed physics stats. Debug logging level must be on also.
95 private int m_detailedStatsStep = 0; 92 private int m_detailedStatsStep = 0;
96 93
97 public IMesher mesher; 94 public IMesher mesher;
98 private float m_meshLOD; 95 // Level of Detail values kept as float because that's what the Meshmerizer wants
99 public float MeshLOD 96 public float MeshLOD { get; private set; }
100 { 97 public float MeshMegaPrimLOD { get; private set; }
101 get { return m_meshLOD; } 98 public float MeshMegaPrimThreshold { get; private set; }
102 } 99 public float SculptLOD { get; private set; }
103 private float m_sculptLOD;
104 public float SculptLOD
105 {
106 get { return m_sculptLOD; }
107 }
108 100
109 private BulletSim m_worldSim; 101 public uint WorldID { get; private set; }
110 public BulletSim World 102 public BulletSim World { get; private set; }
111 {
112 get { return m_worldSim; }
113 }
114 private BSConstraintCollection m_constraintCollection;
115 public BSConstraintCollection Constraints
116 {
117 get { return m_constraintCollection; }
118 }
119 103
104 // All the constraints that have been allocated in this instance.
105 public BSConstraintCollection Constraints { get; private set; }
106
107 // Simulation parameters
120 private int m_maxSubSteps; 108 private int m_maxSubSteps;
121 private float m_fixedTimeStep; 109 private float m_fixedTimeStep;
122 private long m_simulationStep = 0; 110 private long m_simulationStep = 0;
123 public long SimulationStep { get { return m_simulationStep; } } 111 public long SimulationStep { get { return m_simulationStep; } }
124 112
125 public float LastSimulatedTimestep { get; private set; }
126
127 // A value of the time now so all the collision and update routines do not have to get their own 113 // A value of the time now so all the collision and update routines do not have to get their own
128 // Set to 'now' just before all the prims and actors are called for collisions and updates 114 // Set to 'now' just before all the prims and actors are called for collisions and updates
129 private int m_simulationNowTime; 115 public int SimulationNowTime { get; private set; }
130 public int SimulationNowTime { get { return m_simulationNowTime; } } 116
117 // True if initialized and ready to do simulation steps
118 private bool m_initialized = false;
131 119
120 // Pinned memory used to pass step information between managed and unmanaged
132 private int m_maxCollisionsPerFrame; 121 private int m_maxCollisionsPerFrame;
133 private CollisionDesc[] m_collisionArray; 122 private CollisionDesc[] m_collisionArray;
134 private GCHandle m_collisionArrayPinnedHandle; 123 private GCHandle m_collisionArrayPinnedHandle;
@@ -137,14 +126,18 @@ public class BSScene : PhysicsScene, IPhysicsParameters
137 private EntityProperties[] m_updateArray; 126 private EntityProperties[] m_updateArray;
138 private GCHandle m_updateArrayPinnedHandle; 127 private GCHandle m_updateArrayPinnedHandle;
139 128
140 private bool _meshSculptedPrim = true; // cause scuplted prims to get meshed 129 public bool ShouldMeshSculptedPrim { get; private set; } // cause scuplted prims to get meshed
141 private bool _forceSimplePrimMeshing = false; // if a cube or sphere, let Bullet do internal shapes 130 public bool ShouldForceSimplePrimMeshing { get; private set; } // if a cube or sphere, let Bullet do internal shapes
142 131
143 public float PID_D { get; private set; } // derivative 132 public float PID_D { get; private set; } // derivative
144 public float PID_P { get; private set; } // proportional 133 public float PID_P { get; private set; } // proportional
145 134
146 public const uint TERRAIN_ID = 0; // OpenSim senses terrain with a localID of zero 135 public const uint TERRAIN_ID = 0; // OpenSim senses terrain with a localID of zero
147 public const uint GROUNDPLANE_ID = 1; 136 public const uint GROUNDPLANE_ID = 1;
137 public const uint CHILDTERRAIN_ID = 2; // Terrain allocated based on our mega-prim childre start here
138
139 private float m_waterLevel;
140 public BSTerrainManager TerrainManager { get; private set; }
148 141
149 public ConfigurationParameters Params 142 public ConfigurationParameters Params
150 { 143 {
@@ -154,13 +147,18 @@ public class BSScene : PhysicsScene, IPhysicsParameters
154 { 147 {
155 get { return new Vector3(0f, 0f, Params.gravity); } 148 get { return new Vector3(0f, 0f, Params.gravity); }
156 } 149 }
157 150 // Just the Z value of the gravity
158 private float m_maximumObjectMass; 151 public float DefaultGravityZ
159 public float MaximumObjectMass
160 { 152 {
161 get { return m_maximumObjectMass; } 153 get { return Params.gravity; }
162 } 154 }
163 155
156 public float MaximumObjectMass { get; private set; }
157
158 // When functions in the unmanaged code must be called, it is only
159 // done at a known time just before the simulation step. The taint
160 // system saves all these function calls and executes them in
161 // order before the simulation.
164 public delegate void TaintCallback(); 162 public delegate void TaintCallback();
165 private struct TaintCallbackEntry 163 private struct TaintCallbackEntry
166 { 164 {
@@ -172,15 +170,17 @@ public class BSScene : PhysicsScene, IPhysicsParameters
172 callback = c; 170 callback = c;
173 } 171 }
174 } 172 }
173 private Object _taintLock = new Object(); // lock for using the next object
175 private List<TaintCallbackEntry> _taintedObjects; 174 private List<TaintCallbackEntry> _taintedObjects;
176 private Object _taintLock = new Object();
177 175
178 // A pointer to an instance if this structure is passed to the C++ code 176 // A pointer to an instance if this structure is passed to the C++ code
177 // Used to pass basic configuration values to the unmanaged code.
179 ConfigurationParameters[] m_params; 178 ConfigurationParameters[] m_params;
180 GCHandle m_paramsHandle; 179 GCHandle m_paramsHandle;
181 180
182 public bool ShouldDebugLog { get; private set; } 181 // Handle to the callback used by the unmanaged code to call into the managed code.
183 182 // Used for debug logging.
183 // Need to store the handle in a persistant variable so it won't be freed.
184 private BulletSimAPI.DebugLogCallback m_DebugLogCallbackHandle; 184 private BulletSimAPI.DebugLogCallback m_DebugLogCallbackHandle;
185 185
186 // Sometimes you just have to log everything. 186 // Sometimes you just have to log everything.
@@ -189,13 +189,15 @@ public class BSScene : PhysicsScene, IPhysicsParameters
189 private string m_physicsLoggingDir; 189 private string m_physicsLoggingDir;
190 private string m_physicsLoggingPrefix; 190 private string m_physicsLoggingPrefix;
191 private int m_physicsLoggingFileMinutes; 191 private int m_physicsLoggingFileMinutes;
192 // 'true' of the vehicle code is to log lots of details
193 public bool VehicleLoggingEnabled { get; private set; }
192 194
193 private bool m_vehicleLoggingEnabled; 195 #region Construction and Initialization
194 public bool VehicleLoggingEnabled { get { return m_vehicleLoggingEnabled; } }
195
196 public BSScene(string identifier) 196 public BSScene(string identifier)
197 { 197 {
198 m_initialized = false; 198 m_initialized = false;
199 // we are passed the name of the region we're working for.
200 RegionName = identifier;
199 } 201 }
200 202
201 public override void Initialise(IMesher meshmerizer, IConfigSource config) 203 public override void Initialise(IMesher meshmerizer, IConfigSource config)
@@ -213,6 +215,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters
213 m_updateArray = new EntityProperties[m_maxUpdatesPerFrame]; 215 m_updateArray = new EntityProperties[m_maxUpdatesPerFrame];
214 m_updateArrayPinnedHandle = GCHandle.Alloc(m_updateArray, GCHandleType.Pinned); 216 m_updateArrayPinnedHandle = GCHandle.Alloc(m_updateArray, GCHandleType.Pinned);
215 217
218 mesher = meshmerizer;
219 _taintedObjects = new List<TaintCallbackEntry>();
220
216 // Enable very detailed logging. 221 // Enable very detailed logging.
217 // By creating an empty logger when not logging, the log message invocation code 222 // By creating an empty logger when not logging, the log message invocation code
218 // can be left in and every call doesn't have to check for null. 223 // can be left in and every call doesn't have to check for null.
@@ -225,38 +230,43 @@ public class BSScene : PhysicsScene, IPhysicsParameters
225 PhysicsLogging = new Logging.LogWriter(); 230 PhysicsLogging = new Logging.LogWriter();
226 } 231 }
227 232
228 // Get the version of the DLL 233 // If Debug logging level, enable logging from the unmanaged code
229 // TODO: this doesn't work yet. Something wrong with marshaling the returned string. 234 m_DebugLogCallbackHandle = null;
230 // BulletSimVersion = BulletSimAPI.GetVersion();
231 // m_log.WarnFormat("{0}: BulletSim.dll version='{1}'", LogHeader, BulletSimVersion);
232
233 // if Debug, enable logging from the unmanaged code
234 if (m_log.IsDebugEnabled || PhysicsLogging.Enabled) 235 if (m_log.IsDebugEnabled || PhysicsLogging.Enabled)
235 { 236 {
236 m_log.DebugFormat("{0}: Initialize: Setting debug callback for unmanaged code", LogHeader); 237 m_log.DebugFormat("{0}: Initialize: Setting debug callback for unmanaged code", LogHeader);
237 if (PhysicsLogging.Enabled) 238 if (PhysicsLogging.Enabled)
239 // The handle is saved in a variable to make sure it doesn't get freed after this call
238 m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLoggerPhysLog); 240 m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLoggerPhysLog);
239 else 241 else
240 m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLogger); 242 m_DebugLogCallbackHandle = new BulletSimAPI.DebugLogCallback(BulletLogger);
241 // the handle is saved in a variable to make sure it doesn't get freed after this call
242 BulletSimAPI.SetDebugLogCallback(m_DebugLogCallbackHandle);
243 } 243 }
244 244
245 _taintedObjects = new List<TaintCallbackEntry>(); 245 // Get the version of the DLL
246 // TODO: this doesn't work yet. Something wrong with marshaling the returned string.
247 // BulletSimVersion = BulletSimAPI.GetVersion();
248 // m_log.WarnFormat("{0}: BulletSim.dll version='{1}'", LogHeader, BulletSimVersion);
246 249
247 mesher = meshmerizer; 250 // The bounding box for the simulated world. The origin is 0,0,0 unless we're
248 // The bounding box for the simulated world 251 // a child in a mega-region.
252 // Turns out that Bullet really doesn't care about the extents of the simulated
253 // area. It tracks active objects no matter where they are.
249 Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, 8192f); 254 Vector3 worldExtent = new Vector3(Constants.RegionSize, Constants.RegionSize, 8192f);
250 255
251 // m_log.DebugFormat("{0}: Initialize: Calling BulletSimAPI.Initialize.", LogHeader); 256 // m_log.DebugFormat("{0}: Initialize: Calling BulletSimAPI.Initialize.", LogHeader);
252 m_worldID = BulletSimAPI.Initialize(worldExtent, m_paramsHandle.AddrOfPinnedObject(), 257 WorldID = BulletSimAPI.Initialize(worldExtent, m_paramsHandle.AddrOfPinnedObject(),
253 m_maxCollisionsPerFrame, m_collisionArrayPinnedHandle.AddrOfPinnedObject(), 258 m_maxCollisionsPerFrame, m_collisionArrayPinnedHandle.AddrOfPinnedObject(),
254 m_maxUpdatesPerFrame, m_updateArrayPinnedHandle.AddrOfPinnedObject()); 259 m_maxUpdatesPerFrame, m_updateArrayPinnedHandle.AddrOfPinnedObject(),
260 m_DebugLogCallbackHandle);
255 261
256 // Initialization to support the transition to a new API which puts most of the logic 262 // Initialization to support the transition to a new API which puts most of the logic
257 // into the C# code so it is easier to modify and add to. 263 // into the C# code so it is easier to modify and add to.
258 m_worldSim = new BulletSim(m_worldID, this, BulletSimAPI.GetSimHandle2(m_worldID)); 264 World = new BulletSim(WorldID, this, BulletSimAPI.GetSimHandle2(WorldID));
259 m_constraintCollection = new BSConstraintCollection(World); 265
266 Constraints = new BSConstraintCollection(World);
267
268 TerrainManager = new BSTerrainManager(this);
269 TerrainManager.CreateInitialGroundPlaneAndTerrain();
260 270
261 m_initialized = true; 271 m_initialized = true;
262 } 272 }
@@ -281,10 +291,13 @@ public class BSScene : PhysicsScene, IPhysicsParameters
281 // Very detailed logging for physics debugging 291 // Very detailed logging for physics debugging
282 m_physicsLoggingEnabled = pConfig.GetBoolean("PhysicsLoggingEnabled", false); 292 m_physicsLoggingEnabled = pConfig.GetBoolean("PhysicsLoggingEnabled", false);
283 m_physicsLoggingDir = pConfig.GetString("PhysicsLoggingDir", "."); 293 m_physicsLoggingDir = pConfig.GetString("PhysicsLoggingDir", ".");
284 m_physicsLoggingPrefix = pConfig.GetString("PhysicsLoggingPrefix", "physics-"); 294 m_physicsLoggingPrefix = pConfig.GetString("PhysicsLoggingPrefix", "physics-%REGIONNAME%-");
285 m_physicsLoggingFileMinutes = pConfig.GetInt("PhysicsLoggingFileMinutes", 5); 295 m_physicsLoggingFileMinutes = pConfig.GetInt("PhysicsLoggingFileMinutes", 5);
286 // Very detailed logging for vehicle debugging 296 // Very detailed logging for vehicle debugging
287 m_vehicleLoggingEnabled = pConfig.GetBoolean("VehicleLoggingEnabled", false); 297 VehicleLoggingEnabled = pConfig.GetBoolean("VehicleLoggingEnabled", false);
298
299 // Do any replacements in the parameters
300 m_physicsLoggingPrefix = m_physicsLoggingPrefix.Replace("%REGIONNAME%", RegionName);
288 } 301 }
289 } 302 }
290 } 303 }
@@ -316,6 +329,38 @@ public class BSScene : PhysicsScene, IPhysicsParameters
316 PhysicsLogging.Write("[BULLETS UNMANAGED]:" + msg); 329 PhysicsLogging.Write("[BULLETS UNMANAGED]:" + msg);
317 } 330 }
318 331
332 public override void Dispose()
333 {
334 // m_log.DebugFormat("{0}: Dispose()", LogHeader);
335
336 // make sure no stepping happens while we're deleting stuff
337 m_initialized = false;
338
339 TerrainManager.ReleaseGroundPlaneAndTerrain();
340
341 foreach (KeyValuePair<uint, BSPhysObject> kvp in PhysObjects)
342 {
343 kvp.Value.Destroy();
344 }
345 PhysObjects.Clear();
346
347 // Now that the prims are all cleaned up, there should be no constraints left
348 if (Constraints != null)
349 {
350 Constraints.Dispose();
351 Constraints = null;
352 }
353
354 // Anything left in the unmanaged code should be cleaned out
355 BulletSimAPI.Shutdown(WorldID);
356
357 // Not logging any more
358 PhysicsLogging.Close();
359 }
360 #endregion // Construction and Initialization
361
362 #region Prim and Avatar addition and removal
363
319 public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying) 364 public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying)
320 { 365 {
321 m_log.ErrorFormat("{0}: CALL TO AddAvatar in BSScene. NOT IMPLEMENTED", LogHeader); 366 m_log.ErrorFormat("{0}: CALL TO AddAvatar in BSScene. NOT IMPLEMENTED", LogHeader);
@@ -329,7 +374,13 @@ public class BSScene : PhysicsScene, IPhysicsParameters
329 if (!m_initialized) return null; 374 if (!m_initialized) return null;
330 375
331 BSCharacter actor = new BSCharacter(localID, avName, this, position, size, isFlying); 376 BSCharacter actor = new BSCharacter(localID, avName, this, position, size, isFlying);
332 lock (m_avatars) m_avatars.Add(localID, actor); 377 lock (PhysObjects) PhysObjects.Add(localID, actor);
378
379 // TODO: Remove kludge someday.
380 // We must generate a collision for avatars whether they collide or not.
381 // This is required by OpenSim to update avatar animations, etc.
382 lock (m_avatarsWithCollisions) m_avatarsWithCollisions.Add(actor);
383
333 return actor; 384 return actor;
334 } 385 }
335 386
@@ -344,7 +395,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters
344 { 395 {
345 try 396 try
346 { 397 {
347 lock (m_avatars) m_avatars.Remove(actor.LocalID); 398 lock (PhysObjects) PhysObjects.Remove(actor.LocalID);
399 // Remove kludge someday
400 lock (m_avatarsWithCollisions) m_avatarsWithCollisions.Remove(bsactor);
348 } 401 }
349 catch (Exception e) 402 catch (Exception e)
350 { 403 {
@@ -362,11 +415,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters
362 BSPrim bsprim = prim as BSPrim; 415 BSPrim bsprim = prim as BSPrim;
363 if (bsprim != null) 416 if (bsprim != null)
364 { 417 {
365 // DetailLog("{0},RemovePrim,call", bsprim.LocalID); 418 DetailLog("{0},RemovePrim,call", bsprim.LocalID);
366 // m_log.DebugFormat("{0}: RemovePrim. id={1}/{2}", LogHeader, bsprim.Name, bsprim.LocalID); 419 // m_log.DebugFormat("{0}: RemovePrim. id={1}/{2}", LogHeader, bsprim.Name, bsprim.LocalID);
367 try 420 try
368 { 421 {
369 lock (m_prims) m_prims.Remove(bsprim.LocalID); 422 lock (PhysObjects) PhysObjects.Remove(bsprim.LocalID);
370 } 423 }
371 catch (Exception e) 424 catch (Exception e)
372 { 425 {
@@ -388,10 +441,10 @@ public class BSScene : PhysicsScene, IPhysicsParameters
388 441
389 if (!m_initialized) return null; 442 if (!m_initialized) return null;
390 443
391 // DetailLog("{0},AddPrimShape,call", localID); 444 DetailLog("{0},AddPrimShape,call", localID);
392 445
393 BSPrim prim = new BSPrim(localID, primName, this, position, size, rotation, pbs, isPhysical); 446 BSPrim prim = new BSPrim(localID, primName, this, position, size, rotation, pbs, isPhysical);
394 lock (m_prims) m_prims.Add(localID, prim); 447 lock (PhysObjects) PhysObjects.Add(localID, prim);
395 return prim; 448 return prim;
396 } 449 }
397 450
@@ -400,6 +453,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters
400 // information call is not needed. 453 // information call is not needed.
401 public override void AddPhysicsActorTaint(PhysicsActor prim) { } 454 public override void AddPhysicsActorTaint(PhysicsActor prim) { }
402 455
456 #endregion // Prim and Avatar addition and removal
457
458 #region Simulation
403 // Simulate one timestep 459 // Simulate one timestep
404 public override float Simulate(float timeStep) 460 public override float Simulate(float timeStep)
405 { 461 {
@@ -408,18 +464,16 @@ public class BSScene : PhysicsScene, IPhysicsParameters
408 int collidersCount = 0; 464 int collidersCount = 0;
409 IntPtr collidersPtr; 465 IntPtr collidersPtr;
410 466
411 LastSimulatedTimestep = timeStep;
412
413 // prevent simulation until we've been initialized 467 // prevent simulation until we've been initialized
414 if (!m_initialized) return 10.0f; 468 if (!m_initialized) return 5.0f;
415
416 int simulateStartTime = Util.EnvironmentTickCount();
417 469
418 // update the prim states while we know the physics engine is not busy 470 // update the prim states while we know the physics engine is not busy
471 int numTaints = _taintedObjects.Count;
419 ProcessTaints(); 472 ProcessTaints();
420 473
421 // Some of the prims operate with special vehicle properties 474 // Some of the prims operate with special vehicle properties
422 ProcessVehicles(timeStep); 475 ProcessVehicles(timeStep);
476 numTaints += _taintedObjects.Count;
423 ProcessTaints(); // the vehicles might have added taints 477 ProcessTaints(); // the vehicles might have added taints
424 478
425 // step the physical world one interval 479 // step the physical world one interval
@@ -427,15 +481,18 @@ public class BSScene : PhysicsScene, IPhysicsParameters
427 int numSubSteps = 0; 481 int numSubSteps = 0;
428 try 482 try
429 { 483 {
430 numSubSteps = BulletSimAPI.PhysicsStep(m_worldID, timeStep, m_maxSubSteps, m_fixedTimeStep, 484 numSubSteps = BulletSimAPI.PhysicsStep(WorldID, timeStep, m_maxSubSteps, m_fixedTimeStep,
431 out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr); 485 out updatedEntityCount, out updatedEntitiesPtr, out collidersCount, out collidersPtr);
432 // DetailLog("{0},Simulate,call, substeps={1}, updates={2}, colliders={3}", DetailLogZero, numSubSteps, updatedEntityCount, collidersCount); 486 DetailLog("{0},Simulate,call, nTaints= {1}, substeps={2}, updates={3}, colliders={4}",
487 DetailLogZero, numTaints, numSubSteps, updatedEntityCount, collidersCount);
433 } 488 }
434 catch (Exception e) 489 catch (Exception e)
435 { 490 {
436 m_log.WarnFormat("{0},PhysicsStep Exception: substeps={1}, updates={2}, colliders={3}, e={4}", LogHeader, numSubSteps, updatedEntityCount, collidersCount, e); 491 m_log.WarnFormat("{0},PhysicsStep Exception: nTaints={1}, substeps={2}, updates={3}, colliders={4}, e={5}",
437 // DetailLog("{0},PhysicsStepException,call, substeps={1}, updates={2}, colliders={3}", DetailLogZero, numSubSteps, updatedEntityCount, collidersCount); 492 LogHeader, numTaints, numSubSteps, updatedEntityCount, collidersCount, e);
438 // updatedEntityCount = 0; 493 DetailLog("{0},PhysicsStepException,call, nTaints={1}, substeps={2}, updates={3}, colliders={4}",
494 DetailLogZero, numTaints, numSubSteps, updatedEntityCount, collidersCount);
495 updatedEntityCount = 0;
439 collidersCount = 0; 496 collidersCount = 0;
440 } 497 }
441 498
@@ -443,7 +500,13 @@ public class BSScene : PhysicsScene, IPhysicsParameters
443 // Don't have to use the pointers passed back since we know it is the same pinned memory we passed in 500 // Don't have to use the pointers passed back since we know it is the same pinned memory we passed in
444 501
445 // Get a value for 'now' so all the collision and update routines don't have to get their own 502 // Get a value for 'now' so all the collision and update routines don't have to get their own
446 m_simulationNowTime = Util.EnvironmentTickCount(); 503 SimulationNowTime = Util.EnvironmentTickCount();
504
505 // This is a kludge to get avatar movement updates.
506 // ODE sends collisions for avatars even if there are have been no collisions. This updates
507 // avatar animations and stuff.
508 // If you fix avatar animation updates, remove this overhead and let normal collision processing happen.
509 m_objectsWithCollisions = new HashSet<BSPhysObject>(m_avatarsWithCollisions);
447 510
448 // If there were collisions, process them by sending the event to the prim. 511 // If there were collisions, process them by sending the event to the prim.
449 // Collisions must be processed before updates. 512 // Collisions must be processed before updates.
@@ -462,19 +525,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters
462 525
463 // The above SendCollision's batch up the collisions on the objects. 526 // The above SendCollision's batch up the collisions on the objects.
464 // Now push the collisions into the simulator. 527 // Now push the collisions into the simulator.
465 foreach (BSPrim bsp in m_primsWithCollisions) 528 foreach (BSPhysObject bsp in m_objectsWithCollisions)
466 bsp.SendCollisions(); 529 bsp.SendCollisions();
467 m_primsWithCollisions.Clear(); 530 m_objectsWithCollisions.Clear();
468
469 // This is a kludge to get avatar movement updated.
470 // Don't send collisions only if there were collisions -- send everytime.
471 // ODE sends collisions even if there are none and this is used to update
472 // avatar animations and stuff.
473 // foreach (BSCharacter bsc in m_avatarsWithCollisions)
474 // bsc.SendCollisions();
475 foreach (KeyValuePair<uint, BSCharacter> kvp in m_avatars)
476 kvp.Value.SendCollisions();
477 m_avatarsWithCollisions.Clear();
478 531
479 // If any of the objects had updated properties, tell the object it has been changed by the physics engine 532 // If any of the objects had updated properties, tell the object it has been changed by the physics engine
480 if (updatedEntityCount > 0) 533 if (updatedEntityCount > 0)
@@ -482,17 +535,10 @@ public class BSScene : PhysicsScene, IPhysicsParameters
482 for (int ii = 0; ii < updatedEntityCount; ii++) 535 for (int ii = 0; ii < updatedEntityCount; ii++)
483 { 536 {
484 EntityProperties entprop = m_updateArray[ii]; 537 EntityProperties entprop = m_updateArray[ii];
485 BSPrim prim; 538 BSPhysObject pobj;
486 if (m_prims.TryGetValue(entprop.ID, out prim)) 539 if (PhysObjects.TryGetValue(entprop.ID, out pobj))
487 {
488 prim.UpdateProperties(entprop);
489 continue;
490 }
491 BSCharacter actor;
492 if (m_avatars.TryGetValue(entprop.ID, out actor))
493 { 540 {
494 actor.UpdateProperties(entprop); 541 pobj.UpdateProperties(entprop);
495 continue;
496 } 542 }
497 } 543 }
498 } 544 }
@@ -506,79 +552,59 @@ public class BSScene : PhysicsScene, IPhysicsParameters
506 } 552 }
507 } 553 }
508 554
509 // this is a waste since the outside routine also calcuates the physics simulation 555 // The physics engine returns the number of milliseconds it simulated this call.
510 // period. TODO: There should be a way of computing physics frames from simulator computation. 556 // These are summed and normalized to one second and divided by 1000 to give the reported physics FPS.
511 // long simulateTotalTime = Util.EnvironmentTickCountSubtract(simulateStartTime); 557 // Since Bullet normally does 5 or 6 substeps, this will normally sum to about 60 FPS.
512 // return (timeStep * (float)simulateTotalTime); 558 return numSubSteps * m_fixedTimeStep;
513
514 // TODO: FIX THIS: fps calculation possibly wrong.
515 // This calculation says 1/timeStep is the ideal frame rate. Any time added to
516 // that by the physics simulation gives a slower frame rate.
517 long totalSimulationTime = Util.EnvironmentTickCountSubtract(simulateStartTime);
518 if (totalSimulationTime >= timeStep)
519 return 0;
520 return 1f / (timeStep + totalSimulationTime);
521 } 559 }
522 560
523 // Something has collided 561 // Something has collided
524 private void SendCollision(uint localID, uint collidingWith, Vector3 collidePoint, Vector3 collideNormal, float penitration) 562 private void SendCollision(uint localID, uint collidingWith, Vector3 collidePoint, Vector3 collideNormal, float penetration)
525 { 563 {
526 if (localID == TERRAIN_ID || localID == GROUNDPLANE_ID) 564 if (localID <= TerrainManager.HighestTerrainID)
527 { 565 {
528 return; // don't send collisions to the terrain 566 return; // don't send collisions to the terrain
529 } 567 }
530 568
531 ActorTypes type = ActorTypes.Prim; 569 BSPhysObject collider;
532 if (collidingWith == TERRAIN_ID || collidingWith == GROUNDPLANE_ID) 570 if (!PhysObjects.TryGetValue(localID, out collider))
533 type = ActorTypes.Ground; 571 {
534 else if (m_avatars.ContainsKey(collidingWith)) 572 // If the object that is colliding cannot be found, just ignore the collision.
535 type = ActorTypes.Agent;
536
537 BSPrim prim;
538 if (m_prims.TryGetValue(localID, out prim)) {
539 prim.Collide(collidingWith, type, collidePoint, collideNormal, penitration);
540 m_primsWithCollisions.Add(prim);
541 return; 573 return;
542 } 574 }
543 BSCharacter actor; 575
544 if (m_avatars.TryGetValue(localID, out actor)) { 576 // The terrain is not in the physical object list so 'collidee'
545 actor.Collide(collidingWith, type, collidePoint, collideNormal, penitration); 577 // can be null when Collide() is called.
546 m_avatarsWithCollisions.Add(actor); 578 BSPhysObject collidee = null;
547 return; 579 PhysObjects.TryGetValue(collidingWith, out collidee);
580
581 // DetailLog("{0},BSScene.SendCollision,collide,id={1},with={2}", DetailLogZero, localID, collidingWith);
582
583 if (collider.Collide(collidingWith, collidee, collidePoint, collideNormal, penetration))
584 {
585 // If a collision was posted, remember to send it to the simulator
586 m_objectsWithCollisions.Add(collider);
548 } 587 }
588
549 return; 589 return;
550 } 590 }
551 591
552 public override void GetResults() { } 592 #endregion // Simulation
553 593
554 public override void SetTerrain(float[] heightMap) { 594 public override void GetResults() { }
555 m_heightMap = heightMap;
556 this.TaintedObject("BSScene.SetTerrain", delegate()
557 {
558 BulletSimAPI.SetHeightmap(m_worldID, m_heightMap);
559 });
560 }
561 595
562 // Someday we will have complex terrain with caves and tunnels 596 #region Terrain
563 // For the moment, it's flat and convex
564 public float GetTerrainHeightAtXYZ(Vector3 loc)
565 {
566 return GetTerrainHeightAtXY(loc.X, loc.Y);
567 }
568 597
569 public float GetTerrainHeightAtXY(float tX, float tY) 598 public override void SetTerrain(float[] heightMap) {
570 { 599 TerrainManager.SetTerrain(heightMap);
571 if (tX < 0 || tX >= Constants.RegionSize || tY < 0 || tY >= Constants.RegionSize)
572 return 30;
573 return m_heightMap[((int)tX) * Constants.RegionSize + ((int)tY)];
574 } 600 }
575 601
576 public override void SetWaterLevel(float baseheight) 602 public override void SetWaterLevel(float baseheight)
577 { 603 {
578 m_waterLevel = baseheight; 604 m_waterLevel = baseheight;
579 // TODO: pass to physics engine so things will float?
580 } 605 }
581 public float GetWaterLevel() 606 // Someday....
607 public float GetWaterLevelAtXYZ(Vector3 loc)
582 { 608 {
583 return m_waterLevel; 609 return m_waterLevel;
584 } 610 }
@@ -588,39 +614,27 @@ public class BSScene : PhysicsScene, IPhysicsParameters
588 // m_log.DebugFormat("{0}: DeleteTerrain()", LogHeader); 614 // m_log.DebugFormat("{0}: DeleteTerrain()", LogHeader);
589 } 615 }
590 616
591 public override void Dispose() 617 // Although no one seems to check this, I do support combining.
618 public override bool SupportsCombining()
592 { 619 {
593 // m_log.DebugFormat("{0}: Dispose()", LogHeader); 620 return TerrainManager.SupportsCombining();
594 621 }
595 // make sure no stepping happens while we're deleting stuff 622 // This call says I am a child to region zero in a mega-region. 'pScene' is that
596 m_initialized = false; 623 // of region zero, 'offset' is my offset from regions zero's origin, and
597 624 // 'extents' is the largest XY that is handled in my region.
598 foreach (KeyValuePair<uint, BSCharacter> kvp in m_avatars) 625 public override void Combine(PhysicsScene pScene, Vector3 offset, Vector3 extents)
599 { 626 {
600 kvp.Value.Destroy(); 627 TerrainManager.Combine(pScene, offset, extents);
601 } 628 }
602 m_avatars.Clear();
603
604 foreach (KeyValuePair<uint, BSPrim> kvp in m_prims)
605 {
606 kvp.Value.Destroy();
607 }
608 m_prims.Clear();
609
610 // Now that the prims are all cleaned up, there should be no constraints left
611 if (m_constraintCollection != null)
612 {
613 m_constraintCollection.Dispose();
614 m_constraintCollection = null;
615 }
616
617 // Anything left in the unmanaged code should be cleaned out
618 BulletSimAPI.Shutdown(WorldID);
619 629
620 // Not logging any more 630 // Unhook all the combining that I know about.
621 PhysicsLogging.Close(); 631 public override void UnCombine(PhysicsScene pScene)
632 {
633 TerrainManager.UnCombine(pScene);
622 } 634 }
623 635
636 #endregion // Terrain
637
624 public override Dictionary<uint, float> GetTopColliders() 638 public override Dictionary<uint, float> GetTopColliders()
625 { 639 {
626 return new Dictionary<uint, float>(); 640 return new Dictionary<uint, float>();
@@ -628,121 +642,6 @@ public class BSScene : PhysicsScene, IPhysicsParameters
628 642
629 public override bool IsThreaded { get { return false; } } 643 public override bool IsThreaded { get { return false; } }
630 644
631 /// <summary>
632 /// Routine to figure out if we need to mesh this prim with our mesher
633 /// </summary>
634 /// <param name="pbs"></param>
635 /// <returns>true if the prim needs meshing</returns>
636 public bool NeedsMeshing(PrimitiveBaseShape pbs)
637 {
638 // most of this is redundant now as the mesher will return null if it cant mesh a prim
639 // but we still need to check for sculptie meshing being enabled so this is the most
640 // convenient place to do it for now...
641
642 // int iPropertiesNotSupportedDefault = 0;
643
644 if (pbs.SculptEntry && !_meshSculptedPrim)
645 {
646 // Render sculpties as boxes
647 return false;
648 }
649
650 // if it's a standard box or sphere with no cuts, hollows, twist or top shear, return false since Bullet
651 // can use an internal representation for the prim
652 if (!_forceSimplePrimMeshing)
653 {
654 if ((pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight)
655 || (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1
656 && pbs.Scale.X == pbs.Scale.Y && pbs.Scale.Y == pbs.Scale.Z))
657 {
658
659 if (pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0
660 && pbs.ProfileHollow == 0
661 && pbs.PathTwist == 0 && pbs.PathTwistBegin == 0
662 && pbs.PathBegin == 0 && pbs.PathEnd == 0
663 && pbs.PathTaperX == 0 && pbs.PathTaperY == 0
664 && pbs.PathScaleX == 100 && pbs.PathScaleY == 100
665 && pbs.PathShearX == 0 && pbs.PathShearY == 0)
666 {
667 return false;
668 }
669 }
670 }
671
672 /* TODO: verify that the mesher will now do all these shapes
673 if (pbs.ProfileHollow != 0)
674 iPropertiesNotSupportedDefault++;
675
676 if ((pbs.PathBegin != 0) || pbs.PathEnd != 0)
677 iPropertiesNotSupportedDefault++;
678
679 if ((pbs.PathTwistBegin != 0) || (pbs.PathTwist != 0))
680 iPropertiesNotSupportedDefault++;
681
682 if ((pbs.ProfileBegin != 0) || pbs.ProfileEnd != 0)
683 iPropertiesNotSupportedDefault++;
684
685 if ((pbs.PathScaleX != 100) || (pbs.PathScaleY != 100))
686 iPropertiesNotSupportedDefault++;
687
688 if ((pbs.PathShearX != 0) || (pbs.PathShearY != 0))
689 iPropertiesNotSupportedDefault++;
690
691 if (pbs.ProfileShape == ProfileShape.Circle && pbs.PathCurve == (byte)Extrusion.Straight)
692 iPropertiesNotSupportedDefault++;
693
694 if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1 && (pbs.Scale.X != pbs.Scale.Y || pbs.Scale.Y != pbs.Scale.Z || pbs.Scale.Z != pbs.Scale.X))
695 iPropertiesNotSupportedDefault++;
696
697 if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte) Extrusion.Curve1)
698 iPropertiesNotSupportedDefault++;
699
700 // test for torus
701 if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.Square)
702 {
703 if (pbs.PathCurve == (byte)Extrusion.Curve1)
704 {
705 iPropertiesNotSupportedDefault++;
706 }
707 }
708 else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
709 {
710 if (pbs.PathCurve == (byte)Extrusion.Straight)
711 {
712 iPropertiesNotSupportedDefault++;
713 }
714 // ProfileCurve seems to combine hole shape and profile curve so we need to only compare against the lower 3 bits
715 else if (pbs.PathCurve == (byte)Extrusion.Curve1)
716 {
717 iPropertiesNotSupportedDefault++;
718 }
719 }
720 else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
721 {
722 if (pbs.PathCurve == (byte)Extrusion.Curve1 || pbs.PathCurve == (byte)Extrusion.Curve2)
723 {
724 iPropertiesNotSupportedDefault++;
725 }
726 }
727 else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
728 {
729 if (pbs.PathCurve == (byte)Extrusion.Straight)
730 {
731 iPropertiesNotSupportedDefault++;
732 }
733 else if (pbs.PathCurve == (byte)Extrusion.Curve1)
734 {
735 iPropertiesNotSupportedDefault++;
736 }
737 }
738 if (iPropertiesNotSupportedDefault == 0)
739 {
740 return false;
741 }
742 */
743 return true;
744 }
745
746 // Calls to the PhysicsActors can't directly call into the physics engine 645 // Calls to the PhysicsActors can't directly call into the physics engine
747 // because it might be busy. We delay changes to a known time. 646 // because it might be busy. We delay changes to a known time.
748 // We rely on C#'s closure to save and restore the context for the delegate. 647 // We rely on C#'s closure to save and restore the context for the delegate.
@@ -751,7 +650,10 @@ public class BSScene : PhysicsScene, IPhysicsParameters
751 if (!m_initialized) return; 650 if (!m_initialized) return;
752 651
753 lock (_taintLock) 652 lock (_taintLock)
653 {
754 _taintedObjects.Add(new TaintCallbackEntry(ident, callback)); 654 _taintedObjects.Add(new TaintCallbackEntry(ident, callback));
655 }
656
755 return; 657 return;
756 } 658 }
757 659
@@ -830,14 +732,14 @@ public class BSScene : PhysicsScene, IPhysicsParameters
830 // no locking because only called when physics engine is not busy 732 // no locking because only called when physics engine is not busy
831 private void ProcessVehicles(float timeStep) 733 private void ProcessVehicles(float timeStep)
832 { 734 {
833 foreach (BSPrim prim in m_vehicles) 735 foreach (BSPhysObject pobj in m_vehicles)
834 { 736 {
835 prim.StepVehicle(timeStep); 737 pobj.StepVehicle(timeStep);
836 } 738 }
837 } 739 }
838 #endregion Vehicles 740 #endregion Vehicles
839 741
840 #region Parameters 742 #region INI and command line parameter processing
841 743
842 delegate void ParamUser(BSScene scene, IConfig conf, string paramName, float val); 744 delegate void ParamUser(BSScene scene, IConfig conf, string paramName, float val);
843 delegate float ParamGet(BSScene scene); 745 delegate float ParamGet(BSScene scene);
@@ -888,25 +790,35 @@ public class BSScene : PhysicsScene, IPhysicsParameters
888 { 790 {
889 new ParameterDefn("MeshSculptedPrim", "Whether to create meshes for sculpties", 791 new ParameterDefn("MeshSculptedPrim", "Whether to create meshes for sculpties",
890 ConfigurationParameters.numericTrue, 792 ConfigurationParameters.numericTrue,
891 (s,cf,p,v) => { s._meshSculptedPrim = cf.GetBoolean(p, s.BoolNumeric(v)); }, 793 (s,cf,p,v) => { s.ShouldMeshSculptedPrim = cf.GetBoolean(p, s.BoolNumeric(v)); },
892 (s) => { return s.NumericBool(s._meshSculptedPrim); }, 794 (s) => { return s.NumericBool(s.ShouldMeshSculptedPrim); },
893 (s,p,l,v) => { s._meshSculptedPrim = s.BoolNumeric(v); } ), 795 (s,p,l,v) => { s.ShouldMeshSculptedPrim = s.BoolNumeric(v); } ),
894 new ParameterDefn("ForceSimplePrimMeshing", "If true, only use primitive meshes for objects", 796 new ParameterDefn("ForceSimplePrimMeshing", "If true, only use primitive meshes for objects",
895 ConfigurationParameters.numericFalse, 797 ConfigurationParameters.numericFalse,
896 (s,cf,p,v) => { s._forceSimplePrimMeshing = cf.GetBoolean(p, s.BoolNumeric(v)); }, 798 (s,cf,p,v) => { s.ShouldForceSimplePrimMeshing = cf.GetBoolean(p, s.BoolNumeric(v)); },
897 (s) => { return s.NumericBool(s._forceSimplePrimMeshing); }, 799 (s) => { return s.NumericBool(s.ShouldForceSimplePrimMeshing); },
898 (s,p,l,v) => { s._forceSimplePrimMeshing = s.BoolNumeric(v); } ), 800 (s,p,l,v) => { s.ShouldForceSimplePrimMeshing = s.BoolNumeric(v); } ),
899 801
900 new ParameterDefn("MeshLOD", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)", 802 new ParameterDefn("MeshLevelOfDetail", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)",
901 8f, 803 8f,
902 (s,cf,p,v) => { s.m_meshLOD = cf.GetInt(p, (int)v); }, 804 (s,cf,p,v) => { s.MeshLOD = (float)cf.GetInt(p, (int)v); },
903 (s) => { return (float)s.m_meshLOD; }, 805 (s) => { return s.MeshLOD; },
904 (s,p,l,v) => { s.m_meshLOD = (int)v; } ), 806 (s,p,l,v) => { s.MeshLOD = v; } ),
905 new ParameterDefn("SculptLOD", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)", 807 new ParameterDefn("MeshLevelOfDetailMegaPrim", "Level of detail to render meshes larger than threshold meters",
808 16f,
809 (s,cf,p,v) => { s.MeshMegaPrimLOD = (float)cf.GetInt(p, (int)v); },
810 (s) => { return s.MeshMegaPrimLOD; },
811 (s,p,l,v) => { s.MeshMegaPrimLOD = v; } ),
812 new ParameterDefn("MeshLevelOfDetailMegaPrimThreshold", "Size (in meters) of a mesh before using MeshMegaPrimLOD",
813 10f,
814 (s,cf,p,v) => { s.MeshMegaPrimThreshold = (float)cf.GetInt(p, (int)v); },
815 (s) => { return s.MeshMegaPrimThreshold; },
816 (s,p,l,v) => { s.MeshMegaPrimThreshold = v; } ),
817 new ParameterDefn("SculptLevelOfDetail", "Level of detail to render sculpties (32, 16, 8 or 4. 32=most detailed)",
906 32f, 818 32f,
907 (s,cf,p,v) => { s.m_sculptLOD = cf.GetInt(p, (int)v); }, 819 (s,cf,p,v) => { s.SculptLOD = (float)cf.GetInt(p, (int)v); },
908 (s) => { return (float)s.m_sculptLOD; }, 820 (s) => { return s.SculptLOD; },
909 (s,p,l,v) => { s.m_sculptLOD = (int)v; } ), 821 (s,p,l,v) => { s.SculptLOD = v; } ),
910 822
911 new ParameterDefn("MaxSubStep", "In simulation step, maximum number of substeps", 823 new ParameterDefn("MaxSubStep", "In simulation step, maximum number of substeps",
912 10f, 824 10f,
@@ -930,9 +842,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters
930 (s,p,l,v) => { s.m_maxUpdatesPerFrame = (int)v; } ), 842 (s,p,l,v) => { s.m_maxUpdatesPerFrame = (int)v; } ),
931 new ParameterDefn("MaxObjectMass", "Maximum object mass (10000.01)", 843 new ParameterDefn("MaxObjectMass", "Maximum object mass (10000.01)",
932 10000.01f, 844 10000.01f,
933 (s,cf,p,v) => { s.m_maximumObjectMass = cf.GetFloat(p, v); }, 845 (s,cf,p,v) => { s.MaximumObjectMass = cf.GetFloat(p, v); },
934 (s) => { return (float)s.m_maximumObjectMass; }, 846 (s) => { return (float)s.MaximumObjectMass; },
935 (s,p,l,v) => { s.m_maximumObjectMass = v; } ), 847 (s,p,l,v) => { s.MaximumObjectMass = v; } ),
936 848
937 new ParameterDefn("PID_D", "Derivitive factor for motion smoothing", 849 new ParameterDefn("PID_D", "Derivitive factor for motion smoothing",
938 2200f, 850 2200f,
@@ -976,42 +888,42 @@ public class BSScene : PhysicsScene, IPhysicsParameters
976 0f, 888 0f,
977 (s,cf,p,v) => { s.m_params[0].linearDamping = cf.GetFloat(p, v); }, 889 (s,cf,p,v) => { s.m_params[0].linearDamping = cf.GetFloat(p, v); },
978 (s) => { return s.m_params[0].linearDamping; }, 890 (s) => { return s.m_params[0].linearDamping; },
979 (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].linearDamping, p, l, v); } ), 891 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].linearDamping, p, l, v); } ),
980 new ParameterDefn("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)", 892 new ParameterDefn("AngularDamping", "Factor to damp angular movement per second (0.0 - 1.0)",
981 0f, 893 0f,
982 (s,cf,p,v) => { s.m_params[0].angularDamping = cf.GetFloat(p, v); }, 894 (s,cf,p,v) => { s.m_params[0].angularDamping = cf.GetFloat(p, v); },
983 (s) => { return s.m_params[0].angularDamping; }, 895 (s) => { return s.m_params[0].angularDamping; },
984 (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].angularDamping, p, l, v); } ), 896 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].angularDamping, p, l, v); } ),
985 new ParameterDefn("DeactivationTime", "Seconds before considering an object potentially static", 897 new ParameterDefn("DeactivationTime", "Seconds before considering an object potentially static",
986 0.2f, 898 0.2f,
987 (s,cf,p,v) => { s.m_params[0].deactivationTime = cf.GetFloat(p, v); }, 899 (s,cf,p,v) => { s.m_params[0].deactivationTime = cf.GetFloat(p, v); },
988 (s) => { return s.m_params[0].deactivationTime; }, 900 (s) => { return s.m_params[0].deactivationTime; },
989 (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].deactivationTime, p, l, v); } ), 901 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].deactivationTime, p, l, v); } ),
990 new ParameterDefn("LinearSleepingThreshold", "Seconds to measure linear movement before considering static", 902 new ParameterDefn("LinearSleepingThreshold", "Seconds to measure linear movement before considering static",
991 0.8f, 903 0.8f,
992 (s,cf,p,v) => { s.m_params[0].linearSleepingThreshold = cf.GetFloat(p, v); }, 904 (s,cf,p,v) => { s.m_params[0].linearSleepingThreshold = cf.GetFloat(p, v); },
993 (s) => { return s.m_params[0].linearSleepingThreshold; }, 905 (s) => { return s.m_params[0].linearSleepingThreshold; },
994 (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].linearSleepingThreshold, p, l, v); } ), 906 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].linearSleepingThreshold, p, l, v); } ),
995 new ParameterDefn("AngularSleepingThreshold", "Seconds to measure angular movement before considering static", 907 new ParameterDefn("AngularSleepingThreshold", "Seconds to measure angular movement before considering static",
996 1.0f, 908 1.0f,
997 (s,cf,p,v) => { s.m_params[0].angularSleepingThreshold = cf.GetFloat(p, v); }, 909 (s,cf,p,v) => { s.m_params[0].angularSleepingThreshold = cf.GetFloat(p, v); },
998 (s) => { return s.m_params[0].angularSleepingThreshold; }, 910 (s) => { return s.m_params[0].angularSleepingThreshold; },
999 (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].angularSleepingThreshold, p, l, v); } ), 911 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].angularSleepingThreshold, p, l, v); } ),
1000 new ParameterDefn("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" , 912 new ParameterDefn("CcdMotionThreshold", "Continuious collision detection threshold (0 means no CCD)" ,
1001 0f, // set to zero to disable 913 0f, // set to zero to disable
1002 (s,cf,p,v) => { s.m_params[0].ccdMotionThreshold = cf.GetFloat(p, v); }, 914 (s,cf,p,v) => { s.m_params[0].ccdMotionThreshold = cf.GetFloat(p, v); },
1003 (s) => { return s.m_params[0].ccdMotionThreshold; }, 915 (s) => { return s.m_params[0].ccdMotionThreshold; },
1004 (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].ccdMotionThreshold, p, l, v); } ), 916 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].ccdMotionThreshold, p, l, v); } ),
1005 new ParameterDefn("CcdSweptSphereRadius", "Continuious collision detection test radius" , 917 new ParameterDefn("CcdSweptSphereRadius", "Continuious collision detection test radius" ,
1006 0f, 918 0f,
1007 (s,cf,p,v) => { s.m_params[0].ccdSweptSphereRadius = cf.GetFloat(p, v); }, 919 (s,cf,p,v) => { s.m_params[0].ccdSweptSphereRadius = cf.GetFloat(p, v); },
1008 (s) => { return s.m_params[0].ccdSweptSphereRadius; }, 920 (s) => { return s.m_params[0].ccdSweptSphereRadius; },
1009 (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].ccdSweptSphereRadius, p, l, v); } ), 921 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].ccdSweptSphereRadius, p, l, v); } ),
1010 new ParameterDefn("ContactProcessingThreshold", "Distance between contacts before doing collision check" , 922 new ParameterDefn("ContactProcessingThreshold", "Distance between contacts before doing collision check" ,
1011 0.1f, 923 0.1f,
1012 (s,cf,p,v) => { s.m_params[0].contactProcessingThreshold = cf.GetFloat(p, v); }, 924 (s,cf,p,v) => { s.m_params[0].contactProcessingThreshold = cf.GetFloat(p, v); },
1013 (s) => { return s.m_params[0].contactProcessingThreshold; }, 925 (s) => { return s.m_params[0].contactProcessingThreshold; },
1014 (s,p,l,v) => { s.UpdateParameterPrims(ref s.m_params[0].contactProcessingThreshold, p, l, v); } ), 926 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].contactProcessingThreshold, p, l, v); } ),
1015 927
1016 new ParameterDefn("TerrainFriction", "Factor to reduce movement against terrain surface" , 928 new ParameterDefn("TerrainFriction", "Factor to reduce movement against terrain surface" ,
1017 0.5f, 929 0.5f,
@@ -1029,35 +941,35 @@ public class BSScene : PhysicsScene, IPhysicsParameters
1029 (s) => { return s.m_params[0].terrainRestitution; }, 941 (s) => { return s.m_params[0].terrainRestitution; },
1030 (s,p,l,v) => { s.m_params[0].terrainRestitution = v; s.TaintedUpdateParameter(p,l,v); } ), 942 (s,p,l,v) => { s.m_params[0].terrainRestitution = v; s.TaintedUpdateParameter(p,l,v); } ),
1031 new ParameterDefn("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation.", 943 new ParameterDefn("AvatarFriction", "Factor to reduce movement against an avatar. Changed on avatar recreation.",
1032 0.5f, 944 0.2f,
1033 (s,cf,p,v) => { s.m_params[0].avatarFriction = cf.GetFloat(p, v); }, 945 (s,cf,p,v) => { s.m_params[0].avatarFriction = cf.GetFloat(p, v); },
1034 (s) => { return s.m_params[0].avatarFriction; }, 946 (s) => { return s.m_params[0].avatarFriction; },
1035 (s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarFriction, p, l, v); } ), 947 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarFriction, p, l, v); } ),
1036 new ParameterDefn("AvatarDensity", "Density of an avatar. Changed on avatar recreation.", 948 new ParameterDefn("AvatarDensity", "Density of an avatar. Changed on avatar recreation.",
1037 60f, 949 60f,
1038 (s,cf,p,v) => { s.m_params[0].avatarDensity = cf.GetFloat(p, v); }, 950 (s,cf,p,v) => { s.m_params[0].avatarDensity = cf.GetFloat(p, v); },
1039 (s) => { return s.m_params[0].avatarDensity; }, 951 (s) => { return s.m_params[0].avatarDensity; },
1040 (s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarDensity, p, l, v); } ), 952 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarDensity, p, l, v); } ),
1041 new ParameterDefn("AvatarRestitution", "Bouncyness. Changed on avatar recreation.", 953 new ParameterDefn("AvatarRestitution", "Bouncyness. Changed on avatar recreation.",
1042 0f, 954 0f,
1043 (s,cf,p,v) => { s.m_params[0].avatarRestitution = cf.GetFloat(p, v); }, 955 (s,cf,p,v) => { s.m_params[0].avatarRestitution = cf.GetFloat(p, v); },
1044 (s) => { return s.m_params[0].avatarRestitution; }, 956 (s) => { return s.m_params[0].avatarRestitution; },
1045 (s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarRestitution, p, l, v); } ), 957 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarRestitution, p, l, v); } ),
1046 new ParameterDefn("AvatarCapsuleRadius", "Radius of space around an avatar", 958 new ParameterDefn("AvatarCapsuleRadius", "Radius of space around an avatar",
1047 0.37f, 959 0.37f,
1048 (s,cf,p,v) => { s.m_params[0].avatarCapsuleRadius = cf.GetFloat(p, v); }, 960 (s,cf,p,v) => { s.m_params[0].avatarCapsuleRadius = cf.GetFloat(p, v); },
1049 (s) => { return s.m_params[0].avatarCapsuleRadius; }, 961 (s) => { return s.m_params[0].avatarCapsuleRadius; },
1050 (s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarCapsuleRadius, p, l, v); } ), 962 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarCapsuleRadius, p, l, v); } ),
1051 new ParameterDefn("AvatarCapsuleHeight", "Default height of space around avatar", 963 new ParameterDefn("AvatarCapsuleHeight", "Default height of space around avatar",
1052 1.5f, 964 1.5f,
1053 (s,cf,p,v) => { s.m_params[0].avatarCapsuleHeight = cf.GetFloat(p, v); }, 965 (s,cf,p,v) => { s.m_params[0].avatarCapsuleHeight = cf.GetFloat(p, v); },
1054 (s) => { return s.m_params[0].avatarCapsuleHeight; }, 966 (s) => { return s.m_params[0].avatarCapsuleHeight; },
1055 (s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarCapsuleHeight, p, l, v); } ), 967 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarCapsuleHeight, p, l, v); } ),
1056 new ParameterDefn("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions", 968 new ParameterDefn("AvatarContactProcessingThreshold", "Distance from capsule to check for collisions",
1057 0.1f, 969 0.1f,
1058 (s,cf,p,v) => { s.m_params[0].avatarContactProcessingThreshold = cf.GetFloat(p, v); }, 970 (s,cf,p,v) => { s.m_params[0].avatarContactProcessingThreshold = cf.GetFloat(p, v); },
1059 (s) => { return s.m_params[0].avatarContactProcessingThreshold; }, 971 (s) => { return s.m_params[0].avatarContactProcessingThreshold; },
1060 (s,p,l,v) => { s.UpdateParameterAvatars(ref s.m_params[0].avatarContactProcessingThreshold, p, l, v); } ), 972 (s,p,l,v) => { s.UpdateParameterObject(ref s.m_params[0].avatarContactProcessingThreshold, p, l, v); } ),
1061 973
1062 974
1063 new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)", 975 new ParameterDefn("MaxPersistantManifoldPoolSize", "Number of manifolds pooled (0 means default of 4096)",
@@ -1121,8 +1033,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
1121 (s,cf,p,v) => { s.m_params[0].linkConstraintTransMotorMaxForce = cf.GetFloat(p, v); }, 1033 (s,cf,p,v) => { s.m_params[0].linkConstraintTransMotorMaxForce = cf.GetFloat(p, v); },
1122 (s) => { return s.m_params[0].linkConstraintTransMotorMaxForce; }, 1034 (s) => { return s.m_params[0].linkConstraintTransMotorMaxForce; },
1123 (s,p,l,v) => { s.m_params[0].linkConstraintTransMotorMaxForce = v; } ), 1035 (s,p,l,v) => { s.m_params[0].linkConstraintTransMotorMaxForce = v; } ),
1124 new ParameterDefn("LinkConstraintCFM", "Amount constraint can be violated. 0=none, 1=all. Default=0", 1036 new ParameterDefn("LinkConstraintCFM", "Amount constraint can be violated. 0=no violation, 1=infinite. Default=0.1",
1125 0.0f, 1037 0.1f,
1126 (s,cf,p,v) => { s.m_params[0].linkConstraintCFM = cf.GetFloat(p, v); }, 1038 (s,cf,p,v) => { s.m_params[0].linkConstraintCFM = cf.GetFloat(p, v); },
1127 (s) => { return s.m_params[0].linkConstraintCFM; }, 1039 (s) => { return s.m_params[0].linkConstraintCFM; },
1128 (s,p,l,v) => { s.m_params[0].linkConstraintCFM = v; } ), 1040 (s,p,l,v) => { s.m_params[0].linkConstraintCFM = v; } ),
@@ -1131,18 +1043,17 @@ public class BSScene : PhysicsScene, IPhysicsParameters
1131 (s,cf,p,v) => { s.m_params[0].linkConstraintERP = cf.GetFloat(p, v); }, 1043 (s,cf,p,v) => { s.m_params[0].linkConstraintERP = cf.GetFloat(p, v); },
1132 (s) => { return s.m_params[0].linkConstraintERP; }, 1044 (s) => { return s.m_params[0].linkConstraintERP; },
1133 (s,p,l,v) => { s.m_params[0].linkConstraintERP = v; } ), 1045 (s,p,l,v) => { s.m_params[0].linkConstraintERP = v; } ),
1046 new ParameterDefn("LinkConstraintSolverIterations", "Number of solver iterations when computing constraint. (0 = Bullet default)",
1047 40,
1048 (s,cf,p,v) => { s.m_params[0].linkConstraintSolverIterations = cf.GetFloat(p, v); },
1049 (s) => { return s.m_params[0].linkConstraintSolverIterations; },
1050 (s,p,l,v) => { s.m_params[0].linkConstraintSolverIterations = v; } ),
1134 1051
1135 new ParameterDefn("DetailedStats", "Frames between outputting detailed phys stats. (0 is off)", 1052 new ParameterDefn("DetailedStats", "Frames between outputting detailed phys stats. (0 is off)",
1136 0f, 1053 0f,
1137 (s,cf,p,v) => { s.m_detailedStatsStep = cf.GetInt(p, (int)v); }, 1054 (s,cf,p,v) => { s.m_detailedStatsStep = cf.GetInt(p, (int)v); },
1138 (s) => { return (float)s.m_detailedStatsStep; }, 1055 (s) => { return (float)s.m_detailedStatsStep; },
1139 (s,p,l,v) => { s.m_detailedStatsStep = (int)v; } ), 1056 (s,p,l,v) => { s.m_detailedStatsStep = (int)v; } ),
1140 new ParameterDefn("ShouldDebugLog", "Enables detailed DEBUG log statements",
1141 ConfigurationParameters.numericFalse,
1142 (s,cf,p,v) => { s.ShouldDebugLog = cf.GetBoolean(p, s.BoolNumeric(v)); },
1143 (s) => { return s.NumericBool(s.ShouldDebugLog); },
1144 (s,p,l,v) => { s.ShouldDebugLog = s.BoolNumeric(v); } ),
1145
1146 }; 1057 };
1147 1058
1148 // Convert a boolean to our numeric true and false values 1059 // Convert a boolean to our numeric true and false values
@@ -1200,6 +1111,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
1200 1111
1201 private PhysParameterEntry[] SettableParameters = new PhysParameterEntry[1]; 1112 private PhysParameterEntry[] SettableParameters = new PhysParameterEntry[1];
1202 1113
1114 // This creates an array in the correct format for returning the list of
1115 // parameters. This is used by the 'list' option of the 'physics' command.
1203 private void BuildParameterTable() 1116 private void BuildParameterTable()
1204 { 1117 {
1205 if (SettableParameters.Length < ParameterDefinitions.Length) 1118 if (SettableParameters.Length < ParameterDefinitions.Length)
@@ -1250,18 +1163,10 @@ public class BSScene : PhysicsScene, IPhysicsParameters
1250 } 1163 }
1251 1164
1252 // check to see if we are updating a parameter for a particular or all of the prims 1165 // check to see if we are updating a parameter for a particular or all of the prims
1253 protected void UpdateParameterPrims(ref float loc, string parm, uint localID, float val) 1166 protected void UpdateParameterObject(ref float loc, string parm, uint localID, float val)
1254 {
1255 List<uint> operateOn;
1256 lock (m_prims) operateOn = new List<uint>(m_prims.Keys);
1257 UpdateParameterSet(operateOn, ref loc, parm, localID, val);
1258 }
1259
1260 // check to see if we are updating a parameter for a particular or all of the avatars
1261 protected void UpdateParameterAvatars(ref float loc, string parm, uint localID, float val)
1262 { 1167 {
1263 List<uint> operateOn; 1168 List<uint> operateOn;
1264 lock (m_avatars) operateOn = new List<uint>(m_avatars.Keys); 1169 lock (PhysObjects) operateOn = new List<uint>(PhysObjects.Keys);
1265 UpdateParameterSet(operateOn, ref loc, parm, localID, val); 1170 UpdateParameterSet(operateOn, ref loc, parm, localID, val);
1266 } 1171 }
1267 1172
@@ -1284,7 +1189,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
1284 TaintedObject("BSScene.UpdateParameterSet", delegate() { 1189 TaintedObject("BSScene.UpdateParameterSet", delegate() {
1285 foreach (uint lID in objectIDs) 1190 foreach (uint lID in objectIDs)
1286 { 1191 {
1287 BulletSimAPI.UpdateParameter(m_worldID, lID, xparm, xval); 1192 BulletSimAPI.UpdateParameter(WorldID, lID, xparm, xval);
1288 } 1193 }
1289 }); 1194 });
1290 break; 1195 break;
@@ -1302,7 +1207,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
1302 string xparm = parm.ToLower(); 1207 string xparm = parm.ToLower();
1303 float xval = val; 1208 float xval = val;
1304 TaintedObject("BSScene.TaintedUpdateParameter", delegate() { 1209 TaintedObject("BSScene.TaintedUpdateParameter", delegate() {
1305 BulletSimAPI.UpdateParameter(m_worldID, xlocalID, xparm, xval); 1210 BulletSimAPI.UpdateParameter(WorldID, xlocalID, xparm, xval);
1306 }); 1211 });
1307 } 1212 }
1308 1213
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
new file mode 100755
index 0000000..d48462e
--- /dev/null
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs
@@ -0,0 +1,480 @@
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 copyrightD
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 */
27using System;
28using System.Collections.Generic;
29using System.Text;
30
31using OpenSim.Framework;
32using OpenSim.Region.Framework;
33using OpenSim.Region.CoreModules;
34using OpenSim.Region.Physics.Manager;
35
36using Nini.Config;
37using log4net;
38
39using OpenMetaverse;
40
41namespace OpenSim.Region.Physics.BulletSPlugin
42{
43public class BSTerrainManager
44{
45 static string LogHeader = "[BULLETSIM TERRAIN MANAGER]";
46
47 // These height values are fractional so the odd values will be
48 // noticable when debugging.
49 public const float HEIGHT_INITIALIZATION = 24.987f;
50 public const float HEIGHT_INITIAL_LASTHEIGHT = 24.876f;
51 public const float HEIGHT_GETHEIGHT_RET = 24.765f;
52
53 // If the min and max height are equal, we reduce the min by this
54 // amount to make sure that a bounding box is built for the terrain.
55 public const float HEIGHT_EQUAL_FUDGE = 0.2f;
56
57 public const float TERRAIN_COLLISION_MARGIN = 0.0f;
58
59 // Until the whole simulator is changed to pass us the region size, we rely on constants.
60 public Vector3 DefaultRegionSize = new Vector3(Constants.RegionSize, Constants.RegionSize, 0f);
61
62 // The scene that I am part of
63 private BSScene m_physicsScene;
64
65 // The ground plane created to keep thing from falling to infinity.
66 private BulletBody m_groundPlane;
67
68 // If doing mega-regions, if we're region zero we will be managing multiple
69 // region terrains since region zero does the physics for the whole mega-region.
70 private Dictionary<Vector2, BulletHeightMapInfo> m_heightMaps;
71
72 // True of the terrain has been modified.
73 // Used to force recalculation of terrain height after terrain has been modified
74 private bool m_terrainModified;
75
76 // If we are doing mega-regions, terrains are added from TERRAIN_ID to m_terrainCount.
77 // This is incremented before assigning to new region so it is the last ID allocated.
78 private uint m_terrainCount = BSScene.CHILDTERRAIN_ID - 1;
79 public uint HighestTerrainID { get {return m_terrainCount; } }
80
81 // If doing mega-regions, this holds our offset from region zero of
82 // the mega-regions. "parentScene" points to the PhysicsScene of region zero.
83 private Vector3 m_worldOffset;
84 // If the parent region (region 0), this is the extent of the combined regions
85 // relative to the origin of region zero
86 private Vector3 m_worldMax;
87 private PhysicsScene m_parentScene;
88
89 public BSTerrainManager(BSScene physicsScene)
90 {
91 m_physicsScene = physicsScene;
92 m_heightMaps = new Dictionary<Vector2,BulletHeightMapInfo>();
93 m_terrainModified = false;
94
95 // Assume one region of default size
96 m_worldOffset = Vector3.Zero;
97 m_worldMax = new Vector3(DefaultRegionSize.X, DefaultRegionSize.Y, 4096f);
98 m_parentScene = null;
99 }
100
101 // Create the initial instance of terrain and the underlying ground plane.
102 // The objects are allocated in the unmanaged space and the pointers are tracked
103 // by the managed code.
104 // The terrains and the groundPlane are not added to the list of PhysObjects.
105 // This is called from the initialization routine so we presume it is
106 // safe to call Bullet in real time. We hope no one is moving prims around yet.
107 public void CreateInitialGroundPlaneAndTerrain()
108 {
109 // The ground plane is here to catch things that are trying to drop to negative infinity
110 BulletShape groundPlaneShape = new BulletShape(BulletSimAPI.CreateGroundPlaneShape2(BSScene.GROUNDPLANE_ID, 1f, TERRAIN_COLLISION_MARGIN));
111 m_groundPlane = new BulletBody(BSScene.GROUNDPLANE_ID,
112 BulletSimAPI.CreateBodyWithDefaultMotionState2(groundPlaneShape.Ptr, Vector3.Zero, Quaternion.Identity));
113 BulletSimAPI.AddObjectToWorld2(m_physicsScene.World.Ptr, m_groundPlane.Ptr);
114
115 Vector3 minTerrainCoords = new Vector3(0f, 0f, HEIGHT_INITIALIZATION - HEIGHT_EQUAL_FUDGE);
116 Vector3 maxTerrainCoords = new Vector3(DefaultRegionSize.X, DefaultRegionSize.Y, HEIGHT_INITIALIZATION);
117 int totalHeights = (int)maxTerrainCoords.X * (int)maxTerrainCoords.Y;
118 float[] initialMap = new float[totalHeights];
119 for (int ii = 0; ii < totalHeights; ii++)
120 {
121 initialMap[ii] = HEIGHT_INITIALIZATION;
122 }
123 UpdateOrCreateTerrain(BSScene.TERRAIN_ID, initialMap, minTerrainCoords, maxTerrainCoords, true);
124 }
125
126 // Release all the terrain structures we might have allocated
127 public void ReleaseGroundPlaneAndTerrain()
128 {
129 if (m_groundPlane.Ptr != IntPtr.Zero)
130 {
131 if (BulletSimAPI.RemoveObjectFromWorld2(m_physicsScene.World.Ptr, m_groundPlane.Ptr))
132 {
133 BulletSimAPI.DestroyObject2(m_physicsScene.World.Ptr, m_groundPlane.Ptr);
134 }
135 m_groundPlane.Ptr = IntPtr.Zero;
136 }
137
138 ReleaseTerrain();
139 }
140
141 // Release all the terrain we have allocated
142 public void ReleaseTerrain()
143 {
144 foreach (KeyValuePair<Vector2, BulletHeightMapInfo> kvp in m_heightMaps)
145 {
146 if (BulletSimAPI.RemoveObjectFromWorld2(m_physicsScene.World.Ptr, kvp.Value.terrainBody.Ptr))
147 {
148 BulletSimAPI.DestroyObject2(m_physicsScene.World.Ptr, kvp.Value.terrainBody.Ptr);
149 BulletSimAPI.ReleaseHeightMapInfo2(kvp.Value.Ptr);
150 }
151 }
152 m_heightMaps.Clear();
153 }
154
155 // The simulator wants to set a new heightmap for the terrain.
156 public void SetTerrain(float[] heightMap) {
157 float[] localHeightMap = heightMap;
158 m_physicsScene.TaintedObject("TerrainManager.SetTerrain", delegate()
159 {
160 if (m_worldOffset != Vector3.Zero && m_parentScene != null)
161 {
162 // If a child of a mega-region, we shouldn't have any terrain allocated for us
163 ReleaseGroundPlaneAndTerrain();
164 // If doing the mega-prim stuff and we are the child of the zero region,
165 // the terrain is added to our parent
166 if (m_parentScene is BSScene)
167 {
168 DetailLog("{0},SetTerrain.ToParent,offset={1},worldMax={2}",
169 BSScene.DetailLogZero, m_worldOffset, m_worldMax);
170 ((BSScene)m_parentScene).TerrainManager.UpdateOrCreateTerrain(BSScene.CHILDTERRAIN_ID,
171 localHeightMap, m_worldOffset, m_worldOffset + DefaultRegionSize, true);
172 }
173 }
174 else
175 {
176 // If not doing the mega-prim thing, just change the terrain
177 DetailLog("{0},SetTerrain.Existing", BSScene.DetailLogZero);
178
179 UpdateOrCreateTerrain(BSScene.TERRAIN_ID, localHeightMap, m_worldOffset, m_worldOffset + DefaultRegionSize, true);
180 }
181 });
182 }
183
184 // If called with no mapInfo for the terrain, this will create a new mapInfo and terrain
185 // based on the passed information. The 'id' should be either the terrain id or
186 // BSScene.CHILDTERRAIN_ID. If the latter, a new child terrain ID will be allocated and used.
187 // The latter feature is for creating child terrains for mega-regions.
188 // If called with a mapInfo in m_heightMaps but the terrain has no body yet (mapInfo.terrainBody.Ptr == 0)
189 // then a new body and shape is created and the mapInfo is filled.
190 // This call is used for doing the initial terrain creation.
191 // If called with a mapInfo in m_heightMaps and there is an existing terrain body, a new
192 // terrain shape is created and added to the body.
193 // This call is most often used to update the heightMap and parameters of the terrain.
194 // The 'doNow' boolean says whether to do all the unmanaged activities right now (like when
195 // calling this routine from initialization or taint-time routines) or whether to delay
196 // all the unmanaged activities to taint-time.
197 private void UpdateOrCreateTerrain(uint id, float[] heightMap, Vector3 minCoords, Vector3 maxCoords, bool doNow)
198 {
199 DetailLog("{0},BSTerrainManager.UpdateOrCreateTerrain,call,minC={1},maxC={2},doNow={3}",
200 BSScene.DetailLogZero, minCoords, maxCoords, doNow);
201
202 float minZ = float.MaxValue;
203 float maxZ = float.MinValue;
204 Vector2 terrainRegionBase = new Vector2(minCoords.X, minCoords.Y);
205
206 int heightMapSize = heightMap.Length;
207 for (int ii = 0; ii < heightMapSize; ii++)
208 {
209 float height = heightMap[ii];
210 if (height < minZ) minZ = height;
211 if (height > maxZ) maxZ = height;
212 }
213
214 // The shape of the terrain is from its base to its extents.
215 minCoords.Z = minZ;
216 maxCoords.Z = maxZ;
217
218 BulletHeightMapInfo mapInfo;
219 if (m_heightMaps.TryGetValue(terrainRegionBase, out mapInfo))
220 {
221 // If this is terrain we know about, it's easy to update
222
223 mapInfo.heightMap = heightMap;
224 mapInfo.minCoords = minCoords;
225 mapInfo.maxCoords = maxCoords;
226 mapInfo.minZ = minZ;
227 mapInfo.maxZ = maxZ;
228 mapInfo.sizeX = maxCoords.X - minCoords.X;
229 mapInfo.sizeY = maxCoords.Y - minCoords.Y;
230 DetailLog("{0},UpdateOrCreateTerrain:UpdateExisting,call,terrainBase={1},minC={2}, maxC={3}, szX={4}, szY={5}",
231 BSScene.DetailLogZero, terrainRegionBase, mapInfo.minCoords, mapInfo.maxCoords, mapInfo.sizeX, mapInfo.sizeY);
232
233 BSScene.TaintCallback rebuildOperation = delegate()
234 {
235 if (m_parentScene != null)
236 {
237 // It's possible that Combine() was called after this code was queued.
238 // If we are a child of combined regions, we don't create any terrain for us.
239 DetailLog("{0},UpdateOrCreateTerrain:AmACombineChild,taint", BSScene.DetailLogZero);
240
241 // Get rid of any terrain that may have been allocated for us.
242 ReleaseGroundPlaneAndTerrain();
243
244 // I hate doing this, but just bail
245 return;
246 }
247
248 if (mapInfo.terrainBody.Ptr != IntPtr.Zero)
249 {
250 // Updating an existing terrain.
251 DetailLog("{0},UpdateOrCreateTerrain:UpdateExisting,taint,terrainBase={1},minC={2}, maxC={3}, szX={4}, szY={5}",
252 BSScene.DetailLogZero, terrainRegionBase, mapInfo.minCoords, mapInfo.maxCoords, mapInfo.sizeX, mapInfo.sizeY);
253
254 // Remove from the dynamics world because we're going to mangle this object
255 BulletSimAPI.RemoveObjectFromWorld2(m_physicsScene.World.Ptr, mapInfo.terrainBody.Ptr);
256
257 // Get rid of the old terrain
258 BulletSimAPI.DestroyObject2(m_physicsScene.World.Ptr, mapInfo.terrainBody.Ptr);
259 BulletSimAPI.ReleaseHeightMapInfo2(mapInfo.Ptr);
260 mapInfo.Ptr = IntPtr.Zero;
261
262 /*
263 // NOTE: This routine is half here because I can't get the terrain shape replacement
264 // to work. In the short term, the above three lines completely delete the old
265 // terrain and the code below recreates one from scratch.
266 // Hopefully the Bullet community will help me out on this one.
267
268 // First, release the old collision shape (there is only one terrain)
269 BulletSimAPI.DeleteCollisionShape2(m_physicsScene.World.Ptr, mapInfo.terrainShape.Ptr);
270
271 // Fill the existing height map info with the new location and size information
272 BulletSimAPI.FillHeightMapInfo2(m_physicsScene.World.Ptr, mapInfo.Ptr, mapInfo.ID,
273 mapInfo.minCoords, mapInfo.maxCoords, mapInfo.heightMap, TERRAIN_COLLISION_MARGIN);
274
275 // Create a terrain shape based on the new info
276 mapInfo.terrainShape = new BulletShape(BulletSimAPI.CreateTerrainShape2(mapInfo.Ptr));
277
278 // Stuff the shape into the existing terrain body
279 BulletSimAPI.SetBodyShape2(m_physicsScene.World.Ptr, mapInfo.terrainBody.Ptr, mapInfo.terrainShape.Ptr);
280 */
281 }
282 // else
283 {
284 // Creating a new terrain.
285 DetailLog("{0},UpdateOrCreateTerrain:CreateNewTerrain,taint,baseX={1},baseY={2},minZ={3},maxZ={4}",
286 BSScene.DetailLogZero, mapInfo.minCoords.X, mapInfo.minCoords.Y, minZ, maxZ);
287
288 mapInfo.ID = id;
289 mapInfo.Ptr = BulletSimAPI.CreateHeightMapInfo2(m_physicsScene.World.Ptr, mapInfo.ID,
290 mapInfo.minCoords, mapInfo.maxCoords, mapInfo.heightMap, TERRAIN_COLLISION_MARGIN);
291
292 // The terrain object initial position is at the center of the object
293 Vector3 centerPos;
294 centerPos.X = minCoords.X + (mapInfo.sizeX / 2f);
295 centerPos.Y = minCoords.Y + (mapInfo.sizeY / 2f);
296 centerPos.Z = minZ + ((maxZ - minZ) / 2f);
297
298 // Create the terrain shape from the mapInfo
299 mapInfo.terrainShape = new BulletShape(BulletSimAPI.CreateTerrainShape2(mapInfo.Ptr));
300
301 mapInfo.terrainBody = new BulletBody(mapInfo.ID,
302 BulletSimAPI.CreateBodyWithDefaultMotionState2(mapInfo.terrainShape.Ptr,
303 centerPos, Quaternion.Identity));
304 }
305
306 // Make sure the entry is in the heightmap table
307 m_heightMaps[terrainRegionBase] = mapInfo;
308
309 // Set current terrain attributes
310 BulletSimAPI.SetFriction2(mapInfo.terrainBody.Ptr, m_physicsScene.Params.terrainFriction);
311 BulletSimAPI.SetHitFraction2(mapInfo.terrainBody.Ptr, m_physicsScene.Params.terrainHitFraction);
312 BulletSimAPI.SetRestitution2(mapInfo.terrainBody.Ptr, m_physicsScene.Params.terrainRestitution);
313 BulletSimAPI.SetCollisionFlags2(mapInfo.terrainBody.Ptr, CollisionFlags.CF_STATIC_OBJECT);
314
315 BulletSimAPI.SetMassProps2(mapInfo.terrainBody.Ptr, 0f, Vector3.Zero);
316 BulletSimAPI.UpdateInertiaTensor2(mapInfo.terrainBody.Ptr);
317
318 // Return the new terrain to the world of physical objects
319 BulletSimAPI.AddObjectToWorld2(m_physicsScene.World.Ptr, mapInfo.terrainBody.Ptr);
320
321 // redo its bounding box now that it is in the world
322 BulletSimAPI.UpdateSingleAabb2(m_physicsScene.World.Ptr, mapInfo.terrainBody.Ptr);
323
324 // Make sure the new shape is processed.
325 BulletSimAPI.Activate2(mapInfo.terrainBody.Ptr, true);
326
327 m_terrainModified = true;
328 };
329
330 // There is the option to do the changes now (we're already in 'taint time'), or
331 // to do the Bullet operations later.
332 if (doNow)
333 rebuildOperation();
334 else
335 m_physicsScene.TaintedObject("BSScene.UpdateOrCreateTerrain:UpdateExisting", rebuildOperation);
336 }
337 else
338 {
339 // We don't know about this terrain so either we are creating a new terrain or
340 // our mega-prim child is giving us a new terrain to add to the phys world
341
342 // if this is a child terrain, calculate a unique terrain id
343 uint newTerrainID = id;
344 if (newTerrainID >= BSScene.CHILDTERRAIN_ID)
345 newTerrainID = ++m_terrainCount;
346
347 float[] heightMapX = heightMap;
348 Vector3 minCoordsX = minCoords;
349 Vector3 maxCoordsX = maxCoords;
350
351 DetailLog("{0},UpdateOrCreateTerrain:NewTerrain,call,id={1}, minC={2}, maxC={3}",
352 BSScene.DetailLogZero, newTerrainID, minCoords, minCoords);
353
354 // Code that must happen at taint-time
355 BSScene.TaintCallback createOperation = delegate()
356 {
357 DetailLog("{0},UpdateOrCreateTerrain:NewTerrain,taint,baseX={1},baseY={2}", BSScene.DetailLogZero, minCoords.X, minCoords.Y);
358 // Create a new mapInfo that will be filled with the new info
359 mapInfo = new BulletHeightMapInfo(id, heightMapX,
360 BulletSimAPI.CreateHeightMapInfo2(m_physicsScene.World.Ptr, newTerrainID,
361 minCoordsX, maxCoordsX, heightMapX, TERRAIN_COLLISION_MARGIN));
362 // Put the unfilled heightmap info into the collection of same
363 m_heightMaps.Add(terrainRegionBase, mapInfo);
364 // Build the terrain
365 UpdateOrCreateTerrain(newTerrainID, heightMap, minCoords, maxCoords, true);
366
367 m_terrainModified = true;
368 };
369
370 // If already in taint-time, just call Bullet. Otherwise queue the operations for the safe time.
371 if (doNow)
372 createOperation();
373 else
374 m_physicsScene.TaintedObject("BSScene.UpdateOrCreateTerrain:NewTerrain", createOperation);
375 }
376 }
377
378 // Someday we will have complex terrain with caves and tunnels
379 public float GetTerrainHeightAtXYZ(Vector3 loc)
380 {
381 // For the moment, it's flat and convex
382 return GetTerrainHeightAtXY(loc.X, loc.Y);
383 }
384
385 // Given an X and Y, find the height of the terrain.
386 // Since we could be handling multiple terrains for a mega-region,
387 // the base of the region is calcuated assuming all regions are
388 // the same size and that is the default.
389 // Once the heightMapInfo is found, we have all the information to
390 // compute the offset into the array.
391 private float lastHeightTX = 999999f;
392 private float lastHeightTY = 999999f;
393 private float lastHeight = HEIGHT_INITIAL_LASTHEIGHT;
394 private float GetTerrainHeightAtXY(float tX, float tY)
395 {
396 // You'd be surprized at the number of times this routine is called
397 // with the same parameters as last time.
398 if (!m_terrainModified && lastHeightTX == tX && lastHeightTY == tY)
399 return lastHeight;
400
401 lastHeightTX = tX;
402 lastHeightTY = tY;
403 float ret = HEIGHT_GETHEIGHT_RET;
404
405 int offsetX = ((int)(tX / (int)DefaultRegionSize.X)) * (int)DefaultRegionSize.X;
406 int offsetY = ((int)(tY / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y;
407 Vector2 terrainBaseXY = new Vector2(offsetX, offsetY);
408
409 BulletHeightMapInfo mapInfo;
410 if (m_heightMaps.TryGetValue(terrainBaseXY, out mapInfo))
411 {
412 float regionX = tX - offsetX;
413 float regionY = tY - offsetY;
414 int mapIndex = (int)regionY * (int)mapInfo.sizeY + (int)regionX;
415 try
416 {
417 ret = mapInfo.heightMap[mapIndex];
418 }
419 catch
420 {
421 // Sometimes they give us wonky values of X and Y. Give a warning and return something.
422 m_physicsScene.Logger.WarnFormat("{0} Bad request for terrain height. terrainBase={1}, x={2}, y={3}",
423 LogHeader, terrainBaseXY, regionX, regionY);
424 ret = HEIGHT_GETHEIGHT_RET;
425 }
426 // DetailLog("{0},BSTerrainManager.GetTerrainHeightAtXY,bX={1},baseY={2},szX={3},szY={4},regX={5},regY={6},index={7},ht={8}",
427 // BSScene.DetailLogZero, offsetX, offsetY, mapInfo.sizeX, mapInfo.sizeY, regionX, regionY, mapIndex, ret);
428 }
429 else
430 {
431 m_physicsScene.Logger.ErrorFormat("{0} GetTerrainHeightAtXY: terrain not found: region={1}, x={2}, y={3}",
432 LogHeader, m_physicsScene.RegionName, tX, tY);
433 }
434 m_terrainModified = false;
435 lastHeight = ret;
436 return ret;
437 }
438
439 // Although no one seems to check this, I do support combining.
440 public bool SupportsCombining()
441 {
442 return true;
443 }
444
445 // This routine is called two ways:
446 // One with 'offset' and 'pScene' zero and null but 'extents' giving the maximum
447 // extent of the combined regions. This is to inform the parent of the size
448 // of the combined regions.
449 // and one with 'offset' as the offset of the child region to the base region,
450 // 'pScene' pointing to the parent and 'extents' of zero. This informs the
451 // child of its relative base and new parent.
452 public void Combine(PhysicsScene pScene, Vector3 offset, Vector3 extents)
453 {
454 m_worldOffset = offset;
455 m_worldMax = extents;
456 m_parentScene = pScene;
457 if (pScene != null)
458 {
459 // We are a child.
460 // We want m_worldMax to be the highest coordinate of our piece of terrain.
461 m_worldMax = offset + DefaultRegionSize;
462 }
463 DetailLog("{0},BSTerrainManager.Combine,offset={1},extents={2},wOffset={3},wMax={4}",
464 BSScene.DetailLogZero, offset, extents, m_worldOffset, m_worldMax);
465 }
466
467 // Unhook all the combining that I know about.
468 public void UnCombine(PhysicsScene pScene)
469 {
470 // Just like ODE, for the moment a NOP
471 DetailLog("{0},BSTerrainManager.UnCombine", BSScene.DetailLogZero);
472 }
473
474
475 private void DetailLog(string msg, params Object[] args)
476 {
477 m_physicsScene.PhysicsLogging.Write(msg, args);
478 }
479}
480}
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
index 504bd3c..9221cdb 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs
@@ -33,15 +33,25 @@ using OpenMetaverse;
33namespace OpenSim.Region.Physics.BulletSPlugin { 33namespace OpenSim.Region.Physics.BulletSPlugin {
34 34
35// Classes to allow some type checking for the API 35// Classes to allow some type checking for the API
36// These hold pointers to allocated objects in the unmanaged space.
37
38// The physics engine controller class created at initialization
36public struct BulletSim 39public struct BulletSim
37{ 40{
38 public BulletSim(uint id, BSScene bss, IntPtr xx) { ID = id; scene = bss; Ptr = xx; } 41 public BulletSim(uint worldId, BSScene bss, IntPtr xx) { worldID = worldId; scene = bss; Ptr = xx; }
39 public uint ID; 42 public uint worldID;
40 // The scene is only in here so very low level routines have a handle to print debug/error messages 43 // The scene is only in here so very low level routines have a handle to print debug/error messages
41 public BSScene scene; 44 public BSScene scene;
42 public IntPtr Ptr; 45 public IntPtr Ptr;
43} 46}
44 47
48public struct BulletShape
49{
50 public BulletShape(IntPtr xx) { Ptr = xx; }
51 public IntPtr Ptr;
52}
53
54// An allocated Bullet btRigidBody
45public struct BulletBody 55public struct BulletBody
46{ 56{
47 public BulletBody(uint id, IntPtr xx) { ID = id; Ptr = xx; } 57 public BulletBody(uint id, IntPtr xx) { ID = id; Ptr = xx; }
@@ -49,12 +59,41 @@ public struct BulletBody
49 public uint ID; 59 public uint ID;
50} 60}
51 61
62// An allocated Bullet btConstraint
52public struct BulletConstraint 63public struct BulletConstraint
53{ 64{
54 public BulletConstraint(IntPtr xx) { Ptr = xx; } 65 public BulletConstraint(IntPtr xx) { Ptr = xx; }
55 public IntPtr Ptr; 66 public IntPtr Ptr;
56} 67}
57 68
69// An allocated HeightMapThing which hold various heightmap info
70// Made a class rather than a struct so there would be only one
71// instance of this and C# will pass around pointers rather
72// than making copies.
73public class BulletHeightMapInfo
74{
75 public BulletHeightMapInfo(uint id, float[] hm, IntPtr xx) {
76 ID = id;
77 Ptr = xx;
78 heightMap = hm;
79 terrainRegionBase = new Vector2(0f, 0f);
80 minCoords = new Vector3(100f, 100f, 25f);
81 maxCoords = new Vector3(101f, 101f, 26f);
82 minZ = maxZ = 0f;
83 sizeX = sizeY = 256f;
84 }
85 public uint ID;
86 public IntPtr Ptr;
87 public float[] heightMap;
88 public Vector2 terrainRegionBase;
89 public Vector3 minCoords;
90 public Vector3 maxCoords;
91 public float sizeX, sizeY;
92 public float minZ, maxZ;
93 public BulletShape terrainShape;
94 public BulletBody terrainBody;
95}
96
58// =============================================================================== 97// ===============================================================================
59[StructLayout(LayoutKind.Sequential)] 98[StructLayout(LayoutKind.Sequential)]
60public struct ConvexHull 99public struct ConvexHull
@@ -174,12 +213,26 @@ public struct ConfigurationParameters
174 public float linkConstraintTransMotorMaxForce; 213 public float linkConstraintTransMotorMaxForce;
175 public float linkConstraintERP; 214 public float linkConstraintERP;
176 public float linkConstraintCFM; 215 public float linkConstraintCFM;
216 public float linkConstraintSolverIterations;
177 217
178 public const float numericTrue = 1f; 218 public const float numericTrue = 1f;
179 public const float numericFalse = 0f; 219 public const float numericFalse = 0f;
180} 220}
181 221
182// Values used by Bullet and BulletSim to control collisions 222
223// The states a bullet collision object can have
224public enum ActivationState : uint
225{
226 ACTIVE_TAG = 1,
227 ISLAND_SLEEPING,
228 WANTS_DEACTIVATION,
229 DISABLE_DEACTIVATION,
230 DISABLE_SIMULATION
231}
232
233// Values used by Bullet and BulletSim to control object properties.
234// Bullet's "CollisionFlags" has more to do with operations on the
235// object (if collisions happen, if gravity effects it, ...).
183public enum CollisionFlags : uint 236public enum CollisionFlags : uint
184{ 237{
185 CF_STATIC_OBJECT = 1 << 0, 238 CF_STATIC_OBJECT = 1 << 0,
@@ -194,8 +247,75 @@ public enum CollisionFlags : uint
194 BS_VOLUME_DETECT_OBJECT = 1 << 11, 247 BS_VOLUME_DETECT_OBJECT = 1 << 11,
195 BS_PHANTOM_OBJECT = 1 << 12, 248 BS_PHANTOM_OBJECT = 1 << 12,
196 BS_PHYSICAL_OBJECT = 1 << 13, 249 BS_PHYSICAL_OBJECT = 1 << 13,
250 BS_TERRAIN_OBJECT = 1 << 14,
251 BS_NONE = 0,
252 BS_ALL = 0xFFFFFFFF
253};
254
255// Values for collisions groups and masks
256public enum CollisionFilterGroups : uint
257{
258 NoneFilter = 0,
259 DefaultFilter = 1 << 0,
260 StaticFilter = 1 << 1,
261 KinematicFilter = 1 << 2,
262 DebrisFilter = 1 << 3,
263 SensorTrigger = 1 << 4,
264 CharacterFilter = 1 << 5,
265 AllFilter = 0xFFFFFFFF,
266 // Filter groups defined by BulletSim
267 GroundPlaneFilter = 1 << 10,
268 TerrainFilter = 1 << 11,
269 RaycastFilter = 1 << 12,
270 SolidFilter = 1 << 13,
197}; 271};
198 272
273 // For each type, we first clear and then set the collision flags
274public enum ClearCollisionFlag : uint
275{
276 Terrain = CollisionFlags.BS_ALL,
277 Phantom = CollisionFlags.BS_ALL,
278 VolumeDetect = CollisionFlags.BS_ALL,
279 PhysicalObject = CollisionFlags.BS_ALL,
280 StaticObject = CollisionFlags.BS_ALL
281}
282
283public enum SetCollisionFlag : uint
284{
285 Terrain = CollisionFlags.CF_STATIC_OBJECT
286 | CollisionFlags.BS_TERRAIN_OBJECT,
287 Phantom = CollisionFlags.CF_STATIC_OBJECT
288 | CollisionFlags.BS_PHANTOM_OBJECT
289 | CollisionFlags.CF_NO_CONTACT_RESPONSE,
290 VolumeDetect = CollisionFlags.CF_STATIC_OBJECT
291 | CollisionFlags.BS_VOLUME_DETECT_OBJECT
292 | CollisionFlags.CF_NO_CONTACT_RESPONSE,
293 PhysicalObject = CollisionFlags.BS_PHYSICAL_OBJECT,
294 StaticObject = CollisionFlags.CF_STATIC_OBJECT,
295}
296
297// Collision filters used for different types of objects
298public enum SetCollisionFilter : uint
299{
300 Terrain = CollisionFilterGroups.AllFilter,
301 Phantom = CollisionFilterGroups.GroundPlaneFilter
302 | CollisionFilterGroups.TerrainFilter,
303 VolumeDetect = CollisionFilterGroups.AllFilter,
304 PhysicalObject = CollisionFilterGroups.AllFilter,
305 StaticObject = CollisionFilterGroups.AllFilter,
306}
307
308// Collision masks used for different types of objects
309public enum SetCollisionMask : uint
310{
311 Terrain = CollisionFilterGroups.AllFilter,
312 Phantom = CollisionFilterGroups.GroundPlaneFilter
313 | CollisionFilterGroups.TerrainFilter,
314 VolumeDetect = CollisionFilterGroups.AllFilter,
315 PhysicalObject = CollisionFilterGroups.AllFilter,
316 StaticObject = CollisionFilterGroups.AllFilter
317}
318
199// CFM controls the 'hardness' of the constraint. 0=fixed, 0..1=violatable. Default=0 319// CFM controls the 'hardness' of the constraint. 0=fixed, 0..1=violatable. Default=0
200// ERP controls amount of correction per tick. Usable range=0.1..0.8. Default=0.2. 320// ERP controls amount of correction per tick. Usable range=0.1..0.8. Default=0.2.
201public enum ConstraintParams : int 321public enum ConstraintParams : int
@@ -221,6 +341,10 @@ public enum ConstraintParamAxis : int
221// =============================================================================== 341// ===============================================================================
222static class BulletSimAPI { 342static class BulletSimAPI {
223 343
344// Link back to the managed code for outputting log messages
345[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
346public delegate void DebugLogCallback([MarshalAs(UnmanagedType.LPStr)]string msg);
347
224[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 348[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
225[return: MarshalAs(UnmanagedType.LPStr)] 349[return: MarshalAs(UnmanagedType.LPStr)]
226public static extern string GetVersion(); 350public static extern string GetVersion();
@@ -228,7 +352,11 @@ public static extern string GetVersion();
228[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 352[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
229public static extern uint Initialize(Vector3 maxPosition, IntPtr parms, 353public static extern uint Initialize(Vector3 maxPosition, IntPtr parms,
230 int maxCollisions, IntPtr collisionArray, 354 int maxCollisions, IntPtr collisionArray,
231 int maxUpdates, IntPtr updateArray); 355 int maxUpdates, IntPtr updateArray,
356 DebugLogCallback logRoutine);
357
358[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
359public static extern void CreateInitialGroundPlaneAndTerrain(uint worldID);
232 360
233[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 361[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
234public static extern void SetHeightmap(uint worldID, [MarshalAs(UnmanagedType.LPArray)] float[] heightMap); 362public static extern void SetHeightmap(uint worldID, [MarshalAs(UnmanagedType.LPArray)] float[] heightMap);
@@ -268,23 +396,6 @@ public static extern bool DestroyMesh(uint worldID, System.UInt64 meshKey);
268[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 396[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
269public static extern bool CreateObject(uint worldID, ShapeData shapeData); 397public static extern bool CreateObject(uint worldID, ShapeData shapeData);
270 398
271/* Remove old functionality
272[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
273public static extern void CreateLinkset(uint worldID, int objectCount, ShapeData[] shapeDatas);
274
275[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
276public static extern void AddConstraint(uint worldID, uint id1, uint id2,
277 Vector3 frame1, Quaternion frame1rot,
278 Vector3 frame2, Quaternion frame2rot,
279 Vector3 lowLinear, Vector3 hiLinear, Vector3 lowAngular, Vector3 hiAngular);
280
281[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
282public static extern bool RemoveConstraintByID(uint worldID, uint id1);
283
284[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
285public static extern bool RemoveConstraint(uint worldID, uint id1, uint id2);
286 */
287
288[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 399[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
289public static extern Vector3 GetObjectPosition(uint WorldID, uint id); 400public static extern Vector3 GetObjectPosition(uint WorldID, uint id);
290 401
@@ -300,6 +411,7 @@ public static extern bool SetObjectVelocity(uint worldID, uint id, Vector3 veloc
300[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 411[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
301public static extern bool SetObjectAngularVelocity(uint worldID, uint id, Vector3 angularVelocity); 412public static extern bool SetObjectAngularVelocity(uint worldID, uint id, Vector3 angularVelocity);
302 413
414// Set the current force acting on the object
303[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 415[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
304public static extern bool SetObjectForce(uint worldID, uint id, Vector3 force); 416public static extern bool SetObjectForce(uint worldID, uint id, Vector3 force);
305 417
@@ -342,8 +454,6 @@ public static extern Vector3 RecoverFromPenetration(uint worldID, uint id);
342public static extern void DumpBulletStatistics(); 454public static extern void DumpBulletStatistics();
343 455
344// Log a debug message 456// Log a debug message
345[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
346public delegate void DebugLogCallback([MarshalAs(UnmanagedType.LPStr)]string msg);
347[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 457[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
348public static extern void SetDebugLogCallback(DebugLogCallback callback); 458public static extern void SetDebugLogCallback(DebugLogCallback callback);
349 459
@@ -358,6 +468,7 @@ public static extern void SetDebugLogCallback(DebugLogCallback callback);
358// The names have a "2" tacked on. This will be removed as the C# code gets rebuilt 468// The names have a "2" tacked on. This will be removed as the C# code gets rebuilt
359// and the old code is removed. 469// and the old code is removed.
360 470
471// Functions use while converting from API1 to API2. Can be removed when totally converted.
361[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 472[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
362public static extern IntPtr GetSimHandle2(uint worldID); 473public static extern IntPtr GetSimHandle2(uint worldID);
363 474
@@ -368,6 +479,7 @@ public static extern IntPtr GetBodyHandleWorldID2(uint worldID, uint id);
368public static extern IntPtr GetBodyHandle2(IntPtr world, uint id); 479public static extern IntPtr GetBodyHandle2(IntPtr world, uint id);
369 480
370// =============================================================================== 481// ===============================================================================
482// Initialization and simulation
371[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 483[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
372public static extern IntPtr Initialize2(Vector3 maxPosition, IntPtr parms, 484public static extern IntPtr Initialize2(Vector3 maxPosition, IntPtr parms,
373 int maxCollisions, IntPtr collisionArray, 485 int maxCollisions, IntPtr collisionArray,
@@ -377,7 +489,7 @@ public static extern IntPtr Initialize2(Vector3 maxPosition, IntPtr parms,
377public static extern bool UpdateParameter2(IntPtr world, uint localID, String parm, float value); 489public static extern bool UpdateParameter2(IntPtr world, uint localID, String parm, float value);
378 490
379[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 491[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
380public static extern void SetHeightmap2(IntPtr world, float[] heightmap); 492public static extern void SetHeightMap2(IntPtr world, float[] heightmap);
381 493
382[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 494[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
383public static extern void Shutdown2(IntPtr sim); 495public static extern void Shutdown2(IntPtr sim);
@@ -392,23 +504,78 @@ public static extern int PhysicsStep2(IntPtr world, float timeStep, int maxSubSt
392[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 504[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
393public static extern bool PushUpdate2(IntPtr obj); 505public static extern bool PushUpdate2(IntPtr obj);
394 506
395/* 507// =====================================================================================
508// Mesh, hull, shape and body creation helper routines
509[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
510public static extern IntPtr CreateMeshShape2(IntPtr world,
511 int indicesCount, [MarshalAs(UnmanagedType.LPArray)] int[] indices,
512 int verticesCount, [MarshalAs(UnmanagedType.LPArray)] float[] vertices );
513
514[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
515public static extern IntPtr CreateHullShape2(IntPtr world,
516 int hullCount, [MarshalAs(UnmanagedType.LPArray)] float[] hulls);
517
518[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
519public static extern IntPtr BuildHullShape2(IntPtr world, IntPtr meshShape);
520
521[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
522public static extern IntPtr BuildNativeShape2(IntPtr world,
523 float shapeType, float collisionMargin, Vector3 scale);
524
525[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
526public static extern bool IsNativeShape2(IntPtr shape);
527
528[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
529public static extern IntPtr CreateCompoundShape2(IntPtr sim);
530
531[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
532public static extern void AddChildToCompoundShape2(IntPtr cShape, IntPtr addShape, Vector3 pos, Quaternion rot);
533
534[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
535public static extern void RemoveChildFromCompoundShape2(IntPtr cShape, IntPtr removeShape);
536
537[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
538public static extern IntPtr CreateBodyFromShapeAndInfo2(IntPtr sim, IntPtr shape, IntPtr constructionInfo);
539
540[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
541public static extern bool DeleteCollisionShape2(IntPtr world, IntPtr shape);
542
396[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 543[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
397public static extern IntPtr CreateMesh2(IntPtr world, int indicesCount, int* indices, int verticesCount, float* vertices ); 544public static extern IntPtr CreateBodyFromShape2(IntPtr sim, IntPtr shape, Vector3 pos, Quaternion rot);
398 545
399[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 546[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
400public static extern bool BuildHull2(IntPtr world, IntPtr mesh); 547public static extern IntPtr CreateBodyWithDefaultMotionState2(IntPtr shape, Vector3 pos, Quaternion rot);
401 548
402[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 549[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
403public static extern bool ReleaseHull2(IntPtr world, IntPtr mesh); 550public static extern IntPtr AllocateBodyInfo2(IntPtr obj);
404 551
405[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 552[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
406public static extern bool DestroyMesh2(IntPtr world, IntPtr mesh); 553public static extern void ReleaseBodyInfo2(IntPtr obj);
407 554
408[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 555[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
409public static extern IntPtr CreateObject2(IntPtr world, ShapeData shapeData); 556public static extern void DestroyObject2(IntPtr sim, IntPtr obj);
410*/
411 557
558// =====================================================================================
559// Terrain creation and helper routines
560[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
561public static extern IntPtr CreateHeightMapInfo2(IntPtr sim, uint id, Vector3 minCoords, Vector3 maxCoords,
562 [MarshalAs(UnmanagedType.LPArray)] float[] heightMap, float collisionMargin);
563
564[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
565public static extern IntPtr FillHeightMapInfo2(IntPtr sim, IntPtr mapInfo, uint id, Vector3 minCoords, Vector3 maxCoords,
566 [MarshalAs(UnmanagedType.LPArray)] float[] heightMap, float collisionMargin);
567
568[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
569public static extern bool ReleaseHeightMapInfo2(IntPtr heightMapInfo);
570
571[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
572public static extern IntPtr CreateGroundPlaneShape2(uint id, float height, float collisionMargin);
573
574[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
575public static extern IntPtr CreateTerrainShape2(IntPtr mapInfo);
576
577// =====================================================================================
578// Constraint creation and helper routines
412[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 579[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
413public static extern IntPtr Create6DofConstraint2(IntPtr world, IntPtr obj1, IntPtr obj2, 580public static extern IntPtr Create6DofConstraint2(IntPtr world, IntPtr obj1, IntPtr obj2,
414 Vector3 frame1loc, Quaternion frame1rot, 581 Vector3 frame1loc, Quaternion frame1rot,
@@ -460,11 +627,108 @@ public static extern bool SetConstraintParam2(IntPtr constrain, ConstraintParams
460[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 627[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
461public static extern bool DestroyConstraint2(IntPtr world, IntPtr constrain); 628public static extern bool DestroyConstraint2(IntPtr world, IntPtr constrain);
462 629
630// =====================================================================================
631// btCollisionWorld entries
632[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
633public static extern void UpdateSingleAabb2(IntPtr world, IntPtr obj);
634
635[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
636public static extern void UpdateAabbs2(IntPtr world);
637
638[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
639public static extern bool GetForceUpdateAllAabbs2(IntPtr world);
640
641[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
642public static extern void SetForceUpdateAllAabbs2(IntPtr world, bool force);
643
644// =====================================================================================
645// btDynamicsWorld entries
646[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
647public static extern bool AddObjectToWorld2(IntPtr world, IntPtr obj);
648
649[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
650public static extern bool RemoveObjectFromWorld2(IntPtr world, IntPtr obj);
651
652[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
653public static extern bool AddConstraintToWorld2(IntPtr world, IntPtr constrain, bool disableCollisionsBetweenLinkedObjects);
654
655[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
656public static extern bool RemoveConstraintFromWorld2(IntPtr world, IntPtr constrain);
657// =====================================================================================
658// btCollisionObject entries
659[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
660public static extern Vector3 GetAnisotripicFriction2(IntPtr constrain);
661
662[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
663public static extern Vector3 SetAnisotripicFriction2(IntPtr constrain, Vector3 frict);
664
665[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
666public static extern bool HasAnisotripicFriction2(IntPtr constrain);
667
668[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
669public static extern void SetContactProcessingThreshold2(IntPtr obj, float val);
670
463[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 671[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
464public static extern Vector3 AddObjectToWorld2(IntPtr world, IntPtr obj); 672public static extern float GetContactProcessingThreshold2(IntPtr obj);
465 673
466[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 674[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
467public static extern Vector3 RemoveObjectFromWorld2(IntPtr world, IntPtr obj); 675public static extern bool IsStaticObject2(IntPtr obj);
676
677[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
678public static extern bool IsKinematicObject2(IntPtr obj);
679
680[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
681public static extern bool IsStaticOrKinematicObject2(IntPtr obj);
682
683[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
684public static extern bool HasContactResponse2(IntPtr obj);
685
686[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
687public static extern void SetCollisionShape2(IntPtr sim, IntPtr obj, IntPtr shape);
688
689[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
690public static extern IntPtr GetCollisionShape2(IntPtr obj);
691
692[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
693public static extern int GetActivationState2(IntPtr obj);
694
695[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
696public static extern void SetActivationState2(IntPtr obj, int state);
697
698[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
699public static extern void SetDeactivationTime2(IntPtr obj, float dtime);
700
701[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
702public static extern float GetDeactivationTime2(IntPtr obj);
703
704[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
705public static extern void ForceActivationState2(IntPtr obj, ActivationState state);
706
707[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
708public static extern void Activate2(IntPtr obj, bool forceActivation);
709
710[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
711public static extern bool IsActive2(IntPtr obj);
712
713[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
714public static extern void SetRestitution2(IntPtr obj, float val);
715
716[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
717public static extern float GetRestitution2(IntPtr obj);
718
719[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
720public static extern void SetFriction2(IntPtr obj, float val);
721
722[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
723public static extern float GetFriction2(IntPtr obj);
724
725 /* Haven't defined the type 'Transform'
726[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
727public static extern Transform GetWorldTransform2(IntPtr obj);
728
729[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
730public static extern void setWorldTransform2(IntPtr obj, Transform trans);
731 */
468 732
469[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 733[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
470public static extern Vector3 GetPosition2(IntPtr obj); 734public static extern Vector3 GetPosition2(IntPtr obj);
@@ -473,85 +737,293 @@ public static extern Vector3 GetPosition2(IntPtr obj);
473public static extern Quaternion GetOrientation2(IntPtr obj); 737public static extern Quaternion GetOrientation2(IntPtr obj);
474 738
475[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 739[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
476public static extern bool SetTranslation2(IntPtr obj, Vector3 position, Quaternion rotation); 740public static extern void SetTranslation2(IntPtr obj, Vector3 position, Quaternion rotation);
477 741
478[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 742[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
479public static extern bool SetVelocity2(IntPtr obj, Vector3 velocity); 743public static extern IntPtr GetBroadphaseHandle2(IntPtr obj);
480 744
481[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 745[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
482public static extern bool SetAngularVelocity2(IntPtr obj, Vector3 angularVelocity); 746public static extern void SetBroadphaseHandle2(IntPtr obj, IntPtr handle);
483 747
748 /*
484[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 749[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
485public static extern bool SetObjectForce2(IntPtr obj, Vector3 force); 750public static extern Transform GetInterpolationWorldTransform2(IntPtr obj);
486 751
487[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 752[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
488public static extern bool AddObjectForce2(IntPtr obj, Vector3 force); 753public static extern void SetInterpolationWorldTransform2(IntPtr obj, Transform trans);
754 */
489 755
490[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 756[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
491public static extern bool SetCcdMotionThreshold2(IntPtr obj, float val); 757public static extern void SetInterpolationLinearVelocity2(IntPtr obj, Vector3 vel);
492 758
493[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 759[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
494public static extern bool SetCcdSweepSphereRadius2(IntPtr obj, float val); 760public static extern void SetInterpolationAngularVelocity2(IntPtr obj, Vector3 vel);
495 761
496[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 762[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
497public static extern bool SetDamping2(IntPtr obj, float lin_damping, float ang_damping); 763public static extern void SetInterpolationVelocity2(IntPtr obj, Vector3 linearVel, Vector3 angularVel);
498 764
499[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 765[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
500public static extern bool SetDeactivationTime2(IntPtr obj, float val); 766public static extern float GetHitFraction2(IntPtr obj);
501 767
502[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 768[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
503public static extern bool SetSleepingThresholds2(IntPtr obj, float lin_threshold, float ang_threshold); 769public static extern void SetHitFraction2(IntPtr obj, float val);
504 770
505[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 771[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
506public static extern bool SetContactProcessingThreshold2(IntPtr obj, float val); 772public static extern CollisionFlags GetCollisionFlags2(IntPtr obj);
507 773
508[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 774[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
509public static extern bool SetFriction2(IntPtr obj, float val); 775public static extern CollisionFlags SetCollisionFlags2(IntPtr obj, CollisionFlags flags);
510 776
511[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 777[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
512public static extern bool SetRestitution2(IntPtr obj, float val); 778public static extern CollisionFlags AddToCollisionFlags2(IntPtr obj, CollisionFlags flags);
513 779
514[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 780[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
515public static extern bool SetLinearVelocity2(IntPtr obj, Vector3 val); 781public static extern CollisionFlags RemoveFromCollisionFlags2(IntPtr obj, CollisionFlags flags);
516 782
517[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 783[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
518public static extern bool SetInterpolation2(IntPtr obj, Vector3 lin, Vector3 ang); 784public static extern float GetCcdMotionThreshold2(IntPtr obj);
519 785
520[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 786[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
521public static extern CollisionFlags GetCollisionFlags2(IntPtr obj); 787public static extern void SetCcdMotionThreshold2(IntPtr obj, float val);
788
789[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
790public static extern float GetCcdSweepSphereRadius2(IntPtr obj);
791
792[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
793public static extern void SetCcdSweepSphereRadius2(IntPtr obj, float val);
794
795[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
796public static extern IntPtr GetUserPointer2(IntPtr obj);
797
798[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
799public static extern void SetUserPointer2(IntPtr obj, IntPtr val);
800
801// =====================================================================================
802// btRigidBody entries
803[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
804public static extern void ApplyGravity2(IntPtr obj);
805
806[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
807public static extern void SetGravity2(IntPtr obj, Vector3 val);
808
809[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
810public static extern Vector3 GetGravity2(IntPtr obj);
811
812[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
813public static extern void SetDamping2(IntPtr obj, float lin_damping, float ang_damping);
814
815[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
816public static extern float GetLinearDamping2(IntPtr obj);
817
818[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
819public static extern float GetAngularDamping2(IntPtr obj);
820
821[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
822public static extern float GetLinearSleepingThreshold2(IntPtr obj);
823
824[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
825public static extern float GetAngularSleepingThreshold2(IntPtr obj);
826
827[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
828public static extern void ApplyDamping2(IntPtr obj, float timeStep);
829
830[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
831public static extern void SetMassProps2(IntPtr obj, float mass, Vector3 inertia);
832
833[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
834public static extern Vector3 GetLinearFactor2(IntPtr obj);
835
836[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
837public static extern void SetLinearFactor2(IntPtr obj, Vector3 factor);
838
839 /*
840[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
841public static extern void SetCenterOfMassTransform2(IntPtr obj, Transform trans);
842 */
843
844[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
845public static extern void SetCenterOfMassByPosRot2(IntPtr obj, Vector3 pos, Quaternion rot);
846
847// Add a force to the object as if its mass is one.
848[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
849public static extern void ApplyCentralForce2(IntPtr obj, Vector3 force);
850
851// Set the force being applied to the object as if its mass is one.
852[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
853public static extern void SetObjectForce2(IntPtr obj, Vector3 force);
854
855[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
856public static extern Vector3 GetTotalForce2(IntPtr obj);
857
858[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
859public static extern Vector3 GetTotalTorque2(IntPtr obj);
860
861[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
862public static extern Vector3 GetInvInertiaDiagLocal2(IntPtr obj);
863
864[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
865public static extern void SetInvInertiaDiagLocal2(IntPtr obj, Vector3 inert);
866
867[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
868public static extern void SetSleepingThresholds2(IntPtr obj, float lin_threshold, float ang_threshold);
869
870[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
871public static extern void ApplyTorque2(IntPtr obj, Vector3 torque);
872
873// Apply force at the given point. Will add torque to the object.
874[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
875public static extern void ApplyForce2(IntPtr obj, Vector3 force, Vector3 pos);
876
877// Apply impulse to the object. Same as "ApplycentralForce" but force scaled by object's mass.
878[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
879public static extern void ApplyCentralImpulse2(IntPtr obj, Vector3 imp);
880
881// Apply impulse to the object's torque. Force is scaled by object's mass.
882[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
883public static extern void ApplyTorqueImpulse2(IntPtr obj, Vector3 imp);
884
885// Apply impulse at the point given. For is scaled by object's mass and effects both linear and angular forces.
886[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
887public static extern void ApplyImpulse2(IntPtr obj, Vector3 imp, Vector3 pos);
888
889[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
890public static extern void ClearForces2(IntPtr obj);
891
892[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
893public static extern void ClearAllForces2(IntPtr obj);
894
895[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
896public static extern void UpdateInertiaTensor2(IntPtr obj);
897
898[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
899public static extern Vector3 GetCenterOfMassPosition2(IntPtr obj);
900
901 /*
902[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
903public static extern Transform GetCenterOfMassTransform2(IntPtr obj);
904 */
905
906[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
907public static extern Vector3 GetLinearVelocity2(IntPtr obj);
908
909[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
910public static extern Vector3 GetAngularVelocity2(IntPtr obj);
911
912[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
913public static extern void SetLinearVelocity2(IntPtr obj, Vector3 val);
914
915[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
916public static extern void SetAngularVelocity2(IntPtr obj, Vector3 angularVelocity);
917
918[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
919public static extern Vector3 GetVelocityInLocalPoint2(IntPtr obj, Vector3 pos);
920
921[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
922public static extern void Translate2(IntPtr obj, Vector3 trans);
923
924[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
925public static extern void UpdateDeactivation2(IntPtr obj, float timeStep);
926
927[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
928public static extern bool WantsSleeping2(IntPtr obj);
929
930[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
931public static extern void SetAngularFactor2(IntPtr obj, float factor);
932
933[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
934public static extern void SetAngularFactorV2(IntPtr obj, Vector3 factor);
935
936[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
937public static extern Vector3 GetAngularFactor2(IntPtr obj);
938
939[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
940public static extern bool IsInWorld2(IntPtr obj);
941
942[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
943public static extern void AddConstraintRef2(IntPtr obj, IntPtr constrain);
944
945[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
946public static extern void RemoveConstraintRef2(IntPtr obj, IntPtr constrain);
947
948[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
949public static extern IntPtr GetConstraintRef2(IntPtr obj, int index);
950
951[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
952public static extern int GetNumConstraintRefs2(IntPtr obj);
953
954[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
955public static extern Vector3 GetDeltaLinearVelocity2(IntPtr obj);
956
957[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
958public static extern Vector3 GetDeltaAngularVelocity2(IntPtr obj);
959
960[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
961public static extern Vector3 GetPushVelocity2(IntPtr obj);
962
963[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
964public static extern Vector3 GetTurnVelocity2(IntPtr obj);
965
966// =====================================================================================
967// btCollisionShape entries
968
969[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
970public static extern float GetAngularMotionDisc2(IntPtr shape);
971
972[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
973public static extern float GetContactBreakingThreshold2(IntPtr shape, float defaultFactor);
974
975[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
976public static extern bool IsPolyhedral2(IntPtr shape);
977
978[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
979public static extern bool IsConvex2d2(IntPtr shape);
980
981[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
982public static extern bool IsConvex2(IntPtr shape);
983
984[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
985public static extern bool IsNonMoving2(IntPtr shape);
986
987[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
988public static extern bool IsConcave2(IntPtr shape);
989
990[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
991public static extern bool IsCompound2(IntPtr shape);
522 992
523[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 993[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
524public static extern IntPtr SetCollisionFlags2(IntPtr obj, CollisionFlags flags); 994public static extern bool IsSoftBody2(IntPtr shape);
525 995
526[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 996[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
527public static extern IntPtr AddToCollisionFlags2(IntPtr obj, CollisionFlags flags); 997public static extern bool IsInfinite2(IntPtr shape);
528 998
529[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 999[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
530public static extern IntPtr RemoveFromCollisionFlags2(IntPtr obj, CollisionFlags flags); 1000public static extern void SetLocalScaling2(IntPtr shape, Vector3 scale);
531 1001
532[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 1002[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
533public static extern bool SetMassProps2(IntPtr obj, float mass, Vector3 inertia); 1003public static extern Vector3 GetLocalScaling2(IntPtr shape);
534 1004
535[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 1005[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
536public static extern bool UpdateInertiaTensor2(IntPtr obj); 1006public static extern Vector3 CalculateLocalInertia2(IntPtr shape, float mass);
537 1007
538[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 1008[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
539public static extern bool SetGravity2(IntPtr obj, Vector3 val); 1009public static extern int GetShapeType2(IntPtr shape);
540 1010
541[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 1011[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
542public static extern IntPtr ClearForces2(IntPtr obj); 1012public static extern void SetMargin2(IntPtr shape, float val);
543 1013
544[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 1014[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
545public static extern IntPtr ClearAllForces2(IntPtr obj); 1015public static extern float GetMargin2(IntPtr shape);
546 1016
547[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 1017[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
548public static extern bool SetMargin2(IntPtr obj, float val); 1018public static extern void SetCollisionFilterMask(IntPtr shape, uint filter, uint mask);
549 1019
1020// =====================================================================================
1021// Debugging
550[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 1022[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
551public static extern bool UpdateSingleAabb2(IntPtr world, IntPtr obj); 1023public static extern void DumpRigidBody2(IntPtr sim, IntPtr collisionObject);
552 1024
553[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 1025[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
554public static extern bool DestroyObject2(IntPtr world, uint id); 1026public static extern void DumpMapInfo2(IntPtr sim, IntPtr manInfo);
555 1027
556[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 1028[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
557public static extern void DumpPhysicsStatistics2(IntPtr sim); 1029public static extern void DumpPhysicsStatistics2(IntPtr sim);
diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs
index 3144d76..190fca0 100644
--- a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs
+++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs
@@ -39,11 +39,8 @@ using OpenSim.Framework.Console;
39using OpenSim.Region.Physics.Manager; 39using OpenSim.Region.Physics.Manager;
40using Mono.Addins; 40using Mono.Addins;
41 41
42[assembly: Addin("RegionCombinerModule", "0.1")]
43[assembly: AddinDependency("OpenSim", "0.5")]
44namespace OpenSim.Region.RegionCombinerModule 42namespace OpenSim.Region.RegionCombinerModule
45{ 43{
46 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
47 public class RegionCombinerModule : ISharedRegionModule, IRegionCombinerModule 44 public class RegionCombinerModule : ISharedRegionModule, IRegionCombinerModule
48 { 45 {
49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
diff --git a/OpenSim/Region/RegionCombinerModule/Resources/RegionCombinerModule.addin.xml b/OpenSim/Region/RegionCombinerModule/Resources/RegionCombinerModule.addin.xml
new file mode 100644
index 0000000..13cb8b6
--- /dev/null
+++ b/OpenSim/Region/RegionCombinerModule/Resources/RegionCombinerModule.addin.xml
@@ -0,0 +1,14 @@
1<Addin id="OpenSim.RegionModules.RegionCombinerModule" version="0.3">
2 <Runtime>
3 <Import assembly="OpenSim.Region.RegionCombinerModule.dll"/>
4 </Runtime>
5
6 <Dependencies>
7 <Addin id="OpenSim" version="0.5" />
8 </Dependencies>
9
10 <Extension path = "/OpenSim/RegionModules">
11 <RegionModule id="RegionCombinerModule" type="OpenSim.Region.RegionCombinerModule.RegionCombinerModule" />
12 </Extension>
13
14</Addin>
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index f9b4bfd..9570669 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -341,7 +341,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
341 return GetLinkParts(m_host, linkType); 341 return GetLinkParts(m_host, linkType);
342 } 342 }
343 343
344 private List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType) 344 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType)
345 { 345 {
346 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 346 List<SceneObjectPart> ret = new List<SceneObjectPart>();
347 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 347 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
@@ -426,14 +426,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
426 return key; 426 return key;
427 } 427 }
428 428
429 // convert a LSL_Rotation to a Quaternion
430 public static Quaternion Rot2Quaternion(LSL_Rotation r)
431 {
432 Quaternion q = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
433 q.Normalize();
434 return q;
435 }
436
437 //These are the implementations of the various ll-functions used by the LSL scripts. 429 //These are the implementations of the various ll-functions used by the LSL scripts.
438 public LSL_Float llSin(double f) 430 public LSL_Float llSin(double f)
439 { 431 {
@@ -1240,9 +1232,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1240 public LSL_Float llGround(LSL_Vector offset) 1232 public LSL_Float llGround(LSL_Vector offset)
1241 { 1233 {
1242 m_host.AddScriptLPS(1); 1234 m_host.AddScriptLPS(1);
1243 Vector3 pos = m_host.GetWorldPosition() + new Vector3((float)offset.x, 1235 Vector3 pos = m_host.GetWorldPosition() + (Vector3)offset;
1244 (float)offset.y,
1245 (float)offset.z);
1246 1236
1247 //Get the slope normal. This gives us the equation of the plane tangent to the slope. 1237 //Get the slope normal. This gives us the equation of the plane tangent to the slope.
1248 LSL_Vector vsn = llGroundNormal(offset); 1238 LSL_Vector vsn = llGroundNormal(offset);
@@ -1492,31 +1482,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1492 if (part == null || part.ParentGroup.IsDeleted) 1482 if (part == null || part.ParentGroup.IsDeleted)
1493 return; 1483 return;
1494 1484
1495 if (scale.x < 0.01) 1485 // First we need to check whether or not we need to clamp the size of a physics-enabled prim
1496 scale.x = 0.01;
1497 if (scale.y < 0.01)
1498 scale.y = 0.01;
1499 if (scale.z < 0.01)
1500 scale.z = 0.01;
1501
1502 PhysicsActor pa = part.ParentGroup.RootPart.PhysActor; 1486 PhysicsActor pa = part.ParentGroup.RootPart.PhysActor;
1503
1504 if (pa != null && pa.IsPhysical) 1487 if (pa != null && pa.IsPhysical)
1505 { 1488 {
1506 if (scale.x > World.m_maxPhys) 1489 scale.x = Math.Max(World.m_minPhys, Math.Min(World.m_maxPhys, scale.x));
1507 scale.x = World.m_maxPhys; 1490 scale.y = Math.Max(World.m_minPhys, Math.Min(World.m_maxPhys, scale.y));
1508 if (scale.y > World.m_maxPhys) 1491 scale.z = Math.Max(World.m_minPhys, Math.Min(World.m_maxPhys, scale.z));
1509 scale.y = World.m_maxPhys; 1492 }
1510 if (scale.z > World.m_maxPhys) 1493 else
1511 scale.z = World.m_maxPhys; 1494 {
1495 // If not physical, then we clamp the scale to the non-physical min/max
1496 scale.x = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, scale.x));
1497 scale.y = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, scale.y));
1498 scale.z = Math.Max(World.m_minNonphys, Math.Min(World.m_maxNonphys, scale.z));
1512 } 1499 }
1513
1514 if (scale.x > World.m_maxNonphys)
1515 scale.x = World.m_maxNonphys;
1516 if (scale.y > World.m_maxNonphys)
1517 scale.y = World.m_maxNonphys;
1518 if (scale.z > World.m_maxNonphys)
1519 scale.z = World.m_maxNonphys;
1520 1500
1521 Vector3 tmp = part.Scale; 1501 Vector3 tmp = part.Scale;
1522 tmp.X = (float)scale.x; 1502 tmp.X = (float)scale.x;
@@ -1590,7 +1570,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1590 if (face == ScriptBaseClass.ALL_SIDES) 1570 if (face == ScriptBaseClass.ALL_SIDES)
1591 face = SceneObjectPart.ALL_SIDES; 1571 face = SceneObjectPart.ALL_SIDES;
1592 1572
1593 m_host.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 1573 m_host.SetFaceColorAlpha(face, color, null);
1594 } 1574 }
1595 1575
1596 public void SetTexGen(SceneObjectPart part, int face,int style) 1576 public void SetTexGen(SceneObjectPart part, int face,int style)
@@ -2202,7 +2182,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2202 pos.x > (Constants.RegionSize + 10) || // return FALSE if more than 10 meters into a east-adjacent region. 2182 pos.x > (Constants.RegionSize + 10) || // return FALSE if more than 10 meters into a east-adjacent region.
2203 pos.y < -10.0 || // return FALSE if more than 10 meters into a south-adjacent region. 2183 pos.y < -10.0 || // return FALSE if more than 10 meters into a south-adjacent region.
2204 pos.y > (Constants.RegionSize + 10) || // return FALSE if more than 10 meters into a north-adjacent region. 2184 pos.y > (Constants.RegionSize + 10) || // return FALSE if more than 10 meters into a north-adjacent region.
2205 pos.z > 4096 // return FALSE if altitude than 4096m 2185 pos.z > Constants.RegionHeight // return FALSE if altitude than 4096m
2206 ) 2186 )
2207 ) 2187 )
2208 { 2188 {
@@ -2213,14 +2193,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2213 // this could possibly be done in the above else-if block, but we're doing the check here to keep the code easier to read. 2193 // this could possibly be done in the above else-if block, but we're doing the check here to keep the code easier to read.
2214 2194
2215 Vector3 objectPos = m_host.ParentGroup.RootPart.AbsolutePosition; 2195 Vector3 objectPos = m_host.ParentGroup.RootPart.AbsolutePosition;
2216 LandData here = World.GetLandData((float)objectPos.X, (float)objectPos.Y); 2196 LandData here = World.GetLandData(objectPos);
2217 LandData there = World.GetLandData((float)pos.x, (float)pos.y); 2197 LandData there = World.GetLandData(pos);
2218 2198
2219 // we're only checking prim limits if it's moving to a different parcel under the assumption that if the object got onto the parcel without exceeding the prim limits. 2199 // we're only checking prim limits if it's moving to a different parcel under the assumption that if the object got onto the parcel without exceeding the prim limits.
2220 2200
2221 bool sameParcel = here.GlobalID == there.GlobalID; 2201 bool sameParcel = here.GlobalID == there.GlobalID;
2222 2202
2223 if (!sameParcel && !World.Permissions.CanObjectEntry(m_host.UUID, false, new Vector3((float)pos.x, (float)pos.y, (float)pos.z))) 2203 if (!sameParcel && !World.Permissions.CanRezObject(
2204 m_host.ParentGroup.PrimCount, m_host.ParentGroup.OwnerID, pos))
2224 { 2205 {
2225 return 0; 2206 return 0;
2226 } 2207 }
@@ -2279,16 +2260,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2279 if (part.ParentGroup.RootPart == part) 2260 if (part.ParentGroup.RootPart == part)
2280 { 2261 {
2281 SceneObjectGroup parent = part.ParentGroup; 2262 SceneObjectGroup parent = part.ParentGroup;
2282 Vector3 dest = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z); 2263 if (!World.Permissions.CanObjectEntry(parent.UUID, false, (Vector3)toPos))
2283 if (!World.Permissions.CanObjectEntry(parent.UUID, false, dest))
2284 return; 2264 return;
2285 Util.FireAndForget(delegate(object x) { 2265 Util.FireAndForget(delegate(object x) {
2286 parent.UpdateGroupPosition(dest); 2266 parent.UpdateGroupPosition((Vector3)toPos);
2287 }); 2267 });
2288 } 2268 }
2289 else 2269 else
2290 { 2270 {
2291 part.OffsetPosition = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z); 2271 part.OffsetPosition = (Vector3)toPos;
2292 SceneObjectGroup parent = part.ParentGroup; 2272 SceneObjectGroup parent = part.ParentGroup;
2293 parent.HasGroupChanged = true; 2273 parent.HasGroupChanged = true;
2294 parent.ScheduleGroupForTerseUpdate(); 2274 parent.ScheduleGroupForTerseUpdate();
@@ -2326,7 +2306,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2326 pos = part.AbsolutePosition; 2306 pos = part.AbsolutePosition;
2327 } 2307 }
2328 2308
2329 return new LSL_Vector(pos.X, pos.Y, pos.Z); 2309// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
2310
2311 return new LSL_Vector(pos);
2330 } 2312 }
2331 2313
2332 public void llSetRot(LSL_Rotation rot) 2314 public void llSetRot(LSL_Rotation rot)
@@ -2334,26 +2316,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2334 m_host.AddScriptLPS(1); 2316 m_host.AddScriptLPS(1);
2335 2317
2336 // try to let this work as in SL... 2318 // try to let this work as in SL...
2337 if (m_host.LinkNum < 2) 2319 if (m_host.ParentID == 0)
2338 { 2320 {
2339 // Special case: If we are root, rotate complete SOG to new 2321 // special case: If we are root, rotate complete SOG to new rotation
2340 // rotation. 2322 SetRot(m_host, rot);
2341 // We are root if the link number is 0 (single prim) or 1
2342 // (root prim). ParentID may be nonzero in attachments and
2343 // using it would cause attachments and HUDs to rotate
2344 // to the wrong positions.
2345
2346 SetRot(m_host, Rot2Quaternion(rot));
2347 } 2323 }
2348 else 2324 else
2349 { 2325 {
2350 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. 2326 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask.
2351 SceneObjectPart rootPart; 2327 SceneObjectPart rootPart = m_host.ParentGroup.RootPart;
2352 if (m_host.ParentGroup != null) // better safe than sorry 2328 if (rootPart != null) // better safe than sorry
2353 { 2329 {
2354 rootPart = m_host.ParentGroup.RootPart; 2330 SetRot(m_host, rootPart.RotationOffset * (Quaternion)rot);
2355 if (rootPart != null)
2356 SetRot(m_host, rootPart.RotationOffset * Rot2Quaternion(rot));
2357 } 2331 }
2358 } 2332 }
2359 2333
@@ -2363,8 +2337,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2363 public void llSetLocalRot(LSL_Rotation rot) 2337 public void llSetLocalRot(LSL_Rotation rot)
2364 { 2338 {
2365 m_host.AddScriptLPS(1); 2339 m_host.AddScriptLPS(1);
2366 2340 SetRot(m_host, rot);
2367 SetRot(m_host, Rot2Quaternion(rot));
2368 ScriptSleep(200); 2341 ScriptSleep(200);
2369 } 2342 }
2370 2343
@@ -2476,7 +2449,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2476 if (local != 0) 2449 if (local != 0)
2477 force *= llGetRot(); 2450 force *= llGetRot();
2478 2451
2479 m_host.ParentGroup.RootPart.SetForce(new Vector3((float)force.x, (float)force.y, (float)force.z)); 2452 m_host.ParentGroup.RootPart.SetForce(force);
2480 } 2453 }
2481 } 2454 }
2482 2455
@@ -2488,10 +2461,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2488 2461
2489 if (!m_host.ParentGroup.IsDeleted) 2462 if (!m_host.ParentGroup.IsDeleted)
2490 { 2463 {
2491 Vector3 tmpForce = m_host.ParentGroup.RootPart.GetForce(); 2464 force = m_host.ParentGroup.RootPart.GetForce();
2492 force.x = tmpForce.X;
2493 force.y = tmpForce.Y;
2494 force.z = tmpForce.Z;
2495 } 2465 }
2496 2466
2497 return force; 2467 return force;
@@ -2500,8 +2470,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2500 public LSL_Integer llTarget(LSL_Vector position, double range) 2470 public LSL_Integer llTarget(LSL_Vector position, double range)
2501 { 2471 {
2502 m_host.AddScriptLPS(1); 2472 m_host.AddScriptLPS(1);
2503 return m_host.ParentGroup.registerTargetWaypoint( 2473 return m_host.ParentGroup.registerTargetWaypoint(position,
2504 new Vector3((float)position.x, (float)position.y, (float)position.z), (float)range); 2474 (float)range);
2505 } 2475 }
2506 2476
2507 public void llTargetRemove(int number) 2477 public void llTargetRemove(int number)
@@ -2513,8 +2483,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2513 public LSL_Integer llRotTarget(LSL_Rotation rot, double error) 2483 public LSL_Integer llRotTarget(LSL_Rotation rot, double error)
2514 { 2484 {
2515 m_host.AddScriptLPS(1); 2485 m_host.AddScriptLPS(1);
2516 return m_host.ParentGroup.registerRotTargetWaypoint( 2486 return m_host.ParentGroup.registerRotTargetWaypoint(rot, (float)error);
2517 new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s), (float)error);
2518 } 2487 }
2519 2488
2520 public void llRotTargetRemove(int number) 2489 public void llRotTargetRemove(int number)
@@ -2526,7 +2495,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2526 public void llMoveToTarget(LSL_Vector target, double tau) 2495 public void llMoveToTarget(LSL_Vector target, double tau)
2527 { 2496 {
2528 m_host.AddScriptLPS(1); 2497 m_host.AddScriptLPS(1);
2529 m_host.MoveToTarget(new Vector3((float)target.x, (float)target.y, (float)target.z), (float)tau); 2498 m_host.MoveToTarget(target, (float)tau);
2530 } 2499 }
2531 2500
2532 public void llStopMoveToTarget() 2501 public void llStopMoveToTarget()
@@ -2539,7 +2508,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2539 { 2508 {
2540 m_host.AddScriptLPS(1); 2509 m_host.AddScriptLPS(1);
2541 //No energy force yet 2510 //No energy force yet
2542 Vector3 v = new Vector3((float)force.x, (float)force.y, (float)force.z); 2511 Vector3 v = force;
2543 if (v.Length() > 20000.0f) 2512 if (v.Length() > 20000.0f)
2544 { 2513 {
2545 v.Normalize(); 2514 v.Normalize();
@@ -2552,13 +2521,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2552 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2521 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2553 { 2522 {
2554 m_host.AddScriptLPS(1); 2523 m_host.AddScriptLPS(1);
2555 m_host.ParentGroup.RootPart.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0); 2524 m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0);
2556 } 2525 }
2557 2526
2558 public void llSetTorque(LSL_Vector torque, int local) 2527 public void llSetTorque(LSL_Vector torque, int local)
2559 { 2528 {
2560 m_host.AddScriptLPS(1); 2529 m_host.AddScriptLPS(1);
2561 m_host.ParentGroup.RootPart.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0); 2530 m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0);
2562 } 2531 }
2563 2532
2564 public LSL_Vector llGetTorque() 2533 public LSL_Vector llGetTorque()
@@ -3123,13 +3092,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3123 return; 3092 return;
3124 } 3093 }
3125 3094
3126 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
3127 Vector3 llvel = new Vector3((float)vel.x, (float)vel.y, (float)vel.z);
3128
3129 // need the magnitude later 3095 // need the magnitude later
3130 // float velmag = (float)Util.GetMagnitude(llvel); 3096 // float velmag = (float)Util.GetMagnitude(llvel);
3131 3097
3132 SceneObjectGroup new_group = World.RezObject(m_host, item, llpos, Rot2Quaternion(rot), llvel, param); 3098 SceneObjectGroup new_group = World.RezObject(m_host, item, pos, rot, vel, param);
3133 3099
3134 // If either of these are null, then there was an unknown error. 3100 // If either of these are null, then there was an unknown error.
3135 if (new_group == null) 3101 if (new_group == null)
@@ -3156,11 +3122,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3156 3122
3157 PhysicsActor pa = new_group.RootPart.PhysActor; 3123 PhysicsActor pa = new_group.RootPart.PhysActor;
3158 3124
3159 if (pa != null && pa.IsPhysical && llvel != Vector3.Zero) 3125 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
3160 { 3126 {
3161 float groupmass = new_group.GetMass(); 3127 float groupmass = new_group.GetMass();
3162 llvel *= -groupmass; 3128 vel *= -groupmass;
3163 llApplyImpulse(new LSL_Vector(llvel.X, llvel.Y,llvel.Z), 0); 3129 llApplyImpulse(vel, 0);
3164 } 3130 }
3165 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3131 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3166 return; 3132 return;
@@ -3211,7 +3177,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3211 return; 3177 return;
3212 } 3178 }
3213 3179
3214 m_host.StartLookAt(Rot2Quaternion(r3 * r2 * r1), (float)strength, (float)damping); 3180 m_host.StartLookAt((Quaternion)(r3 * r2 * r1), (float)strength, (float)damping);
3215 } 3181 }
3216 } 3182 }
3217 3183
@@ -3637,7 +3603,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3637 } 3603 }
3638 else 3604 else
3639 { 3605 {
3640 m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping); 3606 m_host.RotLookAt(target, (float)strength, (float)damping);
3641 } 3607 }
3642 } 3608 }
3643 3609
@@ -3718,7 +3684,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3718 3684
3719 protected void TargetOmega(SceneObjectPart part, LSL_Vector axis, double spinrate, double gain) 3685 protected void TargetOmega(SceneObjectPart part, LSL_Vector axis, double spinrate, double gain)
3720 { 3686 {
3721 part.UpdateAngularVelocity(new Vector3((float)(axis.x * spinrate), (float)(axis.y * spinrate), (float)(axis.z * spinrate))); 3687 part.UpdateAngularVelocity(axis * spinrate);
3722 } 3688 }
3723 3689
3724 public LSL_Integer llGetStartParameter() 3690 public LSL_Integer llGetStartParameter()
@@ -3928,7 +3894,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3928 try 3894 try
3929 { 3895 {
3930 foreach (SceneObjectPart part in parts) 3896 foreach (SceneObjectPart part in parts)
3931 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3897 part.SetFaceColorAlpha(face, color, null);
3932 } 3898 }
3933 finally 3899 finally
3934 { 3900 {
@@ -4398,9 +4364,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4398 public void llSetText(string text, LSL_Vector color, double alpha) 4364 public void llSetText(string text, LSL_Vector color, double alpha)
4399 { 4365 {
4400 m_host.AddScriptLPS(1); 4366 m_host.AddScriptLPS(1);
4401 Vector3 av3 = new Vector3(Util.Clip((float)color.x, 0.0f, 1.0f), 4367 Vector3 av3 = Util.Clip(color, 0.0f, 1.0f);
4402 Util.Clip((float)color.y, 0.0f, 1.0f),
4403 Util.Clip((float)color.z, 0.0f, 1.0f));
4404 m_host.SetText(text.Length > 254 ? text.Remove(254) : text, av3, Util.Clip((float)alpha, 0.0f, 1.0f)); 4368 m_host.SetText(text.Length > 254 ? text.Remove(254) : text, av3, Util.Clip((float)alpha, 0.0f, 1.0f));
4405 //m_host.ParentGroup.HasGroupChanged = true; 4369 //m_host.ParentGroup.HasGroupChanged = true;
4406 //m_host.ParentGroup.ScheduleGroupForFullUpdate(); 4370 //m_host.ParentGroup.ScheduleGroupForFullUpdate();
@@ -4616,14 +4580,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4616 ScriptSleep(5000); 4580 ScriptSleep(5000);
4617 } 4581 }
4618 4582
4619 public void llTeleportAgent(string agent, string destination, LSL_Vector pos, LSL_Vector lookAt) 4583 public void llTeleportAgent(string agent, string destination, LSL_Vector targetPos, LSL_Vector targetLookAt)
4620 { 4584 {
4621 m_host.AddScriptLPS(1); 4585 m_host.AddScriptLPS(1);
4622 UUID agentId = new UUID(); 4586 UUID agentId = new UUID();
4623 4587
4624 Vector3 targetPos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
4625 Vector3 targetLookAt = new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z);
4626
4627 if (UUID.TryParse(agent, out agentId)) 4588 if (UUID.TryParse(agent, out agentId))
4628 { 4589 {
4629 ScenePresence presence = World.GetScenePresence(agentId); 4590 ScenePresence presence = World.GetScenePresence(agentId);
@@ -4652,15 +4613,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4652 } 4613 }
4653 } 4614 }
4654 4615
4655 public void llTeleportAgentGlobalCoords(string agent, LSL_Vector global_coords, LSL_Vector pos, LSL_Vector lookAt) 4616 public void llTeleportAgentGlobalCoords(string agent, LSL_Vector global_coords, LSL_Vector targetPos, LSL_Vector targetLookAt)
4656 { 4617 {
4657 m_host.AddScriptLPS(1); 4618 m_host.AddScriptLPS(1);
4658 UUID agentId = new UUID(); 4619 UUID agentId = new UUID();
4659 4620
4660 ulong regionHandle = Utils.UIntsToLong((uint)global_coords.x, (uint)global_coords.y); 4621 ulong regionHandle = Utils.UIntsToLong((uint)global_coords.x, (uint)global_coords.y);
4661 4622
4662 Vector3 targetPos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
4663 Vector3 targetLookAt = new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z);
4664 if (UUID.TryParse(agent, out agentId)) 4623 if (UUID.TryParse(agent, out agentId))
4665 { 4624 {
4666 ScenePresence presence = World.GetScenePresence(agentId); 4625 ScenePresence presence = World.GetScenePresence(agentId);
@@ -4957,7 +4916,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4957 distance_attenuation = 1f / normalized_units; 4916 distance_attenuation = 1f / normalized_units;
4958 } 4917 }
4959 4918
4960 Vector3 applied_linear_impulse = new Vector3((float)impulse.x, (float)impulse.y, (float)impulse.z); 4919 Vector3 applied_linear_impulse = impulse;
4961 { 4920 {
4962 float impulse_length = applied_linear_impulse.Length(); 4921 float impulse_length = applied_linear_impulse.Length();
4963 4922
@@ -5605,25 +5564,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5605 /// separated list. There is a space after 5564 /// separated list. There is a space after
5606 /// each comma. 5565 /// each comma.
5607 /// </summary> 5566 /// </summary>
5608
5609 public LSL_String llList2CSV(LSL_List src) 5567 public LSL_String llList2CSV(LSL_List src)
5610 { 5568 {
5611
5612 string ret = String.Empty;
5613 int x = 0;
5614
5615 m_host.AddScriptLPS(1); 5569 m_host.AddScriptLPS(1);
5616 5570
5617 if (src.Data.Length > 0) 5571 return string.Join(", ",
5618 { 5572 (new List<object>(src.Data)).ConvertAll<string>(o =>
5619 ret = src.Data[x++].ToString(); 5573 {
5620 for (; x < src.Data.Length; x++) 5574 return o.ToString();
5621 { 5575 }).ToArray());
5622 ret += ", "+src.Data[x].ToString();
5623 }
5624 }
5625
5626 return ret;
5627 } 5576 }
5628 5577
5629 /// <summary> 5578 /// <summary>
@@ -6296,19 +6245,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6296 m_host.AddScriptLPS(1); 6245 m_host.AddScriptLPS(1);
6297 6246
6298 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6247 List<SceneObjectPart> parts = GetLinkParts(linknumber);
6299 if (parts.Count > 0) 6248
6249 try
6300 { 6250 {
6301 try 6251 foreach (SceneObjectPart part in parts)
6302 {
6303 foreach (var part in parts)
6304 {
6305 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6306 }
6307 }
6308 finally
6309 { 6252 {
6253 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6310 } 6254 }
6311 } 6255 }
6256 finally
6257 {
6258 }
6312 } 6259 }
6313 6260
6314 private void SetTextureAnim(SceneObjectPart part, int mode, int face, int sizex, int sizey, double start, double length, double rate) 6261 private void SetTextureAnim(SceneObjectPart part, int mode, int face, int sizex, int sizey, double start, double length, double rate)
@@ -6526,9 +6473,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6526 6473
6527 //Plug the x,y coordinates of the slope normal into the equation of the plane to get 6474 //Plug the x,y coordinates of the slope normal into the equation of the plane to get
6528 //the height of that point on the plane. The resulting vector gives the slope. 6475 //the height of that point on the plane. The resulting vector gives the slope.
6529 Vector3 vsl = new Vector3(); 6476 Vector3 vsl = vsn;
6530 vsl.X = (float)vsn.x;
6531 vsl.Y = (float)vsn.y;
6532 vsl.Z = (float)(((vsn.x * vsn.x) + (vsn.y * vsn.y)) / (-1 * vsn.z)); 6477 vsl.Z = (float)(((vsn.x * vsn.x) + (vsn.y * vsn.y)) / (-1 * vsn.z));
6533 vsl.Normalize(); 6478 vsl.Normalize();
6534 //Normalization might be overkill here 6479 //Normalization might be overkill here
@@ -6539,9 +6484,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6539 public LSL_Vector llGroundNormal(LSL_Vector offset) 6484 public LSL_Vector llGroundNormal(LSL_Vector offset)
6540 { 6485 {
6541 m_host.AddScriptLPS(1); 6486 m_host.AddScriptLPS(1);
6542 Vector3 pos = m_host.GetWorldPosition() + new Vector3((float)offset.x, 6487 Vector3 pos = m_host.GetWorldPosition() + (Vector3)offset;
6543 (float)offset.y,
6544 (float)offset.z);
6545 // Clamp to valid position 6488 // Clamp to valid position
6546 if (pos.X < 0) 6489 if (pos.X < 0)
6547 pos.X = 0; 6490 pos.X = 0;
@@ -6706,7 +6649,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6706 6649
6707 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6650 List<SceneObjectPart> parts = GetLinkParts(linknumber);
6708 6651
6709 foreach (var part in parts) 6652 foreach (SceneObjectPart part in parts)
6710 { 6653 {
6711 SetParticleSystem(part, rules); 6654 SetParticleSystem(part, rules);
6712 } 6655 }
@@ -6995,8 +6938,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6995 6938
6996 if (!m_host.ParentGroup.IsDeleted) 6939 if (!m_host.ParentGroup.IsDeleted)
6997 { 6940 {
6998 m_host.ParentGroup.RootPart.SetVehicleVectorParam(param, 6941 m_host.ParentGroup.RootPart.SetVehicleVectorParam(param, vec);
6999 new Vector3((float)vec.x, (float)vec.y, (float)vec.z));
7000 } 6942 }
7001 } 6943 }
7002 6944
@@ -7008,7 +6950,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7008 6950
7009 if (!m_host.ParentGroup.IsDeleted) 6951 if (!m_host.ParentGroup.IsDeleted)
7010 { 6952 {
7011 m_host.ParentGroup.RootPart.SetVehicleRotationParam(param, Rot2Quaternion(rot)); 6953 m_host.ParentGroup.RootPart.SetVehicleRotationParam(param, rot);
7012 } 6954 }
7013 } 6955 }
7014 6956
@@ -7038,8 +6980,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7038 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0) 6980 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
7039 rot.s = 1; // ZERO_ROTATION = 0,0,0,1 6981 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
7040 6982
7041 part.SitTargetPosition = new Vector3((float)offset.x, (float)offset.y, (float)offset.z); 6983 part.SitTargetPosition = offset;
7042 part.SitTargetOrientation = Rot2Quaternion(rot); 6984 part.SitTargetOrientation = rot;
7043 part.ParentGroup.HasGroupChanged = true; 6985 part.ParentGroup.HasGroupChanged = true;
7044 } 6986 }
7045 6987
@@ -7142,13 +7084,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7142 public void llSetCameraEyeOffset(LSL_Vector offset) 7084 public void llSetCameraEyeOffset(LSL_Vector offset)
7143 { 7085 {
7144 m_host.AddScriptLPS(1); 7086 m_host.AddScriptLPS(1);
7145 m_host.SetCameraEyeOffset(new Vector3((float)offset.x, (float)offset.y, (float)offset.z)); 7087 m_host.SetCameraEyeOffset(offset);
7146 } 7088 }
7147 7089
7148 public void llSetCameraAtOffset(LSL_Vector offset) 7090 public void llSetCameraAtOffset(LSL_Vector offset)
7149 { 7091 {
7150 m_host.AddScriptLPS(1); 7092 m_host.AddScriptLPS(1);
7151 m_host.SetCameraAtOffset(new Vector3((float)offset.x, (float)offset.y, (float)offset.z)); 7093 m_host.SetCameraAtOffset(offset);
7152 } 7094 }
7153 7095
7154 public LSL_String llDumpList2String(LSL_List src, string seperator) 7096 public LSL_String llDumpList2String(LSL_List src, string seperator)
@@ -7170,7 +7112,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7170 public LSL_Integer llScriptDanger(LSL_Vector pos) 7112 public LSL_Integer llScriptDanger(LSL_Vector pos)
7171 { 7113 {
7172 m_host.AddScriptLPS(1); 7114 m_host.AddScriptLPS(1);
7173 bool result = World.ScriptDanger(m_host.LocalId, new Vector3((float)pos.x, (float)pos.y, (float)pos.z)); 7115 bool result = World.ScriptDanger(m_host.LocalId, pos);
7174 if (result) 7116 if (result)
7175 { 7117 {
7176 return 1; 7118 return 1;
@@ -7752,7 +7694,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7752 { 7694 {
7753 m_host.AddScriptLPS(1); 7695 m_host.AddScriptLPS(1);
7754 7696
7755 setLinkPrimParams(ScriptBaseClass.LINK_THIS, rules); 7697 setLinkPrimParams(ScriptBaseClass.LINK_THIS, rules, "llSetPrimitiveParams");
7756 7698
7757 ScriptSleep(200); 7699 ScriptSleep(200);
7758 } 7700 }
@@ -7761,10 +7703,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7761 { 7703 {
7762 m_host.AddScriptLPS(1); 7704 m_host.AddScriptLPS(1);
7763 7705
7764 setLinkPrimParams(linknumber, rules); 7706 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7707
7708 ScriptSleep(200);
7765 } 7709 }
7766 7710
7767 private void setLinkPrimParams(int linknumber, LSL_List rules) 7711 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7768 { 7712 {
7769 List<object> parts = new List<object>(); 7713 List<object> parts = new List<object>();
7770 List<SceneObjectPart> prims = GetLinkParts(linknumber); 7714 List<SceneObjectPart> prims = GetLinkParts(linknumber);
@@ -7775,15 +7719,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7775 parts.Add(p); 7719 parts.Add(p);
7776 7720
7777 LSL_List remaining = null; 7721 LSL_List remaining = null;
7722 uint rulesParsed = 0;
7778 7723
7779 if (parts.Count > 0) 7724 if (parts.Count > 0)
7780 { 7725 {
7781 foreach (object part in parts) 7726 foreach (object part in parts)
7782 { 7727 {
7783 if (part is SceneObjectPart) 7728 if (part is SceneObjectPart)
7784 remaining = SetPrimParams((SceneObjectPart)part, rules); 7729 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7785 else 7730 else
7786 remaining = SetPrimParams((ScenePresence)part, rules); 7731 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7787 } 7732 }
7788 7733
7789 while ((object)remaining != null && remaining.Length > 2) 7734 while ((object)remaining != null && remaining.Length > 2)
@@ -7802,9 +7747,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7802 foreach (object part in parts) 7747 foreach (object part in parts)
7803 { 7748 {
7804 if (part is SceneObjectPart) 7749 if (part is SceneObjectPart)
7805 remaining = SetPrimParams((SceneObjectPart)part, rules); 7750 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7806 else 7751 else
7807 remaining = SetPrimParams((ScenePresence)part, rules); 7752 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7808 } 7753 }
7809 } 7754 }
7810 } 7755 }
@@ -7842,6 +7787,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7842 7787
7843 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7788 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7844 { 7789 {
7790 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7845 llSetLinkPrimitiveParamsFast(linknumber, rules); 7791 llSetLinkPrimitiveParamsFast(linknumber, rules);
7846 ScriptSleep(200); 7792 ScriptSleep(200);
7847 } 7793 }
@@ -7869,195 +7815,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7869 return new Vector3((float)x, (float)y, (float)z); 7815 return new Vector3((float)x, (float)y, (float)z);
7870 } 7816 }
7871 7817
7872 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules) 7818 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7873 {
7874 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7875
7876 int idx = 0;
7877
7878 bool positionChanged = false;
7879 Vector3 finalPos = Vector3.Zero;
7880
7881 try
7882 {
7883 while (idx < rules.Length)
7884 {
7885 int code = rules.GetLSLIntegerItem(idx++);
7886
7887 int remain = rules.Length - idx;
7888
7889 switch (code)
7890 {
7891 case (int)ScriptBaseClass.PRIM_POSITION:
7892 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
7893 {
7894 if (remain < 1)
7895 return null;
7896
7897 LSL_Vector v;
7898 v = rules.GetVector3Item(idx++);
7899
7900 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
7901 if (part == null)
7902 break;
7903
7904 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7905 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7906 if (part.LinkNum > 1)
7907 {
7908 localRot = GetPartLocalRot(part);
7909 localPos = GetPartLocalPos(part);
7910 }
7911
7912 v -= localPos;
7913 v /= localRot;
7914
7915 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
7916
7917 v = v + 2 * sitOffset;
7918
7919 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7920 av.SendAvatarDataToAllAgents();
7921
7922 }
7923 break;
7924
7925 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
7926 case (int)ScriptBaseClass.PRIM_ROTATION:
7927 {
7928 if (remain < 1)
7929 return null;
7930
7931 LSL_Rotation r;
7932 r = rules.GetQuaternionItem(idx++);
7933
7934 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
7935 if (part == null)
7936 break;
7937
7938 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7939 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7940
7941 if (part.LinkNum > 1)
7942 localRot = GetPartLocalRot(part);
7943
7944 r = r * llGetRootRotation() / localRot;
7945 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7946 av.SendAvatarDataToAllAgents();
7947 }
7948 break;
7949
7950 // parse rest doing nothing but number of parameters error check
7951 case (int)ScriptBaseClass.PRIM_SIZE:
7952 case (int)ScriptBaseClass.PRIM_MATERIAL:
7953 case (int)ScriptBaseClass.PRIM_PHANTOM:
7954 case (int)ScriptBaseClass.PRIM_PHYSICS:
7955 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
7956 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7957 case (int)ScriptBaseClass.PRIM_NAME:
7958 case (int)ScriptBaseClass.PRIM_DESC:
7959 if (remain < 1)
7960 return null;
7961 idx++;
7962 break;
7963
7964 case (int)ScriptBaseClass.PRIM_GLOW:
7965 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7966 case (int)ScriptBaseClass.PRIM_TEXGEN:
7967 if (remain < 2)
7968 return null;
7969 idx += 2;
7970 break;
7971
7972 case (int)ScriptBaseClass.PRIM_TYPE:
7973 if (remain < 3)
7974 return null;
7975 code = (int)rules.GetLSLIntegerItem(idx++);
7976 remain = rules.Length - idx;
7977 switch (code)
7978 {
7979 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
7980 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
7981 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
7982 if (remain < 6)
7983 return null;
7984 idx += 6;
7985 break;
7986
7987 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
7988 if (remain < 5)
7989 return null;
7990 idx += 5;
7991 break;
7992
7993 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
7994 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
7995 case (int)ScriptBaseClass.PRIM_TYPE_RING:
7996 if (remain < 11)
7997 return null;
7998 idx += 11;
7999 break;
8000
8001 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
8002 if (remain < 2)
8003 return null;
8004 idx += 2;
8005 break;
8006 }
8007 break;
8008
8009 case (int)ScriptBaseClass.PRIM_COLOR:
8010 case (int)ScriptBaseClass.PRIM_TEXT:
8011 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8012 case (int)ScriptBaseClass.PRIM_OMEGA:
8013 if (remain < 3)
8014 return null;
8015 idx += 3;
8016 break;
8017
8018 case (int)ScriptBaseClass.PRIM_TEXTURE:
8019 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
8020 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8021 if (remain < 5)
8022 return null;
8023 idx += 5;
8024 break;
8025
8026 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
8027 if (remain < 7)
8028 return null;
8029
8030 idx += 7;
8031 break;
8032
8033 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
8034 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
8035 return null;
8036
8037 return rules.GetSublist(idx, -1);
8038 }
8039 }
8040 }
8041
8042 finally
8043 {
8044 if (positionChanged)
8045 {
8046 av.OffsetPosition = finalPos;
8047// av.SendAvatarDataToAllAgents();
8048 av.SendTerseUpdateToAllClients();
8049 positionChanged = false;
8050 }
8051 }
8052 return null;
8053 }
8054
8055 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules)
8056 { 7819 {
8057 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 7820 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
8058 return null; 7821 return null;
8059 7822
8060 int idx = 0; 7823 int idx = 0;
7824 int idxStart = 0;
8061 7825
8062 SceneObjectGroup parentgrp = part.ParentGroup; 7826 SceneObjectGroup parentgrp = part.ParentGroup;
8063 7827
@@ -8068,9 +7832,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8068 { 7832 {
8069 while (idx < rules.Length) 7833 while (idx < rules.Length)
8070 { 7834 {
7835 ++rulesParsed;
8071 int code = rules.GetLSLIntegerItem(idx++); 7836 int code = rules.GetLSLIntegerItem(idx++);
8072 7837
8073 int remain = rules.Length - idx; 7838 int remain = rules.Length - idx;
7839 idxStart = idx;
8074 7840
8075 int face; 7841 int face;
8076 LSL_Vector v; 7842 LSL_Vector v;
@@ -8100,18 +7866,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8100 return null; 7866 return null;
8101 7867
8102 LSL_Rotation q = rules.GetQuaternionItem(idx++); 7868 LSL_Rotation q = rules.GetQuaternionItem(idx++);
8103 SceneObjectPart rootPart = parentgrp.RootPart;
8104 // try to let this work as in SL... 7869 // try to let this work as in SL...
8105 if (rootPart == part) 7870 if (part.ParentID == 0)
8106 { 7871 {
8107 // special case: If we are root, rotate complete SOG to new rotation 7872 // special case: If we are root, rotate complete SOG to new rotation
8108 SetRot(part, Rot2Quaternion(q)); 7873 SetRot(part, q);
8109 } 7874 }
8110 else 7875 else
8111 { 7876 {
8112 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. 7877 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask.
8113 // sounds like sl bug that we need to replicate 7878 SceneObjectPart rootPart = part.ParentGroup.RootPart;
8114 SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q)); 7879 SetRot(part, rootPart.RotationOffset * (Quaternion)q);
8115 } 7880 }
8116 7881
8117 break; 7882 break;
@@ -8285,8 +8050,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8285 LSL_Vector color=rules.GetVector3Item(idx++); 8050 LSL_Vector color=rules.GetVector3Item(idx++);
8286 double alpha=(double)rules.GetLSLFloatItem(idx++); 8051 double alpha=(double)rules.GetLSLFloatItem(idx++);
8287 8052
8288 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 8053 part.SetFaceColorAlpha(face, color, alpha);
8289 SetAlpha(part, alpha, face);
8290 8054
8291 break; 8055 break;
8292 8056
@@ -8434,9 +8198,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8434 string primText = rules.GetLSLStringItem(idx++); 8198 string primText = rules.GetLSLStringItem(idx++);
8435 LSL_Vector primTextColor = rules.GetVector3Item(idx++); 8199 LSL_Vector primTextColor = rules.GetVector3Item(idx++);
8436 LSL_Float primTextAlpha = rules.GetLSLFloatItem(idx++); 8200 LSL_Float primTextAlpha = rules.GetLSLFloatItem(idx++);
8437 Vector3 av3 = new Vector3(Util.Clip((float)primTextColor.x, 0.0f, 1.0f), 8201 Vector3 av3 = Util.Clip(primTextColor, 0.0f, 1.0f);
8438 Util.Clip((float)primTextColor.y, 0.0f, 1.0f),
8439 Util.Clip((float)primTextColor.z, 0.0f, 1.0f));
8440 part.SetText(primText, av3, Util.Clip((float)primTextAlpha, 0.0f, 1.0f)); 8202 part.SetText(primText, av3, Util.Clip((float)primTextAlpha, 0.0f, 1.0f));
8441 8203
8442 break; 8204 break;
@@ -8455,8 +8217,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8455 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 8217 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8456 if (remain < 1) 8218 if (remain < 1)
8457 return null; 8219 return null;
8458 LSL_Rotation lr = rules.GetQuaternionItem(idx++); 8220 SetRot(part, rules.GetQuaternionItem(idx++));
8459 SetRot(part, Rot2Quaternion(lr));
8460 break; 8221 break;
8461 case (int)ScriptBaseClass.PRIM_OMEGA: 8222 case (int)ScriptBaseClass.PRIM_OMEGA:
8462 if (remain < 3) 8223 if (remain < 3)
@@ -8466,7 +8227,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8466 LSL_Float gain = rules.GetLSLFloatItem(idx++); 8227 LSL_Float gain = rules.GetLSLFloatItem(idx++);
8467 TargetOmega(part, axis, (double)spinrate, (double)gain); 8228 TargetOmega(part, axis, (double)spinrate, (double)gain);
8468 break; 8229 break;
8469 8230 case (int)ScriptBaseClass.PRIM_SLICE:
8231 if (remain < 1)
8232 return null;
8233 LSL_Vector slice = rules.GetVector3Item(idx++);
8234 part.UpdateSlice((float)slice.x, (float)slice.y);
8235 break;
8470 case (int)ScriptBaseClass.PRIM_LINK_TARGET: 8236 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
8471 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless. 8237 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
8472 return null; 8238 return null;
@@ -8475,6 +8241,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8475 } 8241 }
8476 } 8242 }
8477 } 8243 }
8244 catch (InvalidCastException e)
8245 {
8246 ShoutError(string.Format(
8247 "{0} error running rule #{1}: arg #{2} ",
8248 originFunc, rulesParsed, idx - idxStart) + e.Message);
8249 }
8478 finally 8250 finally
8479 { 8251 {
8480 if (positionChanged) 8252 if (positionChanged)
@@ -8483,12 +8255,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8483 { 8255 {
8484 SceneObjectGroup parent = part.ParentGroup; 8256 SceneObjectGroup parent = part.ParentGroup;
8485 Util.FireAndForget(delegate(object x) { 8257 Util.FireAndForget(delegate(object x) {
8486 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z)); 8258 parent.UpdateGroupPosition(currentPosition);
8487 }); 8259 });
8488 } 8260 }
8489 else 8261 else
8490 { 8262 {
8491 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z); 8263 part.OffsetPosition = currentPosition;
8492 SceneObjectGroup parent = part.ParentGroup; 8264 SceneObjectGroup parent = part.ParentGroup;
8493 parent.HasGroupChanged = true; 8265 parent.HasGroupChanged = true;
8494 parent.ScheduleGroupForTerseUpdate(); 8266 parent.ScheduleGroupForTerseUpdate();
@@ -8866,7 +8638,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8866 public LSL_List llGetPrimitiveParams(LSL_List rules) 8638 public LSL_List llGetPrimitiveParams(LSL_List rules)
8867 { 8639 {
8868 m_host.AddScriptLPS(1); 8640 m_host.AddScriptLPS(1);
8869 return GetLinkPrimitiveParams(m_host, rules); 8641
8642 LSL_List result = new LSL_List();
8643
8644 LSL_List remaining = GetPrimParams(m_host, rules, ref result);
8645
8646 while (remaining != null && remaining.Length > 2)
8647 {
8648 int linknumber = remaining.GetLSLIntegerItem(0);
8649 rules = remaining.GetSublist(1, -1);
8650 List<SceneObjectPart> parts = GetLinkParts(linknumber);
8651
8652 foreach (SceneObjectPart part in parts)
8653 remaining = GetPrimParams(part, rules, ref result);
8654 }
8655
8656 return result;
8870 } 8657 }
8871 8658
8872 public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules) 8659 public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules)
@@ -8876,294 +8663,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8876 // acording to SL wiki this must indicate a single link number or link_root or link_this. 8663 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8877 // keep other options as before 8664 // keep other options as before
8878 8665
8879 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8666 List<SceneObjectPart> parts;
8880 List<ScenePresence> avatars = GetLinkAvatars(linknumber); 8667 List<ScenePresence> avatars;
8881 8668
8882 LSL_List res = new LSL_List(); 8669 LSL_List res = new LSL_List();
8670 LSL_List remaining = null;
8883 8671
8884 if (parts.Count > 0) 8672 while (rules.Length > 0)
8885 { 8673 {
8886 foreach (var part in parts) 8674 parts = GetLinkParts(linknumber);
8675 avatars = GetLinkAvatars(linknumber);
8676
8677 remaining = null;
8678 foreach (SceneObjectPart part in parts)
8887 { 8679 {
8888 LSL_List partRes = GetLinkPrimitiveParams(part, rules); 8680 remaining = GetPrimParams(part, rules, ref res);
8889 res += partRes;
8890 } 8681 }
8891 }
8892 if (avatars.Count > 0)
8893 {
8894 foreach (ScenePresence avatar in avatars) 8682 foreach (ScenePresence avatar in avatars)
8895 { 8683 {
8896 LSL_List avaRes = GetLinkPrimitiveParams(avatar, rules); 8684 remaining = GetPrimParams(avatar, rules, ref res);
8897 res += avaRes;
8898 } 8685 }
8899 }
8900 return res;
8901 }
8902
8903 public LSL_List GetLinkPrimitiveParams(ScenePresence avatar, LSL_List rules)
8904 {
8905 // avatars case
8906 // replies as SL wiki
8907
8908 LSL_List res = new LSL_List();
8909// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
8910 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
8911 8686
8912 int idx = 0; 8687 if (remaining != null && remaining.Length > 0)
8913 while (idx < rules.Length)
8914 {
8915 int code = (int)rules.GetLSLIntegerItem(idx++);
8916 int remain = rules.Length - idx;
8917
8918 switch (code)
8919 { 8688 {
8920 case (int)ScriptBaseClass.PRIM_MATERIAL: 8689 linknumber = remaining.GetLSLIntegerItem(0);
8921 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh)); 8690 rules = remaining.GetSublist(1, -1);
8922 break;
8923
8924 case (int)ScriptBaseClass.PRIM_PHYSICS:
8925 res.Add(new LSL_Integer(0));
8926 break;
8927
8928 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
8929 res.Add(new LSL_Integer(0));
8930 break;
8931
8932 case (int)ScriptBaseClass.PRIM_PHANTOM:
8933 res.Add(new LSL_Integer(0));
8934 break;
8935
8936 case (int)ScriptBaseClass.PRIM_POSITION:
8937
8938 Vector3 pos = avatar.OffsetPosition;
8939
8940 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
8941 pos -= sitOffset;
8942
8943 if( sitPart != null)
8944 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
8945
8946 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
8947 break;
8948
8949 case (int)ScriptBaseClass.PRIM_SIZE:
8950 // as in llGetAgentSize above
8951 res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
8952 break;
8953
8954 case (int)ScriptBaseClass.PRIM_ROTATION:
8955 Quaternion rot = avatar.Rotation;
8956 if (sitPart != null)
8957 {
8958 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
8959 }
8960
8961 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
8962 break;
8963
8964 case (int)ScriptBaseClass.PRIM_TYPE:
8965 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
8966 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
8967 res.Add(new LSL_Vector(0f,1.0f,0f));
8968 res.Add(new LSL_Float(0.0f));
8969 res.Add(new LSL_Vector(0, 0, 0));
8970 res.Add(new LSL_Vector(1.0f,1.0f,0f));
8971 res.Add(new LSL_Vector(0, 0, 0));
8972 break;
8973
8974 case (int)ScriptBaseClass.PRIM_TEXTURE:
8975 if (remain < 1)
8976 return res;
8977
8978 int face = (int)rules.GetLSLIntegerItem(idx++);
8979 if (face == ScriptBaseClass.ALL_SIDES)
8980 {
8981 for (face = 0; face < 21; face++)
8982 {
8983 res.Add(new LSL_String(""));
8984 res.Add(new LSL_Vector(0,0,0));
8985 res.Add(new LSL_Vector(0,0,0));
8986 res.Add(new LSL_Float(0.0));
8987 }
8988 }
8989 else
8990 {
8991 if (face >= 0 && face < 21)
8992 {
8993 res.Add(new LSL_String(""));
8994 res.Add(new LSL_Vector(0,0,0));
8995 res.Add(new LSL_Vector(0,0,0));
8996 res.Add(new LSL_Float(0.0));
8997 }
8998 }
8999 break;
9000
9001 case (int)ScriptBaseClass.PRIM_COLOR:
9002 if (remain < 1)
9003 return res;
9004
9005 face = (int)rules.GetLSLIntegerItem(idx++);
9006
9007 if (face == ScriptBaseClass.ALL_SIDES)
9008 {
9009 for (face = 0; face < 21; face++)
9010 {
9011 res.Add(new LSL_Vector(0,0,0));
9012 res.Add(new LSL_Float(0));
9013 }
9014 }
9015 else
9016 {
9017 res.Add(new LSL_Vector(0,0,0));
9018 res.Add(new LSL_Float(0));
9019 }
9020 break;
9021
9022 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
9023 if (remain < 1)
9024 return res;
9025 face = (int)rules.GetLSLIntegerItem(idx++);
9026
9027 if (face == ScriptBaseClass.ALL_SIDES)
9028 {
9029 for (face = 0; face < 21; face++)
9030 {
9031 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
9032 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
9033 }
9034 }
9035 else
9036 {
9037 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
9038 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
9039 }
9040 break;
9041
9042 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
9043 if (remain < 1)
9044 return res;
9045 face = (int)rules.GetLSLIntegerItem(idx++);
9046
9047 if (face == ScriptBaseClass.ALL_SIDES)
9048 {
9049 for (face = 0; face < 21; face++)
9050 {
9051 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
9052 }
9053 }
9054 else
9055 {
9056 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
9057 }
9058 break;
9059
9060 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
9061 res.Add(new LSL_Integer(0));
9062 res.Add(new LSL_Integer(0));// softness
9063 res.Add(new LSL_Float(0.0f)); // gravity
9064 res.Add(new LSL_Float(0.0f)); // friction
9065 res.Add(new LSL_Float(0.0f)); // wind
9066 res.Add(new LSL_Float(0.0f)); // tension
9067 res.Add(new LSL_Vector(0f,0f,0f));
9068 break;
9069
9070 case (int)ScriptBaseClass.PRIM_TEXGEN:
9071 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
9072 if (remain < 1)
9073 return res;
9074 face = (int)rules.GetLSLIntegerItem(idx++);
9075
9076 if (face == ScriptBaseClass.ALL_SIDES)
9077 {
9078 for (face = 0; face < 21; face++)
9079 {
9080 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9081 }
9082 }
9083 else
9084 {
9085 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9086 }
9087 break;
9088
9089 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
9090 res.Add(new LSL_Integer(0));
9091 res.Add(new LSL_Vector(0f,0f,0f));
9092 res.Add(new LSL_Float(0f)); // intensity
9093 res.Add(new LSL_Float(0f)); // radius
9094 res.Add(new LSL_Float(0f)); // falloff
9095 break;
9096
9097 case (int)ScriptBaseClass.PRIM_GLOW:
9098 if (remain < 1)
9099 return res;
9100 face = (int)rules.GetLSLIntegerItem(idx++);
9101
9102 if (face == ScriptBaseClass.ALL_SIDES)
9103 {
9104 for (face = 0; face < 21; face++)
9105 {
9106 res.Add(new LSL_Float(0f));
9107 }
9108 }
9109 else
9110 {
9111 res.Add(new LSL_Float(0f));
9112 }
9113 break;
9114
9115 case (int)ScriptBaseClass.PRIM_TEXT:
9116 res.Add(new LSL_String(""));
9117 res.Add(new LSL_Vector(0f,0f,0f));
9118 res.Add(new LSL_Float(1.0f));
9119 break;
9120
9121 case (int)ScriptBaseClass.PRIM_NAME:
9122 res.Add(new LSL_String(avatar.Name));
9123 break;
9124
9125 case (int)ScriptBaseClass.PRIM_DESC:
9126 res.Add(new LSL_String(""));
9127 break;
9128
9129 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
9130 Quaternion lrot = avatar.Rotation;
9131
9132 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
9133 {
9134 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
9135 }
9136 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
9137 break;
9138
9139 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
9140 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
9141 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
9142 lpos -= lsitOffset;
9143
9144 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
9145 {
9146 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
9147 }
9148 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
9149 break;
9150
9151 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
9152 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
9153 return res;
9154 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
9155 LSL_List new_rules = rules.GetSublist(idx, -1);
9156
9157 res += llGetLinkPrimitiveParams((int)new_linknumber, new_rules);
9158 return res;
9159 } 8691 }
9160 } 8692 }
8693
9161 return res; 8694 return res;
9162 } 8695 }
9163 8696
9164 public LSL_List GetLinkPrimitiveParams(SceneObjectPart part, LSL_List rules) 8697 public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res)
9165 { 8698 {
9166 LSL_List res = new LSL_List();
9167 int idx=0; 8699 int idx=0;
9168 while (idx < rules.Length) 8700 while (idx < rules.Length)
9169 { 8701 {
@@ -9301,7 +8833,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9301 8833
9302 case (int)ScriptBaseClass.PRIM_TEXTURE: 8834 case (int)ScriptBaseClass.PRIM_TEXTURE:
9303 if (remain < 1) 8835 if (remain < 1)
9304 return res; 8836 return null;
9305 8837
9306 int face = (int)rules.GetLSLIntegerItem(idx++); 8838 int face = (int)rules.GetLSLIntegerItem(idx++);
9307 Primitive.TextureEntry tex = part.Shape.Textures; 8839 Primitive.TextureEntry tex = part.Shape.Textures;
@@ -9341,7 +8873,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9341 8873
9342 case (int)ScriptBaseClass.PRIM_COLOR: 8874 case (int)ScriptBaseClass.PRIM_COLOR:
9343 if (remain < 1) 8875 if (remain < 1)
9344 return res; 8876 return null;
9345 8877
9346 face=(int)rules.GetLSLIntegerItem(idx++); 8878 face=(int)rules.GetLSLIntegerItem(idx++);
9347 8879
@@ -9370,7 +8902,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9370 8902
9371 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8903 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
9372 if (remain < 1) 8904 if (remain < 1)
9373 return res; 8905 return null;
8906
9374 face = (int)rules.GetLSLIntegerItem(idx++); 8907 face = (int)rules.GetLSLIntegerItem(idx++);
9375 8908
9376 tex = part.Shape.Textures; 8909 tex = part.Shape.Textures;
@@ -9426,7 +8959,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9426 8959
9427 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8960 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
9428 if (remain < 1) 8961 if (remain < 1)
9429 return res; 8962 return null;
8963
9430 face = (int)rules.GetLSLIntegerItem(idx++); 8964 face = (int)rules.GetLSLIntegerItem(idx++);
9431 8965
9432 tex = part.Shape.Textures; 8966 tex = part.Shape.Textures;
@@ -9480,7 +9014,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9480 case (int)ScriptBaseClass.PRIM_TEXGEN: 9014 case (int)ScriptBaseClass.PRIM_TEXGEN:
9481 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR) 9015 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
9482 if (remain < 1) 9016 if (remain < 1)
9483 return res; 9017 return null;
9018
9484 face = (int)rules.GetLSLIntegerItem(idx++); 9019 face = (int)rules.GetLSLIntegerItem(idx++);
9485 9020
9486 tex = part.Shape.Textures; 9021 tex = part.Shape.Textures;
@@ -9528,7 +9063,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9528 9063
9529 case (int)ScriptBaseClass.PRIM_GLOW: 9064 case (int)ScriptBaseClass.PRIM_GLOW:
9530 if (remain < 1) 9065 if (remain < 1)
9531 return res; 9066 return null;
9067
9532 face = (int)rules.GetLSLIntegerItem(idx++); 9068 face = (int)rules.GetLSLIntegerItem(idx++);
9533 9069
9534 tex = part.Shape.Textures; 9070 tex = part.Shape.Textures;
@@ -9572,18 +9108,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9572 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9108 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
9573 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9109 res.Add(new LSL_Vector(GetPartLocalPos(part)));
9574 break; 9110 break;
9575 9111 case (int)ScriptBaseClass.PRIM_SLICE:
9112 PrimType prim_type = part.GetPrimType();
9113 bool useProfileBeginEnd = (prim_type == PrimType.SPHERE || prim_type == PrimType.TORUS || prim_type == PrimType.TUBE || prim_type == PrimType.RING);
9114 res.Add(new LSL_Vector(
9115 (useProfileBeginEnd ? part.Shape.ProfileBegin : part.Shape.PathBegin) / 50000.0,
9116 1 - (useProfileBeginEnd ? part.Shape.ProfileEnd : part.Shape.PathEnd) / 50000.0,
9117 0
9118 ));
9119 break;
9576 case (int)ScriptBaseClass.PRIM_LINK_TARGET: 9120 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
9577 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless. 9121 if(remain < 3)
9578 return res; 9122 return null;
9579 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++); 9123
9580 LSL_List new_rules = rules.GetSublist(idx, -1); 9124 return rules.GetSublist(idx, -1);
9581 LSL_List tres = llGetLinkPrimitiveParams((int)new_linknumber, new_rules);
9582 res += tres;
9583 return res;
9584 } 9125 }
9585 } 9126 }
9586 return res; 9127
9128 return null;
9587 } 9129 }
9588 9130
9589 public LSL_List llGetPrimMediaParams(int face, LSL_List rules) 9131 public LSL_List llGetPrimMediaParams(int face, LSL_List rules)
@@ -10983,20 +10525,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10983 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString())) 10525 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
10984 { 10526 {
10985 case ParcelMediaCommandEnum.Url: 10527 case ParcelMediaCommandEnum.Url:
10986 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10528 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
10987 break; 10529 break;
10988 case ParcelMediaCommandEnum.Desc: 10530 case ParcelMediaCommandEnum.Desc:
10989 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).Description)); 10531 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).Description));
10990 break; 10532 break;
10991 case ParcelMediaCommandEnum.Texture: 10533 case ParcelMediaCommandEnum.Texture:
10992 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaID.ToString())); 10534 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaID.ToString()));
10993 break; 10535 break;
10994 case ParcelMediaCommandEnum.Type: 10536 case ParcelMediaCommandEnum.Type:
10995 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaType)); 10537 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaType));
10996 break; 10538 break;
10997 case ParcelMediaCommandEnum.Size: 10539 case ParcelMediaCommandEnum.Size:
10998 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaWidth)); 10540 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaWidth));
10999 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaHeight)); 10541 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaHeight));
11000 break; 10542 break;
11001 default: 10543 default:
11002 ParcelMediaCommandEnum mediaCommandEnum = ParcelMediaCommandEnum.Url; 10544 ParcelMediaCommandEnum mediaCommandEnum = ParcelMediaCommandEnum.Url;
@@ -11166,9 +10708,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11166 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10708 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
11167 if (avatar != null) 10709 if (avatar != null)
11168 { 10710 {
11169 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, simname, 10711 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
11170 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 10712 simname, pos, lookAt);
11171 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
11172 } 10713 }
11173 10714
11174 ScriptSleep(1000); 10715 ScriptSleep(1000);
@@ -11353,31 +10894,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11353 public LSL_Float llListStatistics(int operation, LSL_List src) 10894 public LSL_Float llListStatistics(int operation, LSL_List src)
11354 { 10895 {
11355 m_host.AddScriptLPS(1); 10896 m_host.AddScriptLPS(1);
11356 LSL_List nums = LSL_List.ToDoubleList(src);
11357 switch (operation) 10897 switch (operation)
11358 { 10898 {
11359 case ScriptBaseClass.LIST_STAT_RANGE: 10899 case ScriptBaseClass.LIST_STAT_RANGE:
11360 return nums.Range(); 10900 return src.Range();
11361 case ScriptBaseClass.LIST_STAT_MIN: 10901 case ScriptBaseClass.LIST_STAT_MIN:
11362 return nums.Min(); 10902 return src.Min();
11363 case ScriptBaseClass.LIST_STAT_MAX: 10903 case ScriptBaseClass.LIST_STAT_MAX:
11364 return nums.Max(); 10904 return src.Max();
11365 case ScriptBaseClass.LIST_STAT_MEAN: 10905 case ScriptBaseClass.LIST_STAT_MEAN:
11366 return nums.Mean(); 10906 return src.Mean();
11367 case ScriptBaseClass.LIST_STAT_MEDIAN: 10907 case ScriptBaseClass.LIST_STAT_MEDIAN:
11368 return nums.Median(); 10908 return LSL_List.ToDoubleList(src).Median();
11369 case ScriptBaseClass.LIST_STAT_NUM_COUNT: 10909 case ScriptBaseClass.LIST_STAT_NUM_COUNT:
11370 return nums.NumericLength(); 10910 return src.NumericLength();
11371 case ScriptBaseClass.LIST_STAT_STD_DEV: 10911 case ScriptBaseClass.LIST_STAT_STD_DEV:
11372 return nums.StdDev(); 10912 return src.StdDev();
11373 case ScriptBaseClass.LIST_STAT_SUM: 10913 case ScriptBaseClass.LIST_STAT_SUM:
11374 return nums.Sum(); 10914 return src.Sum();
11375 case ScriptBaseClass.LIST_STAT_SUM_SQUARES: 10915 case ScriptBaseClass.LIST_STAT_SUM_SQUARES:
11376 return nums.SumSqrs(); 10916 return src.SumSqrs();
11377 case ScriptBaseClass.LIST_STAT_GEOMETRIC_MEAN: 10917 case ScriptBaseClass.LIST_STAT_GEOMETRIC_MEAN:
11378 return nums.GeometricMean(); 10918 return src.GeometricMean();
11379 case ScriptBaseClass.LIST_STAT_HARMONIC_MEAN: 10919 case ScriptBaseClass.LIST_STAT_HARMONIC_MEAN:
11380 return nums.HarmonicMean(); 10920 return src.HarmonicMean();
11381 default: 10921 default:
11382 return 0.0; 10922 return 0.0;
11383 } 10923 }
@@ -11735,7 +11275,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11735 public LSL_List llGetParcelDetails(LSL_Vector pos, LSL_List param) 11275 public LSL_List llGetParcelDetails(LSL_Vector pos, LSL_List param)
11736 { 11276 {
11737 m_host.AddScriptLPS(1); 11277 m_host.AddScriptLPS(1);
11738 LandData land = World.GetLandData((float)pos.x, (float)pos.y); 11278 LandData land = World.GetLandData(pos);
11739 if (land == null) 11279 if (land == null)
11740 { 11280 {
11741 return new LSL_List(0); 11281 return new LSL_List(0);
@@ -11903,13 +11443,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11903 else 11443 else
11904 rot = obj.GetWorldRotation(); 11444 rot = obj.GetWorldRotation();
11905 11445
11906 LSL_Rotation objrot = new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W); 11446 LSL_Rotation objrot = new LSL_Rotation(rot);
11907 ret.Add(objrot); 11447 ret.Add(objrot);
11908 } 11448 }
11909 break; 11449 break;
11910 case ScriptBaseClass.OBJECT_VELOCITY: 11450 case ScriptBaseClass.OBJECT_VELOCITY:
11911 Vector3 ovel = obj.Velocity; 11451 ret.Add(new LSL_Vector(obj.Velocity));
11912 ret.Add(new LSL_Vector(ovel.X, ovel.Y, ovel.Z));
11913 break; 11452 break;
11914 case ScriptBaseClass.OBJECT_OWNER: 11453 case ScriptBaseClass.OBJECT_OWNER:
11915 ret.Add(new LSL_String(obj.OwnerID.ToString())); 11454 ret.Add(new LSL_String(obj.OwnerID.ToString()));
@@ -12122,7 +11661,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12122 return tid.ToString(); 11661 return tid.ToString();
12123 } 11662 }
12124 11663
12125 public void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules) 11664 public void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc)
12126 { 11665 {
12127 SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim)); 11666 SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim));
12128 if (obj == null) 11667 if (obj == null)
@@ -12131,28 +11670,41 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12131 if (obj.OwnerID != m_host.OwnerID) 11670 if (obj.OwnerID != m_host.OwnerID)
12132 return; 11671 return;
12133 11672
12134 LSL_List remaining = SetPrimParams(obj, rules); 11673 uint rulesParsed = 0;
11674 LSL_List remaining = SetPrimParams(obj, rules, originFunc, ref rulesParsed);
12135 11675
12136 while ((object)remaining != null && remaining.Length > 2) 11676 while ((object)remaining != null && remaining.Length > 2)
12137 { 11677 {
12138 LSL_Integer newLink = remaining.GetLSLIntegerItem(0); 11678 LSL_Integer newLink = remaining.GetLSLIntegerItem(0);
12139 LSL_List newrules = remaining.GetSublist(1, -1); 11679 LSL_List newrules = remaining.GetSublist(1, -1);
12140 foreach(SceneObjectPart part in GetLinkParts(obj, newLink)){ 11680 foreach(SceneObjectPart part in GetLinkParts(obj, newLink)){
12141 remaining = SetPrimParams(part, newrules); 11681 remaining = SetPrimParams(part, newrules, originFunc, ref rulesParsed);
12142 } 11682 }
12143 } 11683 }
12144 } 11684 }
12145 11685
12146 public LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules) 11686 public LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules)
12147 { 11687 {
12148 SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim)); 11688 SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim));
12149 if (obj == null)
12150 return new LSL_List();
12151 11689
12152 if (obj.OwnerID != m_host.OwnerID) 11690 LSL_List result = new LSL_List();
12153 return new LSL_List(); 11691
11692 if (obj != null && obj.OwnerID != m_host.OwnerID)
11693 {
11694 LSL_List remaining = GetPrimParams(obj, rules, ref result);
11695
11696 while (remaining != null && remaining.Length > 2)
11697 {
11698 int linknumber = remaining.GetLSLIntegerItem(0);
11699 rules = remaining.GetSublist(1, -1);
11700 List<SceneObjectPart> parts = GetLinkParts(linknumber);
11701
11702 foreach (SceneObjectPart part in parts)
11703 remaining = GetPrimParams(part, rules, ref result);
11704 }
11705 }
12154 11706
12155 return GetLinkPrimitiveParams(obj, rules); 11707 return result;
12156 } 11708 }
12157 11709
12158 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link) 11710 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
@@ -12515,8 +12067,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12515 12067
12516 m_host.AddScriptLPS(1); 12068 m_host.AddScriptLPS(1);
12517 12069
12518 Vector3 rayStart = new Vector3((float)start.x, (float)start.y, (float)start.z); 12070 Vector3 rayStart = start;
12519 Vector3 rayEnd = new Vector3((float)end.x, (float)end.y, (float)end.z); 12071 Vector3 rayEnd = end;
12520 Vector3 dir = rayEnd - rayStart; 12072 Vector3 dir = rayEnd - rayStart;
12521 12073
12522 float dist = Vector3.Mag(dir); 12074 float dist = Vector3.Mag(dir);
@@ -13090,6 +12642,455 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13090 } 12642 }
13091 } 12643 }
13092 } 12644 }
12645
12646 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
12647 {
12648 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
12649
12650 int idx = 0;
12651 int idxStart = 0;
12652
12653 bool positionChanged = false;
12654 Vector3 finalPos = Vector3.Zero;
12655
12656 try
12657 {
12658 while (idx < rules.Length)
12659 {
12660 ++rulesParsed;
12661 int code = rules.GetLSLIntegerItem(idx++);
12662
12663 int remain = rules.Length - idx;
12664 idxStart = idx;
12665
12666 switch (code)
12667 {
12668 case (int)ScriptBaseClass.PRIM_POSITION:
12669 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
12670 {
12671 if (remain < 1)
12672 return null;
12673
12674 LSL_Vector v;
12675 v = rules.GetVector3Item(idx++);
12676
12677 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12678 if (part == null)
12679 break;
12680
12681 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12682 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12683 if (part.LinkNum > 1)
12684 {
12685 localRot = GetPartLocalRot(part);
12686 localPos = GetPartLocalPos(part);
12687 }
12688
12689 v -= localPos;
12690 v /= localRot;
12691
12692 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
12693
12694 v = v + 2 * sitOffset;
12695
12696 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
12697 av.SendAvatarDataToAllAgents();
12698
12699 }
12700 break;
12701
12702 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
12703 case (int)ScriptBaseClass.PRIM_ROTATION:
12704 {
12705 if (remain < 1)
12706 return null;
12707
12708 LSL_Rotation r;
12709 r = rules.GetQuaternionItem(idx++);
12710
12711 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12712 if (part == null)
12713 break;
12714
12715 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12716 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12717
12718 if (part.LinkNum > 1)
12719 localRot = GetPartLocalRot(part);
12720
12721 r = r * llGetRootRotation() / localRot;
12722 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
12723 av.SendAvatarDataToAllAgents();
12724 }
12725 break;
12726
12727 // parse rest doing nothing but number of parameters error check
12728 case (int)ScriptBaseClass.PRIM_SIZE:
12729 case (int)ScriptBaseClass.PRIM_MATERIAL:
12730 case (int)ScriptBaseClass.PRIM_PHANTOM:
12731 case (int)ScriptBaseClass.PRIM_PHYSICS:
12732 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
12733 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12734 case (int)ScriptBaseClass.PRIM_NAME:
12735 case (int)ScriptBaseClass.PRIM_DESC:
12736 if (remain < 1)
12737 return null;
12738 idx++;
12739 break;
12740
12741 case (int)ScriptBaseClass.PRIM_GLOW:
12742 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12743 case (int)ScriptBaseClass.PRIM_TEXGEN:
12744 if (remain < 2)
12745 return null;
12746 idx += 2;
12747 break;
12748
12749 case (int)ScriptBaseClass.PRIM_TYPE:
12750 if (remain < 3)
12751 return null;
12752 code = (int)rules.GetLSLIntegerItem(idx++);
12753 remain = rules.Length - idx;
12754 switch (code)
12755 {
12756 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
12757 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
12758 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
12759 if (remain < 6)
12760 return null;
12761 idx += 6;
12762 break;
12763
12764 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
12765 if (remain < 5)
12766 return null;
12767 idx += 5;
12768 break;
12769
12770 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
12771 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
12772 case (int)ScriptBaseClass.PRIM_TYPE_RING:
12773 if (remain < 11)
12774 return null;
12775 idx += 11;
12776 break;
12777
12778 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
12779 if (remain < 2)
12780 return null;
12781 idx += 2;
12782 break;
12783 }
12784 break;
12785
12786 case (int)ScriptBaseClass.PRIM_COLOR:
12787 case (int)ScriptBaseClass.PRIM_TEXT:
12788 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12789 case (int)ScriptBaseClass.PRIM_OMEGA:
12790 if (remain < 3)
12791 return null;
12792 idx += 3;
12793 break;
12794
12795 case (int)ScriptBaseClass.PRIM_TEXTURE:
12796 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
12797 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
12798 if (remain < 5)
12799 return null;
12800 idx += 5;
12801 break;
12802
12803 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
12804 if (remain < 7)
12805 return null;
12806
12807 idx += 7;
12808 break;
12809
12810 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
12811 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
12812 return null;
12813
12814 return rules.GetSublist(idx, -1);
12815 }
12816 }
12817 }
12818 catch (InvalidCastException e)
12819 {
12820 ShoutError(string.Format(
12821 "{0} error running rule #{1}: arg #{2} ",
12822 originFunc, rulesParsed, idx - idxStart) + e.Message);
12823 }
12824 finally
12825 {
12826 if (positionChanged)
12827 {
12828 av.OffsetPosition = finalPos;
12829// av.SendAvatarDataToAllAgents();
12830 av.SendTerseUpdateToAllClients();
12831 positionChanged = false;
12832 }
12833 }
12834 return null;
12835 }
12836
12837 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
12838 {
12839 // avatars case
12840 // replies as SL wiki
12841
12842// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
12843 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
12844
12845 int idx = 0;
12846 while (idx < rules.Length)
12847 {
12848 int code = (int)rules.GetLSLIntegerItem(idx++);
12849 int remain = rules.Length - idx;
12850
12851 switch (code)
12852 {
12853 case (int)ScriptBaseClass.PRIM_MATERIAL:
12854 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
12855 break;
12856
12857 case (int)ScriptBaseClass.PRIM_PHYSICS:
12858 res.Add(new LSL_Integer(0));
12859 break;
12860
12861 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12862 res.Add(new LSL_Integer(0));
12863 break;
12864
12865 case (int)ScriptBaseClass.PRIM_PHANTOM:
12866 res.Add(new LSL_Integer(0));
12867 break;
12868
12869 case (int)ScriptBaseClass.PRIM_POSITION:
12870
12871 Vector3 pos = avatar.OffsetPosition;
12872
12873 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
12874 pos -= sitOffset;
12875
12876 if( sitPart != null)
12877 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
12878
12879 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
12880 break;
12881
12882 case (int)ScriptBaseClass.PRIM_SIZE:
12883 // as in llGetAgentSize above
12884 res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
12885 break;
12886
12887 case (int)ScriptBaseClass.PRIM_ROTATION:
12888 Quaternion rot = avatar.Rotation;
12889 if (sitPart != null)
12890 {
12891 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
12892 }
12893
12894 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
12895 break;
12896
12897 case (int)ScriptBaseClass.PRIM_TYPE:
12898 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
12899 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
12900 res.Add(new LSL_Vector(0f,1.0f,0f));
12901 res.Add(new LSL_Float(0.0f));
12902 res.Add(new LSL_Vector(0, 0, 0));
12903 res.Add(new LSL_Vector(1.0f,1.0f,0f));
12904 res.Add(new LSL_Vector(0, 0, 0));
12905 break;
12906
12907 case (int)ScriptBaseClass.PRIM_TEXTURE:
12908 if (remain < 1)
12909 return null;
12910
12911 int face = (int)rules.GetLSLIntegerItem(idx++);
12912 if (face == ScriptBaseClass.ALL_SIDES)
12913 {
12914 for (face = 0; face < 21; face++)
12915 {
12916 res.Add(new LSL_String(""));
12917 res.Add(new LSL_Vector(0,0,0));
12918 res.Add(new LSL_Vector(0,0,0));
12919 res.Add(new LSL_Float(0.0));
12920 }
12921 }
12922 else
12923 {
12924 if (face >= 0 && face < 21)
12925 {
12926 res.Add(new LSL_String(""));
12927 res.Add(new LSL_Vector(0,0,0));
12928 res.Add(new LSL_Vector(0,0,0));
12929 res.Add(new LSL_Float(0.0));
12930 }
12931 }
12932 break;
12933
12934 case (int)ScriptBaseClass.PRIM_COLOR:
12935 if (remain < 1)
12936 return null;
12937
12938 face = (int)rules.GetLSLIntegerItem(idx++);
12939
12940 if (face == ScriptBaseClass.ALL_SIDES)
12941 {
12942 for (face = 0; face < 21; face++)
12943 {
12944 res.Add(new LSL_Vector(0,0,0));
12945 res.Add(new LSL_Float(0));
12946 }
12947 }
12948 else
12949 {
12950 res.Add(new LSL_Vector(0,0,0));
12951 res.Add(new LSL_Float(0));
12952 }
12953 break;
12954
12955 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12956 if (remain < 1)
12957 return null;
12958 face = (int)rules.GetLSLIntegerItem(idx++);
12959
12960 if (face == ScriptBaseClass.ALL_SIDES)
12961 {
12962 for (face = 0; face < 21; face++)
12963 {
12964 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
12965 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
12966 }
12967 }
12968 else
12969 {
12970 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
12971 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
12972 }
12973 break;
12974
12975 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12976 if (remain < 1)
12977 return null;
12978 face = (int)rules.GetLSLIntegerItem(idx++);
12979
12980 if (face == ScriptBaseClass.ALL_SIDES)
12981 {
12982 for (face = 0; face < 21; face++)
12983 {
12984 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
12985 }
12986 }
12987 else
12988 {
12989 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
12990 }
12991 break;
12992
12993 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
12994 res.Add(new LSL_Integer(0));
12995 res.Add(new LSL_Integer(0));// softness
12996 res.Add(new LSL_Float(0.0f)); // gravity
12997 res.Add(new LSL_Float(0.0f)); // friction
12998 res.Add(new LSL_Float(0.0f)); // wind
12999 res.Add(new LSL_Float(0.0f)); // tension
13000 res.Add(new LSL_Vector(0f,0f,0f));
13001 break;
13002
13003 case (int)ScriptBaseClass.PRIM_TEXGEN:
13004 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
13005 if (remain < 1)
13006 return null;
13007 face = (int)rules.GetLSLIntegerItem(idx++);
13008
13009 if (face == ScriptBaseClass.ALL_SIDES)
13010 {
13011 for (face = 0; face < 21; face++)
13012 {
13013 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13014 }
13015 }
13016 else
13017 {
13018 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13019 }
13020 break;
13021
13022 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13023 res.Add(new LSL_Integer(0));
13024 res.Add(new LSL_Vector(0f,0f,0f));
13025 res.Add(new LSL_Float(0f)); // intensity
13026 res.Add(new LSL_Float(0f)); // radius
13027 res.Add(new LSL_Float(0f)); // falloff
13028 break;
13029
13030 case (int)ScriptBaseClass.PRIM_GLOW:
13031 if (remain < 1)
13032 return null;
13033 face = (int)rules.GetLSLIntegerItem(idx++);
13034
13035 if (face == ScriptBaseClass.ALL_SIDES)
13036 {
13037 for (face = 0; face < 21; face++)
13038 {
13039 res.Add(new LSL_Float(0f));
13040 }
13041 }
13042 else
13043 {
13044 res.Add(new LSL_Float(0f));
13045 }
13046 break;
13047
13048 case (int)ScriptBaseClass.PRIM_TEXT:
13049 res.Add(new LSL_String(""));
13050 res.Add(new LSL_Vector(0f,0f,0f));
13051 res.Add(new LSL_Float(1.0f));
13052 break;
13053
13054 case (int)ScriptBaseClass.PRIM_NAME:
13055 res.Add(new LSL_String(avatar.Name));
13056 break;
13057
13058 case (int)ScriptBaseClass.PRIM_DESC:
13059 res.Add(new LSL_String(""));
13060 break;
13061
13062 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13063 Quaternion lrot = avatar.Rotation;
13064
13065 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13066 {
13067 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13068 }
13069 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13070 break;
13071
13072 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13073 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13074 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13075 lpos -= lsitOffset;
13076
13077 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13078 {
13079 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13080 }
13081 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13082 break;
13083
13084 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13085 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13086 return null;
13087
13088 return rules.GetSublist(idx, -1);
13089 }
13090 }
13091
13092 return null;
13093 }
13093 } 13094 }
13094 13095
13095 public class NotecardCache 13096 public class NotecardCache
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
index 795de80..ceb4660 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
@@ -304,7 +304,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
304 case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY: 304 case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY:
305 idx++; 305 idx++;
306 iV = rules.GetVector3Item(idx); 306 iV = rules.GetVector3Item(idx);
307 wl.cloudDetailXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); 307 wl.cloudDetailXYDensity = iV;
308 break; 308 break;
309 case (int)ScriptBaseClass.WL_CLOUD_SCALE: 309 case (int)ScriptBaseClass.WL_CLOUD_SCALE:
310 idx++; 310 idx++;
@@ -329,7 +329,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
329 case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY: 329 case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY:
330 idx++; 330 idx++;
331 iV = rules.GetVector3Item(idx); 331 iV = rules.GetVector3Item(idx);
332 wl.cloudXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); 332 wl.cloudXYDensity = iV;
333 break; 333 break;
334 case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER: 334 case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER:
335 idx++; 335 idx++;
@@ -384,7 +384,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
384 case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE: 384 case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE:
385 idx++; 385 idx++;
386 iV = rules.GetVector3Item(idx); 386 iV = rules.GetVector3Item(idx);
387 wl.reflectionWaveletScale = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); 387 wl.reflectionWaveletScale = iV;
388 break; 388 break;
389 case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE: 389 case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE:
390 idx++; 390 idx++;
@@ -422,7 +422,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
422 case (int)ScriptBaseClass.WL_WATER_COLOR: 422 case (int)ScriptBaseClass.WL_WATER_COLOR:
423 idx++; 423 idx++;
424 iV = rules.GetVector3Item(idx); 424 iV = rules.GetVector3Item(idx);
425 wl.waterColor = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); 425 wl.waterColor = iV;
426 break; 426 break;
427 case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT: 427 case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT:
428 idx++; 428 idx++;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
index 7844c75..6809c09 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
@@ -254,7 +254,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
254 254
255 object[] convertedParms = new object[parms.Length]; 255 object[] convertedParms = new object[parms.Length];
256 for (int i = 0; i < parms.Length; i++) 256 for (int i = 0; i < parms.Length; i++)
257 convertedParms[i] = ConvertFromLSL(parms[i],signature[i]); 257 convertedParms[i] = ConvertFromLSL(parms[i],signature[i], fname);
258 258
259 // now call the function, the contract with the function is that it will always return 259 // now call the function, the contract with the function is that it will always return
260 // non-null but don't trust it completely 260 // non-null but don't trust it completely
@@ -294,7 +294,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
294 294
295 /// <summary> 295 /// <summary>
296 /// </summary> 296 /// </summary>
297 protected object ConvertFromLSL(object lslparm, Type type) 297 protected object ConvertFromLSL(object lslparm, Type type, string fname)
298 { 298 {
299 // ---------- String ---------- 299 // ---------- String ----------
300 if (lslparm is LSL_String) 300 if (lslparm is LSL_String)
@@ -310,7 +310,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
310 // ---------- Integer ---------- 310 // ---------- Integer ----------
311 else if (lslparm is LSL_Integer) 311 else if (lslparm is LSL_Integer)
312 { 312 {
313 if (type == typeof(int)) 313 if (type == typeof(int) || type == typeof(float))
314 return (int)(LSL_Integer)lslparm; 314 return (int)(LSL_Integer)lslparm;
315 } 315 }
316 316
@@ -333,8 +333,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
333 { 333 {
334 if (type == typeof(OpenMetaverse.Quaternion)) 334 if (type == typeof(OpenMetaverse.Quaternion))
335 { 335 {
336 LSL_Rotation rot = (LSL_Rotation)lslparm; 336 return (OpenMetaverse.Quaternion)((LSL_Rotation)lslparm);
337 return new OpenMetaverse.Quaternion((float)rot.x,(float)rot.y,(float)rot.z,(float)rot.s);
338 } 337 }
339 } 338 }
340 339
@@ -343,8 +342,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
343 { 342 {
344 if (type == typeof(OpenMetaverse.Vector3)) 343 if (type == typeof(OpenMetaverse.Vector3))
345 { 344 {
346 LSL_Vector vect = (LSL_Vector)lslparm; 345 return (OpenMetaverse.Vector3)((LSL_Vector)lslparm);
347 return new OpenMetaverse.Vector3((float)vect.x,(float)vect.y,(float)vect.z);
348 } 346 }
349 } 347 }
350 348
@@ -367,23 +365,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
367 result[i] = new UUID((LSL_Key)plist[i]); 365 result[i] = new UUID((LSL_Key)plist[i]);
368 else if (plist[i] is LSL_Rotation) 366 else if (plist[i] is LSL_Rotation)
369 { 367 {
370 LSL_Rotation rot = (LSL_Rotation)plist[i]; 368 result[i] = (OpenMetaverse.Quaternion)(
371 result[i] = new OpenMetaverse.Quaternion((float)rot.x,(float)rot.y,(float)rot.z,(float)rot.s); 369 (LSL_Rotation)plist[i]);
372 } 370 }
373 else if (plist[i] is LSL_Vector) 371 else if (plist[i] is LSL_Vector)
374 { 372 {
375 LSL_Vector vect = (LSL_Vector)plist[i]; 373 result[i] = (OpenMetaverse.Vector3)(
376 result[i] = new OpenMetaverse.Vector3((float)vect.x,(float)vect.y,(float)vect.z); 374 (LSL_Vector)plist[i]);
377 } 375 }
378 else 376 else
379 MODError("unknown LSL list element type"); 377 MODError(String.Format("{0}: unknown LSL list element type", fname));
380 } 378 }
381 379
382 return result; 380 return result;
383 } 381 }
384 } 382 }
385 383
386 MODError(String.Format("parameter type mismatch; expecting {0}",type.Name)); 384 MODError(String.Format("{1}: parameter type mismatch; expecting {0}",type.Name, fname));
387 return null; 385 return null;
388 } 386 }
389 387
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 2f02f1f..160e2df 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -141,6 +141,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
141 internal bool m_debuggerSafe = false; 141 internal bool m_debuggerSafe = false;
142 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 142 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
143 143
144 protected IUrlModule m_UrlModule = null;
145
144 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) 146 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
145 { 147 {
146 m_ScriptEngine = ScriptEngine; 148 m_ScriptEngine = ScriptEngine;
@@ -148,6 +150,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
148 m_item = item; 150 m_item = item;
149 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false); 151 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
150 152
153 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>();
154
151 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false)) 155 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false))
152 m_OSFunctionsEnabled = true; 156 m_OSFunctionsEnabled = true;
153 157
@@ -782,10 +786,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
782 786
783 // We will launch the teleport on a new thread so that when the script threads are terminated 787 // We will launch the teleport on a new thread so that when the script threads are terminated
784 // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting. 788 // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting.
785 Util.FireAndForget( 789 Util.FireAndForget(o => World.RequestTeleportLocation(
786 o => World.RequestTeleportLocation(presence.ControllingClient, regionName, 790 presence.ControllingClient, regionName, position,
787 new Vector3((float)position.x, (float)position.y, (float)position.z), 791 lookat, (uint)TPFlags.ViaLocation));
788 new Vector3((float)lookat.x, (float)lookat.y, (float)lookat.z), (uint)TPFlags.ViaLocation));
789 792
790 ScriptSleep(5000); 793 ScriptSleep(5000);
791 794
@@ -828,10 +831,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
828 831
829 // We will launch the teleport on a new thread so that when the script threads are terminated 832 // We will launch the teleport on a new thread so that when the script threads are terminated
830 // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting. 833 // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting.
831 Util.FireAndForget( 834 Util.FireAndForget(o => World.RequestTeleportLocation(
832 o => World.RequestTeleportLocation(presence.ControllingClient, regionHandle, 835 presence.ControllingClient, regionHandle,
833 new Vector3((float)position.x, (float)position.y, (float)position.z), 836 position, lookat, (uint)TPFlags.ViaLocation));
834 new Vector3((float)lookat.x, (float)lookat.y, (float)lookat.z), (uint)TPFlags.ViaLocation));
835 837
836 ScriptSleep(5000); 838 ScriptSleep(5000);
837 839
@@ -1680,6 +1682,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1680 return; 1682 return;
1681 } 1683 }
1682 1684
1685 MessageObject(objUUID, message);
1686 }
1687
1688 private void MessageObject(UUID objUUID, string message)
1689 {
1683 object[] resobj = new object[] { new LSL_Types.LSLString(m_host.UUID.ToString()), new LSL_Types.LSLString(message) }; 1690 object[] resobj = new object[] { new LSL_Types.LSLString(m_host.UUID.ToString()), new LSL_Types.LSLString(message) };
1684 1691
1685 SceneObjectPart sceneOP = World.GetSceneObjectPart(objUUID); 1692 SceneObjectPart sceneOP = World.GetSceneObjectPart(objUUID);
@@ -2259,11 +2266,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2259 CheckThreatLevel(ThreatLevel.High, "osGetLinkPrimitiveParams"); 2266 CheckThreatLevel(ThreatLevel.High, "osGetLinkPrimitiveParams");
2260 m_host.AddScriptLPS(1); 2267 m_host.AddScriptLPS(1);
2261 InitLSL(); 2268 InitLSL();
2269 // One needs to cast m_LSL_Api because we're using functions not
2270 // on the ILSL_Api interface.
2271 LSL_Api LSL_Api = (LSL_Api)m_LSL_Api;
2262 LSL_List retVal = new LSL_List(); 2272 LSL_List retVal = new LSL_List();
2263 List<SceneObjectPart> parts = ((LSL_Api)m_LSL_Api).GetLinkParts(linknumber); 2273 LSL_List remaining = null;
2274 List<SceneObjectPart> parts = LSL_Api.GetLinkParts(linknumber);
2264 foreach (SceneObjectPart part in parts) 2275 foreach (SceneObjectPart part in parts)
2265 { 2276 {
2266 retVal += ((LSL_Api)m_LSL_Api).GetLinkPrimitiveParams(part, rules); 2277 remaining = LSL_Api.GetPrimParams(part, rules, ref retVal);
2278 }
2279
2280 while (remaining != null && remaining.Length > 2)
2281 {
2282 linknumber = remaining.GetLSLIntegerItem(0);
2283 rules = remaining.GetSublist(1, -1);
2284 parts = LSL_Api.GetLinkParts(linknumber);
2285
2286 foreach (SceneObjectPart part in parts)
2287 remaining = LSL_Api.GetPrimParams(part, rules, ref retVal);
2267 } 2288 }
2268 return retVal; 2289 return retVal;
2269 } 2290 }
@@ -2355,7 +2376,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2355 ownerID = m_host.OwnerID; 2376 ownerID = m_host.OwnerID;
2356 UUID x = module.CreateNPC(firstname, 2377 UUID x = module.CreateNPC(firstname,
2357 lastname, 2378 lastname,
2358 new Vector3((float) position.x, (float) position.y, (float) position.z), 2379 position,
2359 ownerID, 2380 ownerID,
2360 senseAsAgent, 2381 senseAsAgent,
2361 World, 2382 World,
@@ -2478,7 +2499,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2478 return new LSL_Vector(0, 0, 0); 2499 return new LSL_Vector(0, 0, 0);
2479 } 2500 }
2480 2501
2481 public void osNpcMoveTo(LSL_Key npc, LSL_Vector position) 2502 public void osNpcMoveTo(LSL_Key npc, LSL_Vector pos)
2482 { 2503 {
2483 CheckThreatLevel(ThreatLevel.High, "osNpcMoveTo"); 2504 CheckThreatLevel(ThreatLevel.High, "osNpcMoveTo");
2484 m_host.AddScriptLPS(1); 2505 m_host.AddScriptLPS(1);
@@ -2493,7 +2514,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2493 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2514 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2494 return; 2515 return;
2495 2516
2496 Vector3 pos = new Vector3((float) position.x, (float) position.y, (float) position.z);
2497 module.MoveToTarget(npcId, World, pos, false, true, false); 2517 module.MoveToTarget(npcId, World, pos, false, true, false);
2498 } 2518 }
2499 } 2519 }
@@ -2513,11 +2533,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2513 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2533 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2514 return; 2534 return;
2515 2535
2516 Vector3 pos = new Vector3((float)target.x, (float)target.y, (float)target.z);
2517 module.MoveToTarget( 2536 module.MoveToTarget(
2518 new UUID(npc.m_string), 2537 new UUID(npc.m_string),
2519 World, 2538 World,
2520 pos, 2539 target,
2521 (options & ScriptBaseClass.OS_NPC_NO_FLY) != 0, 2540 (options & ScriptBaseClass.OS_NPC_NO_FLY) != 0,
2522 (options & ScriptBaseClass.OS_NPC_LAND_AT_TARGET) != 0, 2541 (options & ScriptBaseClass.OS_NPC_LAND_AT_TARGET) != 0,
2523 (options & ScriptBaseClass.OS_NPC_RUNNING) != 0); 2542 (options & ScriptBaseClass.OS_NPC_RUNNING) != 0);
@@ -2569,7 +2588,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2569 ScenePresence sp = World.GetScenePresence(npcId); 2588 ScenePresence sp = World.GetScenePresence(npcId);
2570 2589
2571 if (sp != null) 2590 if (sp != null)
2572 sp.Rotation = LSL_Api.Rot2Quaternion(rotation); 2591 sp.Rotation = rotation;
2573 } 2592 }
2574 } 2593 }
2575 2594
@@ -2929,7 +2948,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2929 avatar.SpeedModifier = (float)SpeedModifier; 2948 avatar.SpeedModifier = (float)SpeedModifier;
2930 } 2949 }
2931 2950
2932 public void osKickAvatar(string FirstName,string SurName,string alert) 2951 public void osKickAvatar(string FirstName, string SurName, string alert)
2933 { 2952 {
2934 CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar"); 2953 CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar");
2935 m_host.AddScriptLPS(1); 2954 m_host.AddScriptLPS(1);
@@ -2943,10 +2962,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2943 sp.ControllingClient.Kick(alert); 2962 sp.ControllingClient.Kick(alert);
2944 2963
2945 // ...and close on our side 2964 // ...and close on our side
2946 sp.Scene.IncomingCloseAgent(sp.UUID); 2965 sp.Scene.IncomingCloseAgent(sp.UUID, false);
2947 } 2966 }
2948 }); 2967 });
2949 } 2968 }
2969
2970 public LSL_Float osGetHealth(string avatar)
2971 {
2972 CheckThreatLevel(ThreatLevel.None, "osGetHealth");
2973 m_host.AddScriptLPS(1);
2974
2975 LSL_Float health = new LSL_Float(-1);
2976 ScenePresence presence = World.GetScenePresence(new UUID(avatar));
2977 if (presence != null) health = presence.Health;
2978 return health;
2979 }
2950 2980
2951 public void osCauseDamage(string avatar, double damage) 2981 public void osCauseDamage(string avatar, double damage)
2952 { 2982 {
@@ -2959,7 +2989,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2959 ScenePresence presence = World.GetScenePresence(avatarId); 2989 ScenePresence presence = World.GetScenePresence(avatarId);
2960 if (presence != null) 2990 if (presence != null)
2961 { 2991 {
2962 LandData land = World.GetLandData((float)pos.X, (float)pos.Y); 2992 LandData land = World.GetLandData(pos);
2963 if ((land.Flags & (uint)ParcelFlags.AllowDamage) == (uint)ParcelFlags.AllowDamage) 2993 if ((land.Flags & (uint)ParcelFlags.AllowDamage) == (uint)ParcelFlags.AllowDamage)
2964 { 2994 {
2965 float health = presence.Health; 2995 float health = presence.Health;
@@ -3006,7 +3036,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3006 m_host.AddScriptLPS(1); 3036 m_host.AddScriptLPS(1);
3007 InitLSL(); 3037 InitLSL();
3008 3038
3009 return m_LSL_Api.GetLinkPrimitiveParamsEx(prim, rules); 3039 return m_LSL_Api.GetPrimitiveParamsEx(prim, rules);
3010 } 3040 }
3011 3041
3012 public void osSetPrimitiveParams(LSL_Key prim, LSL_List rules) 3042 public void osSetPrimitiveParams(LSL_Key prim, LSL_List rules)
@@ -3015,7 +3045,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3015 m_host.AddScriptLPS(1); 3045 m_host.AddScriptLPS(1);
3016 InitLSL(); 3046 InitLSL();
3017 3047
3018 m_LSL_Api.SetPrimitiveParamsEx(prim, rules); 3048 m_LSL_Api.SetPrimitiveParamsEx(prim, rules, "osSetPrimitiveParams");
3019 } 3049 }
3020 3050
3021 /// <summary> 3051 /// <summary>
@@ -3247,6 +3277,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3247 } 3277 }
3248 } 3278 }
3249 3279
3280 #region Attachment commands
3281
3250 public void osForceAttachToAvatar(int attachmentPoint) 3282 public void osForceAttachToAvatar(int attachmentPoint)
3251 { 3283 {
3252 CheckThreatLevel(ThreatLevel.High, "osForceAttachToAvatar"); 3284 CheckThreatLevel(ThreatLevel.High, "osForceAttachToAvatar");
@@ -3336,6 +3368,175 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3336 ((LSL_Api)m_LSL_Api).DetachFromAvatar(); 3368 ((LSL_Api)m_LSL_Api).DetachFromAvatar();
3337 } 3369 }
3338 3370
3371 public LSL_List osGetNumberOfAttachments(LSL_Key avatar, LSL_List attachmentPoints)
3372 {
3373 CheckThreatLevel(ThreatLevel.Moderate, "osGetNumberOfAttachments");
3374
3375 m_host.AddScriptLPS(1);
3376
3377 UUID targetUUID;
3378 ScenePresence target;
3379 LSL_List resp = new LSL_List();
3380
3381 if (attachmentPoints.Length >= 1 && UUID.TryParse(avatar.ToString(), out targetUUID) && World.TryGetScenePresence(targetUUID, out target))
3382 {
3383 foreach (object point in attachmentPoints.Data)
3384 {
3385 LSL_Integer ipoint = new LSL_Integer(
3386 (point is LSL_Integer || point is int || point is uint) ?
3387 (int)point :
3388 0
3389 );
3390 resp.Add(ipoint);
3391 if (ipoint == 0)
3392 {
3393 // indicates zero attachments
3394 resp.Add(new LSL_Integer(0));
3395 }
3396 else
3397 {
3398 // gets the number of attachments on the attachment point
3399 resp.Add(new LSL_Integer(target.GetAttachments((uint)ipoint).Count));
3400 }
3401 }
3402 }
3403
3404 return resp;
3405 }
3406
3407 public void osMessageAttachments(LSL_Key avatar, string message, LSL_List attachmentPoints, int options)
3408 {
3409 CheckThreatLevel(ThreatLevel.Moderate, "osMessageAttachments");
3410 m_host.AddScriptLPS(1);
3411
3412 UUID targetUUID;
3413 ScenePresence target;
3414
3415 if (attachmentPoints.Length >= 1 && UUID.TryParse(avatar.ToString(), out targetUUID) && World.TryGetScenePresence(targetUUID, out target))
3416 {
3417 List<int> aps = new List<int>();
3418 foreach (object point in attachmentPoints.Data)
3419 {
3420 int ipoint;
3421 if (int.TryParse(point.ToString(), out ipoint))
3422 {
3423 aps.Add(ipoint);
3424 }
3425 }
3426
3427 List<SceneObjectGroup> attachments = new List<SceneObjectGroup>();
3428
3429 bool msgAll = aps.Contains(ScriptBaseClass.OS_ATTACH_MSG_ALL);
3430 bool invertPoints = (options & ScriptBaseClass.OS_ATTACH_MSG_INVERT_POINTS) != 0;
3431
3432 if (msgAll && invertPoints)
3433 {
3434 return;
3435 }
3436 else if (msgAll || invertPoints)
3437 {
3438 attachments = target.GetAttachments();
3439 }
3440 else
3441 {
3442 foreach (int point in aps)
3443 {
3444 if (point > 0)
3445 {
3446 attachments.AddRange(target.GetAttachments((uint)point));
3447 }
3448 }
3449 }
3450
3451 // if we have no attachments at this point, exit now
3452 if (attachments.Count == 0)
3453 {
3454 return;
3455 }
3456
3457 List<SceneObjectGroup> ignoreThese = new List<SceneObjectGroup>();
3458
3459 if (invertPoints)
3460 {
3461 foreach (SceneObjectGroup attachment in attachments)
3462 {
3463 if (aps.Contains((int)attachment.AttachmentPoint))
3464 {
3465 ignoreThese.Add(attachment);
3466 }
3467 }
3468 }
3469
3470 foreach (SceneObjectGroup attachment in ignoreThese)
3471 {
3472 attachments.Remove(attachment);
3473 }
3474 ignoreThese.Clear();
3475
3476 // if inverting removed all attachments to check, exit now
3477 if (attachments.Count < 1)
3478 {
3479 return;
3480 }
3481
3482 if ((options & ScriptBaseClass.OS_ATTACH_MSG_OBJECT_CREATOR) != 0)
3483 {
3484 foreach (SceneObjectGroup attachment in attachments)
3485 {
3486 if (attachment.RootPart.CreatorID != m_host.CreatorID)
3487 {
3488 ignoreThese.Add(attachment);
3489 }
3490 }
3491
3492 foreach (SceneObjectGroup attachment in ignoreThese)
3493 {
3494 attachments.Remove(attachment);
3495 }
3496 ignoreThese.Clear();
3497
3498 // if filtering by same object creator removed all
3499 // attachments to check, exit now
3500 if (attachments.Count == 0)
3501 {
3502 return;
3503 }
3504 }
3505
3506 if ((options & ScriptBaseClass.OS_ATTACH_MSG_SCRIPT_CREATOR) != 0)
3507 {
3508 foreach (SceneObjectGroup attachment in attachments)
3509 {
3510 if (attachment.RootPart.CreatorID != m_item.CreatorID)
3511 {
3512 ignoreThese.Add(attachment);
3513 }
3514 }
3515
3516 foreach (SceneObjectGroup attachment in ignoreThese)
3517 {
3518 attachments.Remove(attachment);
3519 }
3520 ignoreThese.Clear();
3521
3522 // if filtering by object creator must match originating
3523 // script creator removed all attachments to check,
3524 // exit now
3525 if (attachments.Count == 0)
3526 {
3527 return;
3528 }
3529 }
3530
3531 foreach (SceneObjectGroup attachment in attachments)
3532 {
3533 MessageObject(attachment.RootPart.UUID, message);
3534 }
3535 }
3536 }
3537
3538 #endregion
3539
3339 /// <summary> 3540 /// <summary>
3340 /// Checks if thing is a UUID. 3541 /// Checks if thing is a UUID.
3341 /// </summary> 3542 /// </summary>
@@ -3385,5 +3586,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3385 3586
3386 return new LSL_Key(m_host.ParentGroup.FromPartID.ToString()); 3587 return new LSL_Key(m_host.ParentGroup.FromPartID.ToString());
3387 } 3588 }
3589
3590 /// <summary>
3591 /// Sets the response type for an HTTP request/response
3592 /// </summary>
3593 /// <returns></returns>
3594 public void osSetContentType(LSL_Key id, string type)
3595 {
3596 CheckThreatLevel(ThreatLevel.High,"osSetResponseType");
3597 if (m_UrlModule != null)
3598 m_UrlModule.HttpContentType(new UUID(id),type);
3599 }
3388 } 3600 }
3389} 3601}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 678f9d5..4dd795d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -352,7 +352,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
352 q = avatar.Rotation; 352 q = avatar.Rotation;
353 } 353 }
354 354
355 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 355 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
356 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); 356 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r);
357 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); 357 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir);
358 358
@@ -429,9 +429,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
429 try 429 try
430 { 430 {
431 Vector3 diff = toRegionPos - fromRegionPos; 431 Vector3 diff = toRegionPos - fromRegionPos;
432 LSL_Types.Vector3 obj_dir = new LSL_Types.Vector3(diff.X, diff.Y, diff.Z); 432 double dot = LSL_Types.Vector3.Dot(forward_dir, diff);
433 double dot = LSL_Types.Vector3.Dot(forward_dir, obj_dir); 433 double mag_obj = LSL_Types.Vector3.Mag(diff);
434 double mag_obj = LSL_Types.Vector3.Mag(obj_dir);
435 ang_obj = Math.Acos(dot / (mag_fwd * mag_obj)); 434 ang_obj = Math.Acos(dot / (mag_fwd * mag_obj));
436 } 435 }
437 catch 436 catch
@@ -483,7 +482,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
483 q = avatar.Rotation; 482 q = avatar.Rotation;
484 } 483 }
485 484
486 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 485 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
487 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); 486 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r);
488 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); 487 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir);
489 bool attached = (SensePoint.ParentGroup.AttachmentPoint != 0); 488 bool attached = (SensePoint.ParentGroup.AttachmentPoint != 0);
@@ -564,8 +563,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
564 double ang_obj = 0; 563 double ang_obj = 0;
565 try 564 try
566 { 565 {
567 Vector3 diff = toRegionPos - fromRegionPos; 566 LSL_Types.Vector3 obj_dir = new LSL_Types.Vector3(
568 LSL_Types.Vector3 obj_dir = new LSL_Types.Vector3(diff.X, diff.Y, diff.Z); 567 toRegionPos - fromRegionPos);
569 double dot = LSL_Types.Vector3.Dot(forward_dir, obj_dir); 568 double dot = LSL_Types.Vector3.Dot(forward_dir, obj_dir);
570 double mag_obj = LSL_Types.Vector3.Mag(obj_dir); 569 double mag_obj = LSL_Types.Vector3.Mag(obj_dir);
571 ang_obj = Math.Acos(dot / (mag_fwd * mag_obj)); 570 ang_obj = Math.Acos(dot / (mag_fwd * mag_obj));
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
index af35258..05c20f9 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -429,8 +429,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
429 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link); 429 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
430 void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density); 430 void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density);
431 431
432 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 432 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc);
433 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
434 void llSetKeyframedMotion(LSL_List frames, LSL_List options); 433 void llSetKeyframedMotion(LSL_List frames, LSL_List options);
434 LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
435 } 435 }
436} 436}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 8c34ed3..0ea363a 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -40,16 +40,75 @@ using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
40 40
41namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces 41namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
42{ 42{
43 /// <summary>
44 /// To permit region owners to enable the extended scripting functionality
45 /// of OSSL, without allowing malicious scripts to access potentially
46 /// troublesome functions, each OSSL function is assigned a threat level,
47 /// and access to the functions is granted or denied based on a default
48 /// threshold set in OpenSim.ini (which can be overridden for individual
49 /// functions on a case-by-case basis)
50 /// </summary>
43 public enum ThreatLevel 51 public enum ThreatLevel
44 { 52 {
53 // Not documented, presumably means permanently disabled ?
45 NoAccess = -1, 54 NoAccess = -1,
55
56 /// <summary>
57 /// Function is no threat at all. It doesn't constitute a threat to
58 /// either users or the system and has no known side effects.
59 /// </summary>
46 None = 0, 60 None = 0,
61
62 /// <summary>
63 /// Abuse of this command can cause a nuisance to the region operator,
64 /// such as log message spew.
65 /// </summary>
47 Nuisance = 1, 66 Nuisance = 1,
67
68 /// <summary>
69 /// Extreme levels of abuse of this function can cause impaired
70 /// functioning of the region, or very gullible users can be tricked
71 /// into experiencing harmless effects.
72 /// </summary>
48 VeryLow = 2, 73 VeryLow = 2,
74
75 /// <summary>
76 /// Intentional abuse can cause crashes or malfunction under certain
77 /// circumstances, which can be easily rectified; or certain users can
78 /// be tricked into certain situations in an avoidable manner.
79 /// </summary>
49 Low = 3, 80 Low = 3,
81
82 /// <summary>
83 /// Intentional abuse can cause denial of service and crashes with
84 /// potential of data or state loss; or trusting users can be tricked
85 /// into embarrassing or uncomfortable situations.
86 /// </summary>
50 Moderate = 4, 87 Moderate = 4,
88
89 /// <summary>
90 /// Casual abuse can cause impaired functionality or temporary denial
91 /// of service conditions. Intentional abuse can easily cause crashes
92 /// with potential data loss, or can be used to trick experienced and
93 /// cautious users into unwanted situations, or changes global data
94 /// permanently and without undo ability.
95 /// </summary>
51 High = 5, 96 High = 5,
97
98 /// <summary>
99 /// Even normal use may, depending on the number of instances, or
100 /// frequency of use, result in severe service impairment or crash
101 /// with loss of data, or can be used to cause unwanted or harmful
102 /// effects on users without giving the user a means to avoid it.
103 /// </summary>
52 VeryHigh = 6, 104 VeryHigh = 6,
105
106 /// <summary>
107 /// Even casual use is a danger to region stability, or function allows
108 /// console or OS command execution, or function allows taking money
109 /// without consent, or allows deletion or modification of user data,
110 /// or allows the compromise of sensitive data by design.
111 /// </summary>
53 Severe = 7 112 Severe = 7
54 }; 113 };
55 114
@@ -98,7 +157,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
98 void osAvatarPlayAnimation(string avatar, string animation); 157 void osAvatarPlayAnimation(string avatar, string animation);
99 void osAvatarStopAnimation(string avatar, string animation); 158 void osAvatarStopAnimation(string avatar, string animation);
100 159
101 // Attachment commands 160 #region Attachment commands
102 161
103 /// <summary> 162 /// <summary>
104 /// Attach the object containing this script to the avatar that owns it without asking for PERMISSION_ATTACH 163 /// Attach the object containing this script to the avatar that owns it without asking for PERMISSION_ATTACH
@@ -133,6 +192,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
133 /// <remarks>Nothing happens if the object is not attached.</remarks> 192 /// <remarks>Nothing happens if the object is not attached.</remarks>
134 void osForceDetachFromAvatar(); 193 void osForceDetachFromAvatar();
135 194
195 /// <summary>
196 /// Returns a strided list of the specified attachment points and the number of attachments on those points.
197 /// </summary>
198 /// <param name="avatar">avatar UUID</param>
199 /// <param name="attachmentPoints">list of ATTACH_* constants</param>
200 /// <returns></returns>
201 LSL_List osGetNumberOfAttachments(LSL_Key avatar, LSL_List attachmentPoints);
202
203 /// <summary>
204 /// Sends a specified message to the specified avatar's attachments on
205 /// the specified attachment points.
206 /// </summary>
207 /// <remarks>
208 /// Behaves as osMessageObject(), without the sending script needing to know the attachment keys in advance.
209 /// </remarks>
210 /// <param name="avatar">avatar UUID</param>
211 /// <param name="message">message string</param>
212 /// <param name="attachmentPoints">list of ATTACH_* constants, or -1 for all attachments. If -1 is specified and OS_ATTACH_MSG_INVERT_POINTS is present in flags, no action is taken.</param>
213 /// <param name="flags">flags further constraining the attachments to deliver the message to.</param>
214 void osMessageAttachments(LSL_Key avatar, string message, LSL_List attachmentPoints, int flags);
215
216 #endregion
217
136 //texture draw functions 218 //texture draw functions
137 string osMovePen(string drawList, int x, int y); 219 string osMovePen(string drawList, int x, int y);
138 string osDrawLine(string drawList, int startX, int startY, int endX, int endY); 220 string osDrawLine(string drawList, int startX, int startY, int endX, int endY);
@@ -258,6 +340,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
258 int osGetSimulatorMemory(); 340 int osGetSimulatorMemory();
259 void osKickAvatar(string FirstName,string SurName,string alert); 341 void osKickAvatar(string FirstName,string SurName,string alert);
260 void osSetSpeed(string UUID, LSL_Float SpeedModifier); 342 void osSetSpeed(string UUID, LSL_Float SpeedModifier);
343 LSL_Float osGetHealth(string avatar);
261 void osCauseHealing(string avatar, double healing); 344 void osCauseHealing(string avatar, double healing);
262 void osCauseDamage(string avatar, double damage); 345 void osCauseDamage(string avatar, double damage);
263 LSL_List osGetPrimitiveParams(LSL_Key prim, LSL_List rules); 346 LSL_List osGetPrimitiveParams(LSL_Key prim, LSL_List rules);
@@ -305,5 +388,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
305 /// </summary> 388 /// </summary>
306 /// <returns>Rezzing object key or NULL_KEY if rezzed by agent or otherwise unknown.</returns> 389 /// <returns>Rezzing object key or NULL_KEY if rezzed by agent or otherwise unknown.</returns>
307 LSL_Key osGetRezzingObject(); 390 LSL_Key osGetRezzingObject();
391
392 /// <summary>
393 /// Sets the response type for an HTTP request/response
394 /// </summary>
395 /// <returns></returns>
396 void osSetContentType(LSL_Key id, string type);
308 } 397 }
309} 398}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index f989cc6..c788407 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -237,6 +237,58 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
237 public const int ATTACH_HUD_BOTTOM = 37; 237 public const int ATTACH_HUD_BOTTOM = 37;
238 public const int ATTACH_HUD_BOTTOM_RIGHT = 38; 238 public const int ATTACH_HUD_BOTTOM_RIGHT = 38;
239 239
240 #region osMessageAttachments constants
241
242 /// <summary>
243 /// Instructs osMessageAttachements to send the message to attachments
244 /// on every point.
245 /// </summary>
246 /// <remarks>
247 /// One might expect this to be named OS_ATTACH_ALL, but then one might
248 /// also expect functions designed to attach or detach or get
249 /// attachments to work with it too. Attaching a no-copy item to
250 /// many attachments could be dangerous.
251 /// when combined with OS_ATTACH_MSG_INVERT_POINTS, will prevent the
252 /// message from being sent.
253 /// if combined with OS_ATTACH_MSG_OBJECT_CREATOR or
254 /// OS_ATTACH_MSG_SCRIPT_CREATOR, could result in no message being
255 /// sent- this is expected behaviour.
256 /// </remarks>
257 public const int OS_ATTACH_MSG_ALL = -65535;
258
259 /// <summary>
260 /// Instructs osMessageAttachements to invert how the attachment points
261 /// list should be treated (e.g. go from inclusive operation to
262 /// exclusive operation).
263 /// </summary>
264 /// <remarks>
265 /// This might be used if you want to deliver a message to one set of
266 /// attachments and a different message to everything else. With
267 /// this flag, you only need to build one explicit list for both calls.
268 /// </remarks>
269 public const int OS_ATTACH_MSG_INVERT_POINTS = 1;
270
271 /// <summary>
272 /// Instructs osMessageAttachments to only send the message to
273 /// attachments with a CreatorID that matches the host object CreatorID
274 /// </summary>
275 /// <remarks>
276 /// This would be used if distributed in an object vendor/updater server.
277 /// </remarks>
278 public const int OS_ATTACH_MSG_OBJECT_CREATOR = 2;
279
280 /// <summary>
281 /// Instructs osMessageAttachments to only send the message to
282 /// attachments with a CreatorID that matches the sending script CreatorID
283 /// </summary>
284 /// <remarks>
285 /// This might be used if the script is distributed independently of a
286 /// containing object.
287 /// </remarks>
288 public const int OS_ATTACH_MSG_SCRIPT_CREATOR = 4;
289
290 #endregion
291
240 public const int LAND_LEVEL = 0; 292 public const int LAND_LEVEL = 0;
241 public const int LAND_RAISE = 1; 293 public const int LAND_RAISE = 1;
242 public const int LAND_LOWER = 2; 294 public const int LAND_LOWER = 2;
@@ -329,6 +381,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
329 public const int PRIM_OMEGA = 32; 381 public const int PRIM_OMEGA = 32;
330 public const int PRIM_POS_LOCAL = 33; 382 public const int PRIM_POS_LOCAL = 33;
331 public const int PRIM_LINK_TARGET = 34; 383 public const int PRIM_LINK_TARGET = 34;
384 public const int PRIM_SLICE = 35;
332 public const int PRIM_TEXGEN_DEFAULT = 0; 385 public const int PRIM_TEXGEN_DEFAULT = 0;
333 public const int PRIM_TEXGEN_PLANAR = 1; 386 public const int PRIM_TEXGEN_PLANAR = 1;
334 387
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
index 94405d2..52ca3da 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
@@ -289,7 +289,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
289 m_OSSL_Functions.osAvatarStopAnimation(avatar, animation); 289 m_OSSL_Functions.osAvatarStopAnimation(avatar, animation);
290 } 290 }
291 291
292 // Avatar functions 292 #region Attachment commands
293 293
294 public void osForceAttachToAvatar(int attachmentPoint) 294 public void osForceAttachToAvatar(int attachmentPoint)
295 { 295 {
@@ -311,6 +311,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
311 m_OSSL_Functions.osForceDetachFromAvatar(); 311 m_OSSL_Functions.osForceDetachFromAvatar();
312 } 312 }
313 313
314 public LSL_List osGetNumberOfAttachments(LSL_Key avatar, LSL_List attachmentPoints)
315 {
316 return m_OSSL_Functions.osGetNumberOfAttachments(avatar, attachmentPoints);
317 }
318
319 public void osMessageAttachments(LSL_Key avatar, string message, LSL_List attachmentPoints, int flags)
320 {
321 m_OSSL_Functions.osMessageAttachments(avatar, message, attachmentPoints, flags);
322 }
323
324 #endregion
325
314 // Texture Draw functions 326 // Texture Draw functions
315 327
316 public string osMovePen(string drawList, int x, int y) 328 public string osMovePen(string drawList, int x, int y)
@@ -865,7 +877,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
865 { 877 {
866 m_OSSL_Functions.osSetSpeed(UUID, SpeedModifier); 878 m_OSSL_Functions.osSetSpeed(UUID, SpeedModifier);
867 } 879 }
868 880
881 public LSL_Float osGetHealth(string avatar)
882 {
883 return m_OSSL_Functions.osGetHealth(avatar);
884 }
885
869 public void osCauseDamage(string avatar, double damage) 886 public void osCauseDamage(string avatar, double damage)
870 { 887 {
871 m_OSSL_Functions.osCauseDamage(avatar, damage); 888 m_OSSL_Functions.osCauseDamage(avatar, damage);
@@ -950,5 +967,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
950 { 967 {
951 return m_OSSL_Functions.osGetRezzingObject(); 968 return m_OSSL_Functions.osGetRezzingObject();
952 } 969 }
970
971 public void osSetContentType(LSL_Key id, string type)
972 {
973 m_OSSL_Functions.osSetContentType(id,type);
974 }
953 } 975 }
954} 976}
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
index 17a0d69..03be2ab 100644
--- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs
@@ -546,6 +546,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
546 "OpenSim.Region.ScriptEngine.Shared.dll")); 546 "OpenSim.Region.ScriptEngine.Shared.dll"));
547 parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, 547 parameters.ReferencedAssemblies.Add(Path.Combine(rootPath,
548 "OpenSim.Region.ScriptEngine.Shared.Api.Runtime.dll")); 548 "OpenSim.Region.ScriptEngine.Shared.Api.Runtime.dll"));
549 parameters.ReferencedAssemblies.Add(Path.Combine(rootPath,
550 "OpenMetaverseTypes.dll"));
549 551
550 if (lang == enumCompileType.yp) 552 if (lang == enumCompileType.yp)
551 { 553 {
diff --git a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
index 9e5fb24..22804f5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
@@ -164,11 +164,11 @@ namespace OpenSim.Region.ScriptEngine.Shared
164 else 164 else
165 { 165 {
166 // Set the values from the touch data provided by the client 166 // Set the values from the touch data provided by the client
167 touchST = new LSL_Types.Vector3(value.STCoord.X, value.STCoord.Y, value.STCoord.Z); 167 touchST = new LSL_Types.Vector3(value.STCoord);
168 touchUV = new LSL_Types.Vector3(value.UVCoord.X, value.UVCoord.Y, value.UVCoord.Z); 168 touchUV = new LSL_Types.Vector3(value.UVCoord);
169 touchNormal = new LSL_Types.Vector3(value.Normal.X, value.Normal.Y, value.Normal.Z); 169 touchNormal = new LSL_Types.Vector3(value.Normal);
170 touchBinormal = new LSL_Types.Vector3(value.Binormal.X, value.Binormal.Y, value.Binormal.Z); 170 touchBinormal = new LSL_Types.Vector3(value.Binormal);
171 touchPos = new LSL_Types.Vector3(value.Position.X, value.Position.Y, value.Position.Z); 171 touchPos = new LSL_Types.Vector3(value.Position);
172 touchFace = value.FaceIndex; 172 touchFace = value.FaceIndex;
173 } 173 }
174 } 174 }
@@ -189,19 +189,13 @@ namespace OpenSim.Region.ScriptEngine.Shared
189 Country = account.UserCountry; 189 Country = account.UserCountry;
190 190
191 Owner = Key; 191 Owner = Key;
192 Position = new LSL_Types.Vector3( 192 Position = new LSL_Types.Vector3(presence.AbsolutePosition);
193 presence.AbsolutePosition.X,
194 presence.AbsolutePosition.Y,
195 presence.AbsolutePosition.Z);
196 Rotation = new LSL_Types.Quaternion( 193 Rotation = new LSL_Types.Quaternion(
197 presence.Rotation.X, 194 presence.Rotation.X,
198 presence.Rotation.Y, 195 presence.Rotation.Y,
199 presence.Rotation.Z, 196 presence.Rotation.Z,
200 presence.Rotation.W); 197 presence.Rotation.W);
201 Velocity = new LSL_Types.Vector3( 198 Velocity = new LSL_Types.Vector3(presence.Velocity);
202 presence.Velocity.X,
203 presence.Velocity.Y,
204 presence.Velocity.Z);
205 199
206 Type = 0x01; // Avatar 200 Type = 0x01; // Avatar
207 if (presence.PresenceType == PresenceType.Npc) 201 if (presence.PresenceType == PresenceType.Npc)
@@ -254,16 +248,12 @@ namespace OpenSim.Region.ScriptEngine.Shared
254 } 248 }
255 } 249 }
256 250
257 Position = new LSL_Types.Vector3(part.AbsolutePosition.X, 251 Position = new LSL_Types.Vector3(part.AbsolutePosition);
258 part.AbsolutePosition.Y,
259 part.AbsolutePosition.Z);
260 252
261 Quaternion wr = part.ParentGroup.GroupRotation; 253 Quaternion wr = part.ParentGroup.GroupRotation;
262 Rotation = new LSL_Types.Quaternion(wr.X, wr.Y, wr.Z, wr.W); 254 Rotation = new LSL_Types.Quaternion(wr.X, wr.Y, wr.Z, wr.W);
263 255
264 Velocity = new LSL_Types.Vector3(part.Velocity.X, 256 Velocity = new LSL_Types.Vector3(part.Velocity);
265 part.Velocity.Y,
266 part.Velocity.Z);
267 } 257 }
268 } 258 }
269 259
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index 8adf4c5..c9c4753 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -31,6 +31,11 @@ using System.Globalization;
31using System.Text.RegularExpressions; 31using System.Text.RegularExpressions;
32using OpenSim.Framework; 32using OpenSim.Framework;
33 33
34using OpenMetaverse;
35using OMV_Vector3 = OpenMetaverse.Vector3;
36using OMV_Vector3d = OpenMetaverse.Vector3d;
37using OMV_Quaternion = OpenMetaverse.Quaternion;
38
34namespace OpenSim.Region.ScriptEngine.Shared 39namespace OpenSim.Region.ScriptEngine.Shared
35{ 40{
36 [Serializable] 41 [Serializable]
@@ -54,6 +59,20 @@ namespace OpenSim.Region.ScriptEngine.Shared
54 z = (float)vector.z; 59 z = (float)vector.z;
55 } 60 }
56 61
62 public Vector3(OMV_Vector3 vector)
63 {
64 x = vector.X;
65 y = vector.Y;
66 z = vector.Z;
67 }
68
69 public Vector3(OMV_Vector3d vector)
70 {
71 x = vector.X;
72 y = vector.Y;
73 z = vector.Z;
74 }
75
57 public Vector3(double X, double Y, double Z) 76 public Vector3(double X, double Y, double Z)
58 { 77 {
59 x = X; 78 x = X;
@@ -109,6 +128,26 @@ namespace OpenSim.Region.ScriptEngine.Shared
109 return new list(new object[] { vec }); 128 return new list(new object[] { vec });
110 } 129 }
111 130
131 public static implicit operator OMV_Vector3(Vector3 vec)
132 {
133 return new OMV_Vector3((float)vec.x, (float)vec.y, (float)vec.z);
134 }
135
136 public static implicit operator Vector3(OMV_Vector3 vec)
137 {
138 return new Vector3(vec);
139 }
140
141 public static implicit operator OMV_Vector3d(Vector3 vec)
142 {
143 return new OMV_Vector3d(vec.x, vec.y, vec.z);
144 }
145
146 public static implicit operator Vector3(OMV_Vector3d vec)
147 {
148 return new Vector3(vec);
149 }
150
112 public static bool operator ==(Vector3 lhs, Vector3 rhs) 151 public static bool operator ==(Vector3 lhs, Vector3 rhs)
113 { 152 {
114 return (lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z); 153 return (lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z);
@@ -322,6 +361,14 @@ namespace OpenSim.Region.ScriptEngine.Shared
322 s = 1; 361 s = 1;
323 } 362 }
324 363
364 public Quaternion(OMV_Quaternion rot)
365 {
366 x = rot.X;
367 y = rot.Y;
368 z = rot.Z;
369 s = rot.W;
370 }
371
325 #endregion 372 #endregion
326 373
327 #region Overriders 374 #region Overriders
@@ -368,6 +415,21 @@ namespace OpenSim.Region.ScriptEngine.Shared
368 return new list(new object[] { r }); 415 return new list(new object[] { r });
369 } 416 }
370 417
418 public static implicit operator OMV_Quaternion(Quaternion rot)
419 {
420 // LSL quaternions can normalize to 0, normal Quaternions can't.
421 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
422 rot.z = 1; // ZERO_ROTATION = 0,0,0,1
423 OMV_Quaternion omvrot = new OMV_Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s);
424 omvrot.Normalize();
425 return omvrot;
426 }
427
428 public static implicit operator Quaternion(OMV_Quaternion rot)
429 {
430 return new Quaternion(rot);
431 }
432
371 public static bool operator ==(Quaternion lhs, Quaternion rhs) 433 public static bool operator ==(Quaternion lhs, Quaternion rhs)
372 { 434 {
373 // Return true if the fields match: 435 // Return true if the fields match:
@@ -562,12 +624,23 @@ namespace OpenSim.Region.ScriptEngine.Shared
562 else if (m_data[itemIndex] is LSL_Types.LSLString) 624 else if (m_data[itemIndex] is LSL_Types.LSLString)
563 return new LSLInteger(m_data[itemIndex].ToString()); 625 return new LSLInteger(m_data[itemIndex].ToString());
564 else 626 else
565 throw new InvalidCastException(); 627 throw new InvalidCastException(string.Format(
628 "{0} expected but {1} given",
629 typeof(LSL_Types.LSLInteger).Name,
630 m_data[itemIndex] != null ?
631 m_data[itemIndex].GetType().Name : "null"));
566 } 632 }
567 633
568 public LSL_Types.Vector3 GetVector3Item(int itemIndex) 634 public LSL_Types.Vector3 GetVector3Item(int itemIndex)
569 { 635 {
570 return (LSL_Types.Vector3)m_data[itemIndex]; 636 if(m_data[itemIndex] is LSL_Types.Vector3)
637 return (LSL_Types.Vector3)m_data[itemIndex];
638 else
639 throw new InvalidCastException(string.Format(
640 "{0} expected but {1} given",
641 typeof(LSL_Types.Vector3).Name,
642 m_data[itemIndex] != null ?
643 m_data[itemIndex].GetType().Name : "null"));
571 } 644 }
572 645
573 public LSL_Types.Quaternion GetQuaternionItem(int itemIndex) 646 public LSL_Types.Quaternion GetQuaternionItem(int itemIndex)
diff --git a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs
index 5c4174e..cee10df 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs
@@ -152,9 +152,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
152 det[0] = new DetectParams(); 152 det[0] = new DetectParams();
153 det[0].Key = remoteClient.AgentId; 153 det[0].Key = remoteClient.AgentId;
154 det[0].Populate(myScriptEngine.World); 154 det[0].Populate(myScriptEngine.World);
155 det[0].OffsetPos = new LSL_Types.Vector3(offsetPos.X, 155 det[0].OffsetPos = offsetPos;
156 offsetPos.Y,
157 offsetPos.Z);
158 156
159 if (originalID == 0) 157 if (originalID == 0)
160 { 158 {
@@ -298,9 +296,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
298 foreach (DetectedObject detobj in col.Colliders) 296 foreach (DetectedObject detobj in col.Colliders)
299 { 297 {
300 DetectParams d = new DetectParams(); 298 DetectParams d = new DetectParams();
301 d.Position = new LSL_Types.Vector3(detobj.posVector.X, 299 d.Position = detobj.posVector;
302 detobj.posVector.Y,
303 detobj.posVector.Z);
304 d.Populate(myScriptEngine.World); 300 d.Populate(myScriptEngine.World);
305 det.Add(d); 301 det.Add(d);
306 myScriptEngine.PostObjectEvent(localID, new EventParams( 302 myScriptEngine.PostObjectEvent(localID, new EventParams(
@@ -318,9 +314,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
318 foreach (DetectedObject detobj in col.Colliders) 314 foreach (DetectedObject detobj in col.Colliders)
319 { 315 {
320 DetectParams d = new DetectParams(); 316 DetectParams d = new DetectParams();
321 d.Position = new LSL_Types.Vector3(detobj.posVector.X, 317 d.Position = detobj.posVector;
322 detobj.posVector.Y,
323 detobj.posVector.Z);
324 d.Populate(myScriptEngine.World); 318 d.Populate(myScriptEngine.World);
325 det.Add(d); 319 det.Add(d);
326 myScriptEngine.PostObjectEvent(localID, new EventParams( 320 myScriptEngine.PostObjectEvent(localID, new EventParams(
@@ -337,9 +331,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
337 foreach (DetectedObject detobj in col.Colliders) 331 foreach (DetectedObject detobj in col.Colliders)
338 { 332 {
339 DetectParams d = new DetectParams(); 333 DetectParams d = new DetectParams();
340 d.Position = new LSL_Types.Vector3(detobj.posVector.X, 334 d.Position = detobj.posVector;
341 detobj.posVector.Y,
342 detobj.posVector.Z);
343 d.Populate(myScriptEngine.World); 335 d.Populate(myScriptEngine.World);
344 det.Add(d); 336 det.Add(d);
345 myScriptEngine.PostObjectEvent(localID, new EventParams( 337 myScriptEngine.PostObjectEvent(localID, new EventParams(
@@ -381,8 +373,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
381 myScriptEngine.PostObjectEvent(localID, new EventParams( 373 myScriptEngine.PostObjectEvent(localID, new EventParams(
382 "at_target", new object[] { 374 "at_target", new object[] {
383 new LSL_Types.LSLInteger(handle), 375 new LSL_Types.LSLInteger(handle),
384 new LSL_Types.Vector3(targetpos.X,targetpos.Y,targetpos.Z), 376 new LSL_Types.Vector3(targetpos),
385 new LSL_Types.Vector3(atpos.X,atpos.Y,atpos.Z) }, 377 new LSL_Types.Vector3(atpos) },
386 new DetectParams[0])); 378 new DetectParams[0]));
387 } 379 }
388 380
@@ -399,8 +391,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
399 myScriptEngine.PostObjectEvent(localID, new EventParams( 391 myScriptEngine.PostObjectEvent(localID, new EventParams(
400 "at_rot_target", new object[] { 392 "at_rot_target", new object[] {
401 new LSL_Types.LSLInteger(handle), 393 new LSL_Types.LSLInteger(handle),
402 new LSL_Types.Quaternion(targetrot.X,targetrot.Y,targetrot.Z,targetrot.W), 394 new LSL_Types.Quaternion(targetrot),
403 new LSL_Types.Quaternion(atrot.X,atrot.Y,atrot.Z,atrot.W) }, 395 new LSL_Types.Quaternion(atrot) },
404 new DetectParams[0])); 396 new DetectParams[0]));
405 } 397 }
406 398
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index f6cb7df..9f05666 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -656,7 +656,19 @@ namespace OpenSim.Region.ScriptEngine.XEngine
656 if (m_Assemblies.ContainsKey(instance.AssetID)) 656 if (m_Assemblies.ContainsKey(instance.AssetID))
657 { 657 {
658 string assembly = m_Assemblies[instance.AssetID]; 658 string assembly = m_Assemblies[instance.AssetID];
659 instance.SaveState(assembly); 659
660 try
661 {
662 instance.SaveState(assembly);
663 }
664 catch (Exception e)
665 {
666 m_log.Error(
667 string.Format(
668 "[XEngine]: Failed final state save for script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ",
669 instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, World.Name)
670 , e);
671 }
660 } 672 }
661 673
662 // Clear the event queue and abort the instance thread 674 // Clear the event queue and abort the instance thread
@@ -778,7 +790,18 @@ namespace OpenSim.Region.ScriptEngine.XEngine
778 assembly = m_Assemblies[i.AssetID]; 790 assembly = m_Assemblies[i.AssetID];
779 791
780 792
781 i.SaveState(assembly); 793 try
794 {
795 i.SaveState(assembly);
796 }
797 catch (Exception e)
798 {
799 m_log.Error(
800 string.Format(
801 "[XEngine]: Failed to save state of script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ",
802 i.PrimName, i.ScriptName, i.ItemID, i.ObjectID, World.Name)
803 , e);
804 }
782 } 805 }
783 806
784 instances.Clear(); 807 instances.Clear();
@@ -971,6 +994,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
971 // This delay exists to stop mono problems where script compilation and startup would stop the sim 994 // This delay exists to stop mono problems where script compilation and startup would stop the sim
972 // working properly for the session. 995 // working properly for the session.
973 System.Threading.Thread.Sleep(m_StartDelay); 996 System.Threading.Thread.Sleep(m_StartDelay);
997
998 m_log.InfoFormat("[XEngine]: Performing initial script startup on {0}", m_Scene.Name);
974 } 999 }
975 1000
976 object[] o; 1001 object[] o;
@@ -986,13 +1011,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine
986 if (m_InitialStartup) 1011 if (m_InitialStartup)
987 if (scriptsStarted % 50 == 0) 1012 if (scriptsStarted % 50 == 0)
988 m_log.InfoFormat( 1013 m_log.InfoFormat(
989 "[XEngine]: Started {0} scripts in {1}", scriptsStarted, m_Scene.RegionInfo.RegionName); 1014 "[XEngine]: Started {0} scripts in {1}", scriptsStarted, m_Scene.Name);
990 } 1015 }
991 } 1016 }
992 1017
993 if (m_InitialStartup) 1018 if (m_InitialStartup)
994 m_log.InfoFormat( 1019 m_log.InfoFormat(
995 "[XEngine]: Completed starting {0} scripts on {1}", scriptsStarted, m_Scene.RegionInfo.RegionName); 1020 "[XEngine]: Completed starting {0} scripts on {1}", scriptsStarted, m_Scene.Name);
996 1021
997 // NOTE: Despite having a lockless queue, this lock is required 1022 // NOTE: Despite having a lockless queue, this lock is required
998 // to make sure there is never no compile thread while there 1023 // to make sure there is never no compile thread while there
@@ -1053,10 +1078,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1053 return false; 1078 return false;
1054 } 1079 }
1055 1080
1056 UUID assetID = item.AssetID; 1081 m_log.DebugFormat(
1082 "[XEngine] Loading script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}",
1083 part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID,
1084 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1057 1085
1058 //m_log.DebugFormat("[XEngine] Compiling script {0} ({1} on object {2})", 1086 UUID assetID = item.AssetID;
1059 // item.Name, itemID.ToString(), part.ParentGroup.RootPart.Name);
1060 1087
1061 ScenePresence presence = m_Scene.GetScenePresence(item.OwnerID); 1088 ScenePresence presence = m_Scene.GetScenePresence(item.OwnerID);
1062 1089
@@ -1235,10 +1262,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1235 item.Name, startParam, postOnRez, 1262 item.Name, startParam, postOnRez,
1236 stateSource, m_MaxScriptQueue); 1263 stateSource, m_MaxScriptQueue);
1237 1264
1238 m_log.DebugFormat( 1265// m_log.DebugFormat(
1239 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", 1266// "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
1240 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, 1267// part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
1241 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); 1268// part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1242 1269
1243 if (presence != null) 1270 if (presence != null)
1244 { 1271 {
@@ -1554,9 +1581,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1554 else if (p[i] is string) 1581 else if (p[i] is string)
1555 lsl_p[i] = new LSL_Types.LSLString((string)p[i]); 1582 lsl_p[i] = new LSL_Types.LSLString((string)p[i]);
1556 else if (p[i] is Vector3) 1583 else if (p[i] is Vector3)
1557 lsl_p[i] = new LSL_Types.Vector3(((Vector3)p[i]).X, ((Vector3)p[i]).Y, ((Vector3)p[i]).Z); 1584 lsl_p[i] = new LSL_Types.Vector3((Vector3)p[i]);
1558 else if (p[i] is Quaternion) 1585 else if (p[i] is Quaternion)
1559 lsl_p[i] = new LSL_Types.Quaternion(((Quaternion)p[i]).X, ((Quaternion)p[i]).Y, ((Quaternion)p[i]).Z, ((Quaternion)p[i]).W); 1586 lsl_p[i] = new LSL_Types.Quaternion((Quaternion)p[i]);
1560 else if (p[i] is float) 1587 else if (p[i] is float)
1561 lsl_p[i] = new LSL_Types.LSLFloat((float)p[i]); 1588 lsl_p[i] = new LSL_Types.LSLFloat((float)p[i]);
1562 else 1589 else
@@ -1580,9 +1607,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1580 else if (p[i] is string) 1607 else if (p[i] is string)
1581 lsl_p[i] = new LSL_Types.LSLString((string)p[i]); 1608 lsl_p[i] = new LSL_Types.LSLString((string)p[i]);
1582 else if (p[i] is Vector3) 1609 else if (p[i] is Vector3)
1583 lsl_p[i] = new LSL_Types.Vector3(((Vector3)p[i]).X, ((Vector3)p[i]).Y, ((Vector3)p[i]).Z); 1610 lsl_p[i] = new LSL_Types.Vector3((Vector3)p[i]);
1584 else if (p[i] is Quaternion) 1611 else if (p[i] is Quaternion)
1585 lsl_p[i] = new LSL_Types.Quaternion(((Quaternion)p[i]).X, ((Quaternion)p[i]).Y, ((Quaternion)p[i]).Z, ((Quaternion)p[i]).W); 1612 lsl_p[i] = new LSL_Types.Quaternion((Quaternion)p[i]);
1586 else if (p[i] is float) 1613 else if (p[i] is float)
1587 lsl_p[i] = new LSL_Types.LSLFloat((float)p[i]); 1614 lsl_p[i] = new LSL_Types.LSLFloat((float)p[i]);
1588 else 1615 else
diff --git a/OpenSim/Server/Base/ServicesServerBase.cs b/OpenSim/Server/Base/ServicesServerBase.cs
index b137c05..0cff6ed 100644
--- a/OpenSim/Server/Base/ServicesServerBase.cs
+++ b/OpenSim/Server/Base/ServicesServerBase.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic;
29using System.IO; 30using System.IO;
30using System.Reflection; 31using System.Reflection;
31using System.Threading; 32using System.Threading;
@@ -71,10 +72,17 @@ namespace OpenSim.Server.Base
71 // 72 //
72 private string m_pidFile = String.Empty; 73 private string m_pidFile = String.Empty;
73 74
75 /// <summary>
76 /// Time at which this server was started
77 /// </summary>
78 protected DateTime m_startuptime;
79
74 // Handle all the automagical stuff 80 // Handle all the automagical stuff
75 // 81 //
76 public ServicesServerBase(string prompt, string[] args) 82 public ServicesServerBase(string prompt, string[] args)
77 { 83 {
84 m_startuptime = DateTime.Now;
85
78 // Save raw arguments 86 // Save raw arguments
79 // 87 //
80 m_Arguments = args; 88 m_Arguments = args;
@@ -250,6 +258,10 @@ namespace OpenSim.Server.Base
250 "command-script <script>", 258 "command-script <script>",
251 "Run a command script from file", HandleScript); 259 "Run a command script from file", HandleScript);
252 260
261 MainConsole.Instance.Commands.AddCommand("General", false, "show uptime",
262 "show uptime",
263 "Show server uptime", HandleShow);
264
253 265
254 // Allow derived classes to perform initialization that 266 // Allow derived classes to perform initialization that
255 // needs to be done after the console has opened 267 // needs to be done after the console has opened
@@ -345,5 +357,34 @@ namespace OpenSim.Server.Base
345 { 357 {
346 } 358 }
347 } 359 }
360
361 public virtual void HandleShow(string module, string[] cmd)
362 {
363 List<string> args = new List<string>(cmd);
364
365 args.RemoveAt(0);
366
367 string[] showParams = args.ToArray();
368
369 switch (showParams[0])
370 {
371 case "uptime":
372 MainConsole.Instance.Output(GetUptimeReport());
373 break;
374 }
375 }
376
377 /// <summary>
378 /// Return a report about the uptime of this server
379 /// </summary>
380 /// <returns></returns>
381 protected string GetUptimeReport()
382 {
383 StringBuilder sb = new StringBuilder(String.Format("Time now is {0}\n", DateTime.Now));
384 sb.Append(String.Format("Server has been running since {0}, {1}\n", m_startuptime.DayOfWeek, m_startuptime));
385 sb.Append(String.Format("That is an elapsed time of {0}\n", DateTime.Now - m_startuptime));
386
387 return sb.ToString();
388 }
348 } 389 }
349} 390}
diff --git a/OpenSim/Server/Handlers/Avatar/AvatarServerPostHandler.cs b/OpenSim/Server/Handlers/Avatar/AvatarServerPostHandler.cs
index 393584e..8cd747e 100644
--- a/OpenSim/Server/Handlers/Avatar/AvatarServerPostHandler.cs
+++ b/OpenSim/Server/Handlers/Avatar/AvatarServerPostHandler.cs
@@ -137,6 +137,8 @@ namespace OpenSim.Server.Handlers.Avatar
137 if (!UUID.TryParse(request["UserID"].ToString(), out user)) 137 if (!UUID.TryParse(request["UserID"].ToString(), out user))
138 return FailureResult(); 138 return FailureResult();
139 139
140 RemoveRequestParamsNotForStorage(request);
141
140 AvatarData avatar = new AvatarData(request); 142 AvatarData avatar = new AvatarData(request);
141 if (m_AvatarService.SetAvatar(user, avatar)) 143 if (m_AvatarService.SetAvatar(user, avatar))
142 return SuccessResult(); 144 return SuccessResult();
@@ -153,11 +155,25 @@ namespace OpenSim.Server.Handlers.Avatar
153 if (!UUID.TryParse(request["UserID"].ToString(), out user)) 155 if (!UUID.TryParse(request["UserID"].ToString(), out user))
154 return FailureResult(); 156 return FailureResult();
155 157
158 RemoveRequestParamsNotForStorage(request);
159
156 if (m_AvatarService.ResetAvatar(user)) 160 if (m_AvatarService.ResetAvatar(user))
157 return SuccessResult(); 161 return SuccessResult();
158 162
159 return FailureResult(); 163 return FailureResult();
160 } 164 }
165
166 /// <summary>
167 /// Remove parameters that were used to invoke the method and should not in themselves be persisted.
168 /// </summary>
169 /// <param name='request'></param>
170 private void RemoveRequestParamsNotForStorage(Dictionary<string, object> request)
171 {
172 request.Remove("VERSIONMAX");
173 request.Remove("VERSIONMIN");
174 request.Remove("METHOD");
175 request.Remove("UserID");
176 }
161 177
162 byte[] SetItems(Dictionary<string, object> request) 178 byte[] SetItems(Dictionary<string, object> request)
163 { 179 {
@@ -173,6 +189,8 @@ namespace OpenSim.Server.Handlers.Avatar
173 if (!(request["Names"] is List<string> || request["Values"] is List<string>)) 189 if (!(request["Names"] is List<string> || request["Values"] is List<string>))
174 return FailureResult(); 190 return FailureResult();
175 191
192 RemoveRequestParamsNotForStorage(request);
193
176 List<string> _names = (List<string>)request["Names"]; 194 List<string> _names = (List<string>)request["Names"];
177 names = _names.ToArray(); 195 names = _names.ToArray();
178 List<string> _values = (List<string>)request["Values"]; 196 List<string> _values = (List<string>)request["Values"];
diff --git a/OpenSim/Services/AssetService/AssetServiceBase.cs b/OpenSim/Services/AssetService/AssetServiceBase.cs
index 177c565..58ab052 100644
--- a/OpenSim/Services/AssetService/AssetServiceBase.cs
+++ b/OpenSim/Services/AssetService/AssetServiceBase.cs
@@ -84,7 +84,7 @@ namespace OpenSim.Services.AssetService
84 84
85 m_Database = LoadPlugin<IAssetDataPlugin>(dllName); 85 m_Database = LoadPlugin<IAssetDataPlugin>(dllName);
86 if (m_Database == null) 86 if (m_Database == null)
87 throw new Exception("Could not find a storage interface in the given module"); 87 throw new Exception(string.Format("Could not find a storage interface in the module {0}", dllName));
88 88
89 m_Database.Initialise(connString); 89 m_Database.Initialise(connString);
90 90
@@ -96,7 +96,7 @@ namespace OpenSim.Services.AssetService
96 m_AssetLoader = LoadPlugin<IAssetLoader>(loaderName); 96 m_AssetLoader = LoadPlugin<IAssetLoader>(loaderName);
97 97
98 if (m_AssetLoader == null) 98 if (m_AssetLoader == null)
99 throw new Exception("Asset loader could not be loaded"); 99 throw new Exception(string.Format("Asset loader could not be loaded from {0}", loaderName));
100 } 100 }
101 } 101 }
102 } 102 }
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs
index 0e4d794..67a10b0 100644
--- a/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs
@@ -112,7 +112,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
112// m_log.Warn("Registering region " + regionInfo.RegionName + " (" + regionInfo.RegionID + ") that we are not tracking"); 112// m_log.Warn("Registering region " + regionInfo.RegionName + " (" + regionInfo.RegionID + ") that we are not tracking");
113 113
114 Vector3d minPosition = new Vector3d(regionInfo.RegionLocX, regionInfo.RegionLocY, 0.0); 114 Vector3d minPosition = new Vector3d(regionInfo.RegionLocX, regionInfo.RegionLocY, 0.0);
115 Vector3d maxPosition = minPosition + new Vector3d(Constants.RegionSize, Constants.RegionSize, 4096.0); 115 Vector3d maxPosition = minPosition + new Vector3d(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight);
116 116
117 OSDMap extraData = new OSDMap 117 OSDMap extraData = new OSDMap
118 { 118 {
@@ -297,7 +297,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
297 List<GridRegion> foundRegions = new List<GridRegion>(); 297 List<GridRegion> foundRegions = new List<GridRegion>();
298 298
299 Vector3d minPosition = new Vector3d(xmin, ymin, 0.0); 299 Vector3d minPosition = new Vector3d(xmin, ymin, 0.0);
300 Vector3d maxPosition = new Vector3d(xmax, ymax, 4096.0); 300 Vector3d maxPosition = new Vector3d(xmax, ymax, Constants.RegionHeight);
301 301
302 NameValueCollection requestArgs = new NameValueCollection 302 NameValueCollection requestArgs = new NameValueCollection
303 { 303 {
diff --git a/OpenSim/Services/GridService/GridService.cs b/OpenSim/Services/GridService/GridService.cs
index aab403a..5bdea06 100644
--- a/OpenSim/Services/GridService/GridService.cs
+++ b/OpenSim/Services/GridService/GridService.cs
@@ -137,9 +137,14 @@ namespace OpenSim.Services.GridService
137 if (regionInfos.RegionID == UUID.Zero) 137 if (regionInfos.RegionID == UUID.Zero)
138 return "Invalid RegionID - cannot be zero UUID"; 138 return "Invalid RegionID - cannot be zero UUID";
139 139
140 // This needs better sanity testing. What if regionInfo is registering in
141 // overlapping coords?
142 RegionData region = m_Database.Get(regionInfos.RegionLocX, regionInfos.RegionLocY, scopeID); 140 RegionData region = m_Database.Get(regionInfos.RegionLocX, regionInfos.RegionLocY, scopeID);
141 if ((region != null) && (region.RegionID != regionInfos.RegionID))
142 {
143 m_log.WarnFormat("[GRID SERVICE]: Region {0} tried to register in coordinates {1}, {2} which are already in use in scope {3}.",
144 regionInfos.RegionID, regionInfos.RegionLocX, regionInfos.RegionLocY, scopeID);
145 return "Region overlaps another region";
146 }
147
143 if (region != null) 148 if (region != null)
144 { 149 {
145 // There is a preexisting record 150 // There is a preexisting record
@@ -176,19 +181,36 @@ namespace OpenSim.Services.GridService
176 } 181 }
177 } 182 }
178 183
179 if ((region != null) && (region.RegionID != regionInfos.RegionID)) 184 // If we get here, the destination is clear. Now for the real check.
185
186 if (!m_AllowDuplicateNames)
180 { 187 {
181 m_log.WarnFormat("[GRID SERVICE]: Region {0} tried to register in coordinates {1}, {2} which are already in use in scope {3}.", 188 List<RegionData> dupe = m_Database.Get(regionInfos.RegionName, scopeID);
182 regionInfos.RegionID, regionInfos.RegionLocX, regionInfos.RegionLocY, scopeID); 189 if (dupe != null && dupe.Count > 0)
183 return "Region overlaps another region"; 190 {
191 foreach (RegionData d in dupe)
192 {
193 if (d.RegionID != regionInfos.RegionID)
194 {
195 m_log.WarnFormat("[GRID SERVICE]: Region {0} tried to register duplicate name with ID {1}.",
196 regionInfos.RegionName, regionInfos.RegionID);
197 return "Duplicate region name";
198 }
199 }
200 }
184 } 201 }
185 202
203 // If there is an old record for us, delete it if it is elsewhere.
204 region = m_Database.Get(regionInfos.RegionID, scopeID);
186 if ((region != null) && (region.RegionID == regionInfos.RegionID) && 205 if ((region != null) && (region.RegionID == regionInfos.RegionID) &&
187 ((region.posX != regionInfos.RegionLocX) || (region.posY != regionInfos.RegionLocY))) 206 ((region.posX != regionInfos.RegionLocX) || (region.posY != regionInfos.RegionLocY)))
188 { 207 {
189 if ((Convert.ToInt32(region.Data["flags"]) & (int)OpenSim.Data.RegionFlags.NoMove) != 0) 208 if ((Convert.ToInt32(region.Data["flags"]) & (int)OpenSim.Data.RegionFlags.NoMove) != 0)
190 return "Can't move this region"; 209 return "Can't move this region";
191 210
211 if ((Convert.ToInt32(region.Data["flags"]) & (int)OpenSim.Data.RegionFlags.LockedOut) != 0)
212 return "Region locked out";
213
192 // Region reregistering in other coordinates. Delete the old entry 214 // Region reregistering in other coordinates. Delete the old entry
193 m_log.DebugFormat("[GRID SERVICE]: Region {0} ({1}) was previously registered at {2}-{3}. Deleting old entry.", 215 m_log.DebugFormat("[GRID SERVICE]: Region {0} ({1}) was previously registered at {2}-{3}. Deleting old entry.",
194 regionInfos.RegionName, regionInfos.RegionID, regionInfos.RegionLocX, regionInfos.RegionLocY); 216 regionInfos.RegionName, regionInfos.RegionID, regionInfos.RegionLocX, regionInfos.RegionLocY);
@@ -203,23 +225,6 @@ namespace OpenSim.Services.GridService
203 } 225 }
204 } 226 }
205 227
206 if (!m_AllowDuplicateNames)
207 {
208 List<RegionData> dupe = m_Database.Get(regionInfos.RegionName, scopeID);
209 if (dupe != null && dupe.Count > 0)
210 {
211 foreach (RegionData d in dupe)
212 {
213 if (d.RegionID != regionInfos.RegionID)
214 {
215 m_log.WarnFormat("[GRID SERVICE]: Region {0} tried to register duplicate name with ID {1}.",
216 regionInfos.RegionName, regionInfos.RegionID);
217 return "Duplicate region name";
218 }
219 }
220 }
221 }
222
223 // Everything is ok, let's register 228 // Everything is ok, let's register
224 RegionData rdata = RegionInfo2RegionData(regionInfos); 229 RegionData rdata = RegionInfo2RegionData(regionInfos);
225 rdata.ScopeID = scopeID; 230 rdata.ScopeID = scopeID;
@@ -227,8 +232,6 @@ namespace OpenSim.Services.GridService
227 if (region != null) 232 if (region != null)
228 { 233 {
229 int oldFlags = Convert.ToInt32(region.Data["flags"]); 234 int oldFlags = Convert.ToInt32(region.Data["flags"]);
230 if ((oldFlags & (int)OpenSim.Data.RegionFlags.LockedOut) != 0)
231 return "Region locked out";
232 235
233 oldFlags &= ~(int)OpenSim.Data.RegionFlags.Reservation; 236 oldFlags &= ~(int)OpenSim.Data.RegionFlags.Reservation;
234 237
diff --git a/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs b/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs
index 6e4b68c..556a0da 100644
--- a/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs
+++ b/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs
@@ -56,10 +56,12 @@ namespace OpenSim.Services.HypergridService
56 56
57 private string m_HomeURL; 57 private string m_HomeURL;
58 private IUserAccountService m_UserAccountService; 58 private IUserAccountService m_UserAccountService;
59 private IAvatarService m_AvatarService;
59 60
60// private UserAccountCache m_Cache; 61// private UserAccountCache m_Cache;
61 62
62 private ExpiringCache<UUID, List<XInventoryFolder>> m_SuitcaseTrees = new ExpiringCache<UUID, List<XInventoryFolder>>(); 63 private ExpiringCache<UUID, List<XInventoryFolder>> m_SuitcaseTrees = new ExpiringCache<UUID, List<XInventoryFolder>>();
64 private ExpiringCache<UUID, AvatarAppearance> m_Appearances = new ExpiringCache<UUID, AvatarAppearance>();
63 65
64 public HGSuitcaseInventoryService(IConfigSource config, string configName) 66 public HGSuitcaseInventoryService(IConfigSource config, string configName)
65 : base(config, configName) 67 : base(config, configName)
@@ -77,7 +79,6 @@ namespace OpenSim.Services.HypergridService
77 IConfig invConfig = config.Configs[m_ConfigName]; 79 IConfig invConfig = config.Configs[m_ConfigName];
78 if (invConfig != null) 80 if (invConfig != null)
79 { 81 {
80 // realm = authConfig.GetString("Realm", realm);
81 string userAccountsDll = invConfig.GetString("UserAccountsService", string.Empty); 82 string userAccountsDll = invConfig.GetString("UserAccountsService", string.Empty);
82 if (userAccountsDll == string.Empty) 83 if (userAccountsDll == string.Empty)
83 throw new Exception("Please specify UserAccountsService in HGInventoryService configuration"); 84 throw new Exception("Please specify UserAccountsService in HGInventoryService configuration");
@@ -87,8 +88,14 @@ namespace OpenSim.Services.HypergridService
87 if (m_UserAccountService == null) 88 if (m_UserAccountService == null)
88 throw new Exception(String.Format("Unable to create UserAccountService from {0}", userAccountsDll)); 89 throw new Exception(String.Format("Unable to create UserAccountService from {0}", userAccountsDll));
89 90
90 // legacy configuration [obsolete] 91 string avatarDll = invConfig.GetString("AvatarService", string.Empty);
91 m_HomeURL = invConfig.GetString("ProfileServerURI", string.Empty); 92 if (avatarDll == string.Empty)
93 throw new Exception("Please specify AvatarService in HGInventoryService configuration");
94
95 m_AvatarService = ServerUtils.LoadPlugin<IAvatarService>(avatarDll, args);
96 if (m_AvatarService == null)
97 throw new Exception(String.Format("Unable to create m_AvatarService from {0}", avatarDll));
98
92 // Preferred 99 // Preferred
93 m_HomeURL = invConfig.GetString("HomeURI", m_HomeURL); 100 m_HomeURL = invConfig.GetString("HomeURI", m_HomeURL);
94 101
@@ -394,7 +401,7 @@ namespace OpenSim.Services.HypergridService
394 return null; 401 return null;
395 } 402 }
396 403
397 if (!IsWithinSuitcaseTree(it.Owner, it.Folder)) 404 if (!IsWithinSuitcaseTree(it.Owner, it.Folder) && !IsPartOfAppearance(it.Owner, it.ID))
398 { 405 {
399 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: Item {0} (folder {1}) is not within Suitcase", 406 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: Item {0} (folder {1}) is not within Suitcase",
400 it.Name, it.Folder); 407 it.Name, it.Folder);
@@ -549,6 +556,52 @@ namespace OpenSim.Services.HypergridService
549 else return true; 556 else return true;
550 } 557 }
551 #endregion 558 #endregion
559
560 #region Avatar Appearance
561
562 private AvatarAppearance GetAppearance(UUID principalID)
563 {
564 AvatarAppearance a = null;
565 if (m_Appearances.TryGetValue(principalID, out a))
566 return a;
567
568 a = m_AvatarService.GetAppearance(principalID);
569 m_Appearances.AddOrUpdate(principalID, a, 5 * 60); // 5minutes
570 return a;
571 }
572
573 private bool IsPartOfAppearance(UUID principalID, UUID itemID)
574 {
575 AvatarAppearance a = GetAppearance(principalID);
576
577 if (a == null)
578 return false;
579
580 // Check wearables (body parts and clothes)
581 for (int i = 0; i < a.Wearables.Length; i++)
582 {
583 for (int j = 0; j < a.Wearables[i].Count; j++)
584 {
585 if (a.Wearables[i][j].ItemID == itemID)
586 {
587 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: item {0} is a wearable", itemID);
588 return true;
589 }
590 }
591 }
592
593 // Check attachments
594 if (a.GetAttachmentForItem(itemID) != null)
595 {
596 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: item {0} is an attachment", itemID);
597 return true;
598 }
599
600 return false;
601 }
602
603 #endregion
604
552 } 605 }
553 606
554} 607}
diff --git a/OpenSim/Services/InventoryService/XInventoryService.cs b/OpenSim/Services/InventoryService/XInventoryService.cs
index 7518b86..309dab4 100644
--- a/OpenSim/Services/InventoryService/XInventoryService.cs
+++ b/OpenSim/Services/InventoryService/XInventoryService.cs
@@ -94,6 +94,7 @@ namespace OpenSim.Services.InventoryService
94 94
95 m_Database = LoadPlugin<IXInventoryData>(dllName, 95 m_Database = LoadPlugin<IXInventoryData>(dllName,
96 new Object[] {connString, String.Empty}); 96 new Object[] {connString, String.Empty});
97
97 if (m_Database == null) 98 if (m_Database == null)
98 throw new Exception("Could not find a storage interface in the given module"); 99 throw new Exception("Could not find a storage interface in the given module");
99 } 100 }
@@ -229,10 +230,28 @@ namespace OpenSim.Services.InventoryService
229 public virtual InventoryFolderBase GetFolderForType(UUID principalID, AssetType type) 230 public virtual InventoryFolderBase GetFolderForType(UUID principalID, AssetType type)
230 { 231 {
231// m_log.DebugFormat("[XINVENTORY SERVICE]: Getting folder type {0} for user {1}", type, principalID); 232// m_log.DebugFormat("[XINVENTORY SERVICE]: Getting folder type {0} for user {1}", type, principalID);
233
234 InventoryFolderBase rootFolder = GetRootFolder(principalID);
235
236 if (rootFolder == null)
237 {
238 m_log.WarnFormat(
239 "[XINVENTORY]: Found no root folder for {0} in GetFolderForType() when looking for {1}",
240 principalID, type);
241
242 return null;
243 }
244
245 return GetSystemFolderForType(rootFolder, type);
246 }
247
248 private InventoryFolderBase GetSystemFolderForType(InventoryFolderBase rootFolder, AssetType type)
249 {
250// m_log.DebugFormat("[XINVENTORY SERVICE]: Getting folder type {0} for user {1}", type, principalID);
232 251
233 XInventoryFolder[] folders = m_Database.GetFolders( 252 XInventoryFolder[] folders = m_Database.GetFolders(
234 new string[] { "agentID", "type"}, 253 new string[] { "agentID", "parentFolderID", "type"},
235 new string[] { principalID.ToString(), ((int)type).ToString() }); 254 new string[] { rootFolder.Owner.ToString(), rootFolder.ID.ToString(), ((int)type).ToString() });
236 255
237 if (folders.Length == 0) 256 if (folders.Length == 0)
238 { 257 {
@@ -308,22 +327,38 @@ namespace OpenSim.Services.InventoryService
308 if (check != null) 327 if (check != null)
309 return false; 328 return false;
310 329
311 if (folder.Type == (short)AssetType.Folder 330 if (folder.Type != (short)AssetType.Folder && folder.Type != (short)AssetType.Unknown)
312 || folder.Type == (short)AssetType.Unknown
313 || folder.Type == (short)AssetType.OutfitFolder
314 || GetFolderForType(folder.Owner, (AssetType)(folder.Type)) == null)
315 { 331 {
316 XInventoryFolder xFolder = ConvertFromOpenSim(folder); 332 InventoryFolderBase rootFolder = GetRootFolder(folder.Owner);
317 return m_Database.StoreFolder(xFolder); 333
318 } 334 if (rootFolder == null)
319 else 335 {
320 { 336 m_log.WarnFormat(
321 m_log.WarnFormat( 337 "[XINVENTORY]: Found no root folder for {0} in AddFolder() when looking for {1}",
322 "[XINVENTORY]: Folder of type {0} already exists when tried to add {1} to {2} for {3}", 338 folder.Owner, folder.Type);
323 folder.Type, folder.Name, folder.ParentID, folder.Owner); 339
340 return false;
341 }
342
343 // Check we're not trying to add this as a system folder.
344 if (folder.ParentID == rootFolder.ID)
345 {
346 InventoryFolderBase existingSystemFolder
347 = GetSystemFolderForType(rootFolder, (AssetType)folder.Type);
348
349 if (existingSystemFolder != null)
350 {
351 m_log.WarnFormat(
352 "[XINVENTORY]: System folder of type {0} already exists when tried to add {1} to {2} for {3}",
353 folder.Type, folder.Name, folder.ParentID, folder.Owner);
354
355 return false;
356 }
357 }
324 } 358 }
325 359
326 return false; 360 XInventoryFolder xFolder = ConvertFromOpenSim(folder);
361 return m_Database.StoreFolder(xFolder);
327 } 362 }
328 363
329 public virtual bool UpdateFolder(InventoryFolderBase folder) 364 public virtual bool UpdateFolder(InventoryFolderBase folder)
diff --git a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs
index 7598cc3..fc49169 100644
--- a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs
+++ b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs
@@ -245,7 +245,7 @@ namespace OpenSim.Tests.Common
245 config.AddConfig("Modules"); 245 config.AddConfig("Modules");
246 config.AddConfig("InventoryService"); 246 config.AddConfig("InventoryService");
247 config.Configs["Modules"].Set("InventoryServices", "LocalInventoryServicesConnector"); 247 config.Configs["Modules"].Set("InventoryServices", "LocalInventoryServicesConnector");
248 config.Configs["InventoryService"].Set("LocalServiceModule", "OpenSim.Services.InventoryService.dll:InventoryService"); 248 config.Configs["InventoryService"].Set("LocalServiceModule", "OpenSim.Services.InventoryService.dll:XInventoryService");
249 config.Configs["InventoryService"].Set("StorageProvider", "OpenSim.Tests.Common.dll"); 249 config.Configs["InventoryService"].Set("StorageProvider", "OpenSim.Tests.Common.dll");
250 250
251 LocalInventoryServicesConnector inventoryService = new LocalInventoryServicesConnector(); 251 LocalInventoryServicesConnector inventoryService = new LocalInventoryServicesConnector();
diff --git a/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs b/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs
index b3a7c9e..87d9410 100644
--- a/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs
+++ b/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs
@@ -199,7 +199,9 @@ namespace OpenSim.Tests.Common
199 string[] components = path.Split(new string[] { PATH_DELIMITER }, 2, StringSplitOptions.None); 199 string[] components = path.Split(new string[] { PATH_DELIMITER }, 2, StringSplitOptions.None);
200 200
201 InventoryFolderBase newFolder 201 InventoryFolderBase newFolder
202 = new InventoryFolderBase(UUID.Random(), components[0], parentFolder.Owner, parentFolder.ID); 202 = new InventoryFolderBase(
203 UUID.Random(), components[0], parentFolder.Owner, (short)AssetType.Unknown, parentFolder.ID, 0);
204
203 inventoryService.AddFolder(newFolder); 205 inventoryService.AddFolder(newFolder);
204 206
205 if (components.Length > 1) 207 if (components.Length > 1)
diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs
index 6add130..4e3bc67 100644
--- a/OpenSim/Tests/Common/Mock/TestClient.cs
+++ b/OpenSim/Tests/Common/Mock/TestClient.cs
@@ -935,12 +935,12 @@ namespace OpenSim.Tests.Common.Mock
935 Close(); 935 Close();
936 } 936 }
937 937
938 public void Close(bool c) 938 public void Close()
939 { 939 {
940 Close(); 940 Close(true, false);
941 } 941 }
942 942
943 public void Close() 943 public void Close(bool sendStop, bool force)
944 { 944 {
945 // Fire the callback for this connection closing 945 // Fire the callback for this connection closing
946 // This is necesary to get the presence detector to notice that a client has logged out. 946 // This is necesary to get the presence detector to notice that a client has logged out.
diff --git a/OpenSim/Tests/Common/Mock/TestXInventoryDataPlugin.cs b/OpenSim/Tests/Common/Mock/TestXInventoryDataPlugin.cs
new file mode 100644
index 0000000..bca5979
--- /dev/null
+++ b/OpenSim/Tests/Common/Mock/TestXInventoryDataPlugin.cs
@@ -0,0 +1,131 @@
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.Linq;
31using System.Reflection;
32using log4net;
33using OpenMetaverse;
34using OpenSim.Framework;
35using OpenSim.Data;
36
37namespace OpenSim.Tests.Common.Mock
38{
39 public class TestXInventoryDataPlugin : IXInventoryData
40 {
41 private Dictionary<UUID, XInventoryFolder> m_allFolders = new Dictionary<UUID, XInventoryFolder>();
42 private Dictionary<UUID, XInventoryItem> m_allItems = new Dictionary<UUID, XInventoryItem>();
43
44 public TestXInventoryDataPlugin(string conn, string realm) {}
45
46 public XInventoryItem[] GetItems(string[] fields, string[] vals)
47 {
48 List<XInventoryItem> origItems = Get<XInventoryItem>(fields, vals, m_allItems.Values.ToList());
49
50 return origItems.Select(i => i.Clone()).ToArray();
51 }
52
53 public XInventoryFolder[] GetFolders(string[] fields, string[] vals)
54 {
55 List<XInventoryFolder> origFolders
56 = Get<XInventoryFolder>(fields, vals, m_allFolders.Values.ToList());
57
58 return origFolders.Select(f => f.Clone()).ToArray();
59 }
60
61 private List<T> Get<T>(string[] fields, string[] vals, List<T> inputEntities)
62 {
63 List<T> entities = inputEntities;
64
65 for (int i = 0; i < fields.Length; i++)
66 {
67 entities
68 = entities.Where(
69 e =>
70 {
71 FieldInfo fi = typeof(T).GetField(fields[i]);
72 if (fi == null)
73 throw new NotImplementedException(string.Format("No field {0} for val {1}", fields[i], vals[i]));
74
75 return fi.GetValue(e).ToString() == vals[i];
76 }
77 ).ToList();
78 }
79
80 return entities;
81 }
82
83 public bool StoreFolder(XInventoryFolder folder)
84 {
85 m_allFolders[folder.folderID] = folder.Clone();
86
87// Console.WriteLine("Added folder {0} {1}", folder.folderName, folder.folderID);
88
89 return true;
90 }
91
92 public bool StoreItem(XInventoryItem item)
93 {
94 m_allItems[item.inventoryID] = item.Clone();
95
96// Console.WriteLine("Added item {0} {1}, creator {2}, owner {3}", item.inventoryName, item.inventoryID, item.creatorID, item.avatarID);
97
98 return true;
99 }
100
101 public bool DeleteFolders(string field, string val)
102 {
103 return DeleteFolders(new string[] { field }, new string[] { val });
104 }
105
106 public bool DeleteFolders(string[] fields, string[] vals)
107 {
108 XInventoryFolder[] foldersToDelete = GetFolders(fields, vals);
109 Array.ForEach(foldersToDelete, f => m_allFolders.Remove(f.folderID));
110
111 return true;
112 }
113
114 public bool DeleteItems(string field, string val)
115 {
116 return DeleteItems(new string[] { field }, new string[] { val });
117 }
118
119 public bool DeleteItems(string[] fields, string[] vals)
120 {
121 XInventoryItem[] itemsToDelete = GetItems(fields, vals);
122 Array.ForEach(itemsToDelete, i => m_allItems.Remove(i.inventoryID));
123
124 return true;
125 }
126
127 public bool MoveItem(string id, string newParent) { throw new NotImplementedException(); }
128 public XInventoryItem[] GetActiveGestures(UUID principalID) { throw new NotImplementedException(); }
129 public int GetAssetPermissions(UUID principalID, UUID assetID) { throw new NotImplementedException(); }
130 }
131} \ No newline at end of file
diff --git a/OpenSim/Tests/Common/TestHelpers.cs b/OpenSim/Tests/Common/TestHelpers.cs
index 30121fe..57da802 100644
--- a/OpenSim/Tests/Common/TestHelpers.cs
+++ b/OpenSim/Tests/Common/TestHelpers.cs
@@ -95,6 +95,7 @@ namespace OpenSim.Tests.Common
95 public static void EnableLogging() 95 public static void EnableLogging()
96 { 96 {
97 log4net.Config.XmlConfigurator.Configure(EnableLoggingConfigStream); 97 log4net.Config.XmlConfigurator.Configure(EnableLoggingConfigStream);
98 EnableLoggingConfigStream.Position = 0;
98 } 99 }
99 100
100 /// <summary> 101 /// <summary>
diff --git a/OpenSim/Tests/Torture/NPCTortureTests.cs b/OpenSim/Tests/Performance/NPCPerformanceTests.cs
index 731df68..627765b 100644
--- a/OpenSim/Tests/Torture/NPCTortureTests.cs
+++ b/OpenSim/Tests/Performance/NPCPerformanceTests.cs
@@ -47,10 +47,10 @@ using OpenSim.Services.AvatarService;
47using OpenSim.Tests.Common; 47using OpenSim.Tests.Common;
48using OpenSim.Tests.Common.Mock; 48using OpenSim.Tests.Common.Mock;
49 49
50namespace OpenSim.Tests.Torture 50namespace OpenSim.Tests.Performance
51{ 51{
52 /// <summary> 52 /// <summary>
53 /// NPC torture tests 53 /// NPC performance tests
54 /// </summary> 54 /// </summary>
55 /// <remarks> 55 /// <remarks>
56 /// Don't rely on the numbers given by these tests - they will vary a lot depending on what is already cached, 56 /// Don't rely on the numbers given by these tests - they will vary a lot depending on what is already cached,
@@ -58,7 +58,7 @@ namespace OpenSim.Tests.Torture
58 /// earlier tests. 58 /// earlier tests.
59 /// </remarks> 59 /// </remarks>
60 [TestFixture] 60 [TestFixture]
61 public class NPCTortureTests 61 public class NPCPerformanceTests
62 { 62 {
63 private TestScene scene; 63 private TestScene scene;
64 private AvatarFactoryModule afm; 64 private AvatarFactoryModule afm;
diff --git a/OpenSim/Tests/Torture/ObjectTortureTests.cs b/OpenSim/Tests/Performance/ObjectPerformanceTests.cs
index 195d47b..2264d86 100644
--- a/OpenSim/Tests/Torture/ObjectTortureTests.cs
+++ b/OpenSim/Tests/Performance/ObjectPerformanceTests.cs
@@ -36,10 +36,10 @@ using OpenSim.Region.Framework.Scenes;
36using OpenSim.Tests.Common; 36using OpenSim.Tests.Common;
37using OpenSim.Tests.Common.Mock; 37using OpenSim.Tests.Common.Mock;
38 38
39namespace OpenSim.Tests.Torture 39namespace OpenSim.Tests.Performance
40{ 40{
41 /// <summary> 41 /// <summary>
42 /// Object torture tests 42 /// Object performance tests
43 /// </summary> 43 /// </summary>
44 /// <remarks> 44 /// <remarks>
45 /// Don't rely on the numbers given by these tests - they will vary a lot depending on what is already cached, 45 /// Don't rely on the numbers given by these tests - they will vary a lot depending on what is already cached,
@@ -47,7 +47,7 @@ namespace OpenSim.Tests.Torture
47 /// earlier tests. 47 /// earlier tests.
48 /// </remarks> 48 /// </remarks>
49 [TestFixture] 49 [TestFixture]
50 public class ObjectTortureTests 50 public class ObjectPerformanceTests
51 { 51 {
52 [TearDown] 52 [TearDown]
53 public void TearDown() 53 public void TearDown()
diff --git a/OpenSim/Tests/Torture/ScriptTortureTests.cs b/OpenSim/Tests/Performance/ScriptPerformanceTests.cs
index 24f278f..d708abd 100644
--- a/OpenSim/Tests/Torture/ScriptTortureTests.cs
+++ b/OpenSim/Tests/Performance/ScriptPerformanceTests.cs
@@ -42,10 +42,10 @@ using OpenSim.Region.ScriptEngine.XEngine;
42using OpenSim.Tests.Common; 42using OpenSim.Tests.Common;
43using OpenSim.Tests.Common.Mock; 43using OpenSim.Tests.Common.Mock;
44 44
45namespace OpenSim.Tests.Torture 45namespace OpenSim.Tests.Performance
46{ 46{
47 /// <summary> 47 /// <summary>
48 /// Script torture tests 48 /// Script performance tests
49 /// </summary> 49 /// </summary>
50 /// <remarks> 50 /// <remarks>
51 /// Don't rely on the numbers given by these tests - they will vary a lot depending on what is already cached, 51 /// Don't rely on the numbers given by these tests - they will vary a lot depending on what is already cached,
@@ -53,7 +53,7 @@ namespace OpenSim.Tests.Torture
53 /// earlier tests. 53 /// earlier tests.
54 /// </remarks> 54 /// </remarks>
55 [TestFixture] 55 [TestFixture]
56 public class ScriptTortureTests 56 public class ScriptPerformanceTests
57 { 57 {
58 private TestScene m_scene; 58 private TestScene m_scene;
59 private XEngine m_xEngine; 59 private XEngine m_xEngine;
diff --git a/OpenSim/Tests/Stress/VectorRenderModuleStressTests.cs b/OpenSim/Tests/Stress/VectorRenderModuleStressTests.cs
new file mode 100644
index 0000000..1f220c0
--- /dev/null
+++ b/OpenSim/Tests/Stress/VectorRenderModuleStressTests.cs
@@ -0,0 +1,132 @@
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.Linq;
32using System.Reflection;
33using System.Threading;
34using log4net.Config;
35using NUnit.Framework;
36using OpenMetaverse;
37using OpenMetaverse.Assets;
38using OpenSim.Framework;
39using OpenSim.Region.CoreModules.Scripting.DynamicTexture;
40using OpenSim.Region.CoreModules.Scripting.VectorRender;
41using OpenSim.Region.Framework.Scenes;
42using OpenSim.Region.Framework.Scenes.Serialization;
43using OpenSim.Tests.Common;
44using OpenSim.Tests.Common.Mock;
45
46namespace OpenSim.Tests.Stress
47{
48 [TestFixture]
49 public class VectorRenderModuleStressTests : OpenSimTestCase
50 {
51 public Scene Scene { get; private set; }
52 public DynamicTextureModule Dtm { get; private set; }
53 public VectorRenderModule Vrm { get; private set; }
54
55 private void SetupScene(bool reuseTextures)
56 {
57 Scene = new SceneHelpers().SetupScene();
58
59 Dtm = new DynamicTextureModule();
60 Dtm.ReuseTextures = reuseTextures;
61
62 Vrm = new VectorRenderModule();
63
64 SceneHelpers.SetupSceneModules(Scene, Dtm, Vrm);
65 }
66
67 [Test]
68 public void TestConcurrentRepeatedDraw()
69 {
70 int threads = 4;
71 TestHelpers.InMethod();
72
73 SetupScene(false);
74
75 List<Drawer> drawers = new List<Drawer>();
76
77 for (int i = 0; i < threads; i++)
78 {
79 Drawer d = new Drawer(this, i);
80 drawers.Add(d);
81 Console.WriteLine("Starting drawer {0}", i);
82 Util.FireAndForget(o => d.Draw());
83 }
84
85 Thread.Sleep(10 * 60 * 1000);
86
87 drawers.ForEach(d => d.Ready = false);
88 drawers.ForEach(d => Console.WriteLine("Drawer {0} drew {1} textures", d.Number, d.Pass + 1));
89 }
90
91 class Drawer
92 {
93 public int Number { get; private set; }
94 public int Pass { get; private set; }
95 public bool Ready { get; set; }
96
97 private VectorRenderModuleStressTests m_tests;
98
99 public Drawer(VectorRenderModuleStressTests tests, int number)
100 {
101 m_tests = tests;
102 Number = number;
103 Ready = true;
104 }
105
106 public void Draw()
107 {
108 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_tests.Scene);
109
110 while (Ready)
111 {
112 UUID originalTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
113
114 // Ensure unique text
115 string text = string.Format("{0:D2}{1}", Number, Pass);
116
117 m_tests.Dtm.AddDynamicTextureData(
118 m_tests.Scene.RegionInfo.RegionID,
119 so.UUID,
120 m_tests.Vrm.GetContentType(),
121 string.Format("PenColour BLACK; MoveTo 40,220; FontSize 32; Text {0};", text),
122 "",
123 0);
124
125 Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
126
127 Pass++;
128 }
129 }
130 }
131 }
132} \ No newline at end of file
diff --git a/README.txt b/README.md
index a5dec24..552cdef 100644
--- a/README.txt
+++ b/README.md
@@ -1,8 +1,6 @@
1Welcome to OpenSim! 1Welcome to OpenSim!
2 2
3================== 3# Overview
4==== OVERVIEW ====
5==================
6 4
7OpenSim is a BSD Licensed Open Source project to develop a functioning 5OpenSim is a BSD Licensed Open Source project to develop a functioning
8virtual worlds server platform capable of supporting multiple clients 6virtual worlds server platform capable of supporting multiple clients
@@ -12,16 +10,12 @@ C#, and can run under Mono or the Microsoft .NET runtimes.
12This is considered an alpha release. Some stuff works, a lot doesn't. 10This is considered an alpha release. Some stuff works, a lot doesn't.
13If it breaks, you get to keep *both* pieces. 11If it breaks, you get to keep *both* pieces.
14 12
15========================= 13# Compiling OpenSim
16=== Compiling OpenSim ===
17=========================
18 14
19Please see BUILDING.txt if you downloaded a source distribution and 15Please see BUILDING.md if you downloaded a source distribution and
20need to build OpenSim before running it. 16need to build OpenSim before running it.
21 17
22================================== 18# Running OpenSim on Windows
23=== Running OpenSim on Windows ===
24==================================
25 19
26We recommend that you run OpenSim from a command prompt on Windows in order 20We recommend that you run OpenSim from a command prompt on Windows in order
27to capture any errors. 21to capture any errors.
@@ -33,9 +27,7 @@ To run OpenSim from a command prompt
33 27
34Now see the "Configuring OpenSim" section 28Now see the "Configuring OpenSim" section
35 29
36================================ 30# Running OpenSim on Linux
37=== Running OpenSim on Linux ===
38================================
39 31
40You will need Mono >= 2.4.3 to run OpenSim. On some Linux distributions you 32You will need Mono >= 2.4.3 to run OpenSim. On some Linux distributions you
41may need to install additional packages. See http://opensimulator.org/wiki/Dependencies 33may need to install additional packages. See http://opensimulator.org/wiki/Dependencies
@@ -48,14 +40,12 @@ To run OpenSim, from the unpacked distribution type:
48 40
49Now see the "Configuring OpenSim" section 41Now see the "Configuring OpenSim" section
50 42
51=========================== 43# Configuring OpenSim
52=== Configuring OpenSim ===
53===========================
54 44
55When OpenSim starts for the first time, you will be prompted with a 45When OpenSim starts for the first time, you will be prompted with a
56series of questions that look something like: 46series of questions that look something like:
57 47
58[09-17 03:54:40] DEFAULT REGION CONFIG: Simulator Name [OpenSim Test]: 48 [09-17 03:54:40] DEFAULT REGION CONFIG: Simulator Name [OpenSim Test]:
59 49
60For all the options except simulator name, you can safely hit enter to accept 50For all the options except simulator name, you can safely hit enter to accept
61the default if you want to connect using a client on the same machine or over 51the default if you want to connect using a client on the same machine or over
@@ -72,7 +62,7 @@ in-world. You can also use these details to perform your first login.
72 62
73Once you are presented with a prompt that looks like: 63Once you are presented with a prompt that looks like:
74 64
75 Region (My region name) # 65 Region (My region name) #
76 66
77You have successfully started OpenSim. 67You have successfully started OpenSim.
78 68
@@ -83,9 +73,7 @@ Helpful resources:
83 * http://opensimulator.org/wiki/Configuration 73 * http://opensimulator.org/wiki/Configuration
84 * http://opensimulator.org/wiki/Configuring_Regions 74 * http://opensimulator.org/wiki/Configuring_Regions
85 75
86================================== 76# Connecting to your OpenSim
87=== Connecting to your OpenSim ===
88==================================
89 77
90By default your sim will be available for login on port 9000. You can login by 78By default your sim will be available for login on port 9000. You can login by
91adding -loginuri http://127.0.0.1:9000 to the command that starts Second Life 79adding -loginuri http://127.0.0.1:9000 to the command that starts Second Life
@@ -96,15 +84,11 @@ http://192.168.1.2:9000)
96To login, use the avatar details that you gave for your estate ownership or the 84To login, use the avatar details that you gave for your estate ownership or the
97one you set up using the "create user" command. 85one you set up using the "create user" command.
98 86
99=================== 87# Bug reports
100=== Bug reports ===
101===================
102 88
103In the very likely event of bugs biting you (err, your OpenSim) we 89In the very likely event of bugs biting you (err, your OpenSim) we
104encourage you to see whether the problem has already been reported on 90encourage you to see whether the problem has already been reported on
105the OpenSim mantis system. You can find the OpenSim mantis system at 91the [OpenSim mantis system](http://opensimulator.org/mantis/main_page.php).
106
107 http://opensimulator.org/mantis/main_page.php
108 92
109If your bug has already been reported, you might want to add to the 93If your bug has already been reported, you might want to add to the
110bug description and supply additional information. 94bug description and supply additional information.
@@ -119,9 +103,7 @@ mantis"). Useful information to include:
119 103
120 mono --debug OpenSim.exe 104 mono --debug OpenSim.exe
121 105
122=================================== 106# More Information on OpenSim
123=== More Information on OpenSim ===
124===================================
125 107
126More extensive information on building, running, and configuring 108More extensive information on building, running, and configuring
127OpenSim, as well as how to report bugs, and participate in the OpenSim 109OpenSim, as well as how to report bugs, and participate in the OpenSim
diff --git a/ThirdPartyLicenses/Newtonsoft-JsonDotNet.txt b/ThirdPartyLicenses/Newtonsoft-JsonDotNet.txt
deleted file mode 100644
index 457daca..0000000
--- a/ThirdPartyLicenses/Newtonsoft-JsonDotNet.txt
+++ /dev/null
@@ -1,23 +0,0 @@
1Json.NET
2License: The MIT License
3Copyright (c) 2007 James Newton-King
4
5
6Permission is hereby granted, free of charge, to any person obtaining
7a copy of this software and associated documentation files (the
8"Software"), to deal in the Software without restriction, including
9without limitation the rights to use, copy, modify, merge, publish,
10distribute, sublicense, and/or sell copies of the Software, and to
11permit persons to whom the Software is furnished to do so, subject to
12the following conditions:
13
14The above copyright notice and this permission notice shall be
15included in all copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file
diff --git a/bin/Newtonsoft.Json.Net20.dll b/bin/Newtonsoft.Json.Net20.dll
deleted file mode 100755
index 177d9b5..0000000
--- a/bin/Newtonsoft.Json.Net20.dll
+++ /dev/null
Binary files differ
diff --git a/bin/Newtonsoft.Json.XML b/bin/Newtonsoft.Json.XML
deleted file mode 100644
index 1a1e56c..0000000
--- a/bin/Newtonsoft.Json.XML
+++ /dev/null
@@ -1,5827 +0,0 @@
1<?xml version="1.0"?>
2<doc>
3 <assembly>
4 <name>Newtonsoft.Json.Net20</name>
5 </assembly>
6 <members>
7 <member name="T:Newtonsoft.Json.Bson.BsonReader">
8 <summary>
9 Represents a reader that provides fast, non-cached, forward-only access to serialized Json data.
10 </summary>
11 </member>
12 <member name="T:Newtonsoft.Json.JsonReader">
13 <summary>
14 Represents a reader that provides fast, non-cached, forward-only access to serialized Json data.
15 </summary>
16 </member>
17 <member name="M:Newtonsoft.Json.JsonReader.#ctor">
18 <summary>
19 Initializes a new instance of the <see cref="T:Newtonsoft.Json.JsonReader"/> class with the specified <see cref="T:System.IO.TextReader"/>.
20 </summary>
21 </member>
22 <member name="M:Newtonsoft.Json.JsonReader.Read">
23 <summary>
24 Reads the next JSON token from the stream.
25 </summary>
26 <returns>true if the next token was read successfully; false if there are no more tokens to read.</returns>
27 </member>
28 <member name="M:Newtonsoft.Json.JsonReader.ReadAsBytes">
29 <summary>
30 Reads the next JSON token from the stream as a <see cref="T:Byte[]"/>.
31 </summary>
32 <returns>A <see cref="T:Byte[]"/> or a null reference if the next JSON token is null.</returns>
33 </member>
34 <member name="M:Newtonsoft.Json.JsonReader.Skip">
35 <summary>
36 Skips the children of the current token.
37 </summary>
38 </member>
39 <member name="M:Newtonsoft.Json.JsonReader.SetToken(Newtonsoft.Json.JsonToken)">
40 <summary>
41 Sets the current token.
42 </summary>
43 <param name="newToken">The new token.</param>
44 </member>
45 <member name="M:Newtonsoft.Json.JsonReader.SetToken(Newtonsoft.Json.JsonToken,System.Object)">
46 <summary>
47 Sets the current token and value.
48 </summary>
49 <param name="newToken">The new token.</param>
50 <param name="value">The value.</param>
51 </member>
52 <member name="M:Newtonsoft.Json.JsonReader.SetStateBasedOnCurrent">
53 <summary>
54 Sets the state based on current token type.
55 </summary>
56 </member>
57 <member name="M:Newtonsoft.Json.JsonReader.System#IDisposable#Dispose">
58 <summary>
59 Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
60 </summary>
61 </member>
62 <member name="M:Newtonsoft.Json.JsonReader.Dispose(System.Boolean)">
63 <summary>
64 Releases unmanaged and - optionally - managed resources
65 </summary>
66 <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
67 </member>
68 <member name="M:Newtonsoft.Json.JsonReader.Close">
69 <summary>
70 Changes the <see cref="T:Newtonsoft.Json.JsonReader.State"/> to Closed.
71 </summary>
72 </member>
73 <member name="P:Newtonsoft.Json.JsonReader.CurrentState">
74 <summary>
75 Gets the current reader state.
76 </summary>
77 <value>The current reader state.</value>
78 </member>
79 <member name="P:Newtonsoft.Json.JsonReader.QuoteChar">
80 <summary>
81 Gets the quotation mark character used to enclose the value of a string.
82 </summary>
83 </member>
84 <member name="P:Newtonsoft.Json.JsonReader.TokenType">
85 <summary>
86 Gets the type of the current Json token.
87 </summary>
88 </member>
89 <member name="P:Newtonsoft.Json.JsonReader.Value">
90 <summary>
91 Gets the text value of the current Json token.
92 </summary>
93 </member>
94 <member name="P:Newtonsoft.Json.JsonReader.ValueType">
95 <summary>
96 Gets The Common Language Runtime (CLR) type for the current Json token.
97 </summary>
98 </member>
99 <member name="P:Newtonsoft.Json.JsonReader.Depth">
100 <summary>
101 Gets the depth of the current token in the JSON document.
102 </summary>
103 <value>The depth of the current token in the JSON document.</value>
104 </member>
105 <member name="T:Newtonsoft.Json.JsonReader.State">
106 <summary>
107 Specifies the state of the reader.
108 </summary>
109 </member>
110 <member name="F:Newtonsoft.Json.JsonReader.State.Start">
111 <summary>
112 The Read method has not been called.
113 </summary>
114 </member>
115 <member name="F:Newtonsoft.Json.JsonReader.State.Complete">
116 <summary>
117 The end of the file has been reached successfully.
118 </summary>
119 </member>
120 <member name="F:Newtonsoft.Json.JsonReader.State.Property">
121 <summary>
122 Reader is at a property.
123 </summary>
124 </member>
125 <member name="F:Newtonsoft.Json.JsonReader.State.ObjectStart">
126 <summary>
127 Reader is at the start of an object.
128 </summary>
129 </member>
130 <member name="F:Newtonsoft.Json.JsonReader.State.Object">
131 <summary>
132 Reader is in an object.
133 </summary>
134 </member>
135 <member name="F:Newtonsoft.Json.JsonReader.State.ArrayStart">
136 <summary>
137 Reader is at the start of an array.
138 </summary>
139 </member>
140 <member name="F:Newtonsoft.Json.JsonReader.State.Array">
141 <summary>
142 Reader is in an array.
143 </summary>
144 </member>
145 <member name="F:Newtonsoft.Json.JsonReader.State.Closed">
146 <summary>
147 The Close method has been called.
148 </summary>
149 </member>
150 <member name="F:Newtonsoft.Json.JsonReader.State.PostValue">
151 <summary>
152 Reader has just read a value.
153 </summary>
154 </member>
155 <member name="F:Newtonsoft.Json.JsonReader.State.ConstructorStart">
156 <summary>
157 Reader is at the start of a constructor.
158 </summary>
159 </member>
160 <member name="F:Newtonsoft.Json.JsonReader.State.Constructor">
161 <summary>
162 Reader in a constructor.
163 </summary>
164 </member>
165 <member name="F:Newtonsoft.Json.JsonReader.State.Error">
166 <summary>
167 An error occurred that prevents the read operation from continuing.
168 </summary>
169 </member>
170 <member name="F:Newtonsoft.Json.JsonReader.State.Finished">
171 <summary>
172 The end of the file has been reached successfully.
173 </summary>
174 </member>
175 <member name="M:Newtonsoft.Json.Bson.BsonReader.#ctor(System.IO.Stream)">
176 <summary>
177 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Bson.BsonReader"/> class.
178 </summary>
179 <param name="stream">The stream.</param>
180 </member>
181 <member name="M:Newtonsoft.Json.Bson.BsonReader.#ctor(System.IO.Stream,System.Boolean,System.DateTimeKind)">
182 <summary>
183 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Bson.BsonReader"/> class.
184 </summary>
185 <param name="stream">The stream.</param>
186 <param name="readRootValueAsArray">if set to <c>true</c> the root object will be read as a JSON array.</param>
187 <param name="dateTimeKindHandling">The <see cref="T:System.DateTimeKind"/> used when reading <see cref="T:System.DateTime"/> values from BSON.</param>
188 </member>
189 <member name="M:Newtonsoft.Json.Bson.BsonReader.ReadAsBytes">
190 <summary>
191 Reads the next JSON token from the stream as a <see cref="T:Byte[]"/>.
192 </summary>
193 <returns>
194 A <see cref="T:Byte[]"/> or a null reference if the next JSON token is null.
195 </returns>
196 </member>
197 <member name="M:Newtonsoft.Json.Bson.BsonReader.Read">
198 <summary>
199 Reads the next JSON token from the stream.
200 </summary>
201 <returns>
202 true if the next token was read successfully; false if there are no more tokens to read.
203 </returns>
204 </member>
205 <member name="P:Newtonsoft.Json.Bson.BsonReader.ReadRootValueAsArray">
206 <summary>
207 Gets or sets a value indicating whether the root object will be read as a JSON array.
208 </summary>
209 <value>
210 <c>true</c> if the root object will be read as a JSON array; otherwise, <c>false</c>.
211 </value>
212 </member>
213 <member name="P:Newtonsoft.Json.Bson.BsonReader.DateTimeKindHandling">
214 <summary>
215 Gets or sets the <see cref="T:System.DateTimeKind"/> used when reading <see cref="T:System.DateTime"/> values from BSON.
216 </summary>
217 <value>The <see cref="T:System.DateTimeKind"/> used when reading <see cref="T:System.DateTime"/> values from BSON.</value>
218 </member>
219 <member name="T:Newtonsoft.Json.Bson.BsonWriter">
220 <summary>
221 Represents a writer that provides a fast, non-cached, forward-only way of generating Json data.
222 </summary>
223 </member>
224 <member name="T:Newtonsoft.Json.Linq.JTokenWriter">
225 <summary>
226 Represents a writer that provides a fast, non-cached, forward-only way of generating Json data.
227 </summary>
228 </member>
229 <member name="T:Newtonsoft.Json.JsonWriter">
230 <summary>
231 Represents a writer that provides a fast, non-cached, forward-only way of generating Json data.
232 </summary>
233 </member>
234 <member name="M:Newtonsoft.Json.JsonWriter.#ctor">
235 <summary>
236 Creates an instance of the <c>JsonWriter</c> class.
237 </summary>
238 </member>
239 <member name="M:Newtonsoft.Json.JsonWriter.Flush">
240 <summary>
241 Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream.
242 </summary>
243 </member>
244 <member name="M:Newtonsoft.Json.JsonWriter.Close">
245 <summary>
246 Closes this stream and the underlying stream.
247 </summary>
248 </member>
249 <member name="M:Newtonsoft.Json.JsonWriter.WriteStartObject">
250 <summary>
251 Writes the beginning of a Json object.
252 </summary>
253 </member>
254 <member name="M:Newtonsoft.Json.JsonWriter.WriteEndObject">
255 <summary>
256 Writes the end of a Json object.
257 </summary>
258 </member>
259 <member name="M:Newtonsoft.Json.JsonWriter.WriteStartArray">
260 <summary>
261 Writes the beginning of a Json array.
262 </summary>
263 </member>
264 <member name="M:Newtonsoft.Json.JsonWriter.WriteEndArray">
265 <summary>
266 Writes the end of an array.
267 </summary>
268 </member>
269 <member name="M:Newtonsoft.Json.JsonWriter.WriteStartConstructor(System.String)">
270 <summary>
271 Writes the start of a constructor with the given name.
272 </summary>
273 <param name="name">The name of the constructor.</param>
274 </member>
275 <member name="M:Newtonsoft.Json.JsonWriter.WriteEndConstructor">
276 <summary>
277 Writes the end constructor.
278 </summary>
279 </member>
280 <member name="M:Newtonsoft.Json.JsonWriter.WritePropertyName(System.String)">
281 <summary>
282 Writes the property name of a name/value pair on a Json object.
283 </summary>
284 <param name="name">The name of the property.</param>
285 </member>
286 <member name="M:Newtonsoft.Json.JsonWriter.WriteEnd">
287 <summary>
288 Writes the end of the current Json object or array.
289 </summary>
290 </member>
291 <member name="M:Newtonsoft.Json.JsonWriter.WriteToken(Newtonsoft.Json.JsonReader)">
292 <summary>
293 Writes the current <see cref="T:Newtonsoft.Json.JsonReader"/> token.
294 </summary>
295 <param name="reader">The <see cref="T:Newtonsoft.Json.JsonReader"/> to read the token from.</param>
296 </member>
297 <member name="M:Newtonsoft.Json.JsonWriter.WriteEnd(Newtonsoft.Json.JsonToken)">
298 <summary>
299 Writes the specified end token.
300 </summary>
301 <param name="token">The end token to write.</param>
302 </member>
303 <member name="M:Newtonsoft.Json.JsonWriter.WriteIndent">
304 <summary>
305 Writes indent characters.
306 </summary>
307 </member>
308 <member name="M:Newtonsoft.Json.JsonWriter.WriteValueDelimiter">
309 <summary>
310 Writes the JSON value delimiter.
311 </summary>
312 </member>
313 <member name="M:Newtonsoft.Json.JsonWriter.WriteIndentSpace">
314 <summary>
315 Writes an indent space.
316 </summary>
317 </member>
318 <member name="M:Newtonsoft.Json.JsonWriter.WriteNull">
319 <summary>
320 Writes a null value.
321 </summary>
322 </member>
323 <member name="M:Newtonsoft.Json.JsonWriter.WriteUndefined">
324 <summary>
325 Writes an undefined value.
326 </summary>
327 </member>
328 <member name="M:Newtonsoft.Json.JsonWriter.WriteRaw(System.String)">
329 <summary>
330 Writes raw JSON without changing the writer's state.
331 </summary>
332 <param name="json">The raw JSON to write.</param>
333 </member>
334 <member name="M:Newtonsoft.Json.JsonWriter.WriteRawValue(System.String)">
335 <summary>
336 Writes raw JSON where a value is expected and updates the writer's state.
337 </summary>
338 <param name="json">The raw JSON to write.</param>
339 </member>
340 <member name="M:Newtonsoft.Json.JsonWriter.WriteValue(System.String)">
341 <summary>
342 Writes a <see cref="T:System.String"/> value.
343 </summary>
344 <param name="value">The <see cref="T:System.String"/> value to write.</param>
345 </member>
346 <member name="M:Newtonsoft.Json.JsonWriter.WriteValue(System.Int32)">
347 <summary>
348 Writes a <see cref="T:System.Int32"/> value.
349 </summary>
350 <param name="value">The <see cref="T:System.Int32"/> value to write.</param>
351 </member>
352 <member name="M:Newtonsoft.Json.JsonWriter.WriteValue(System.UInt32)">
353 <summary>
354 Writes a <see cref="T:System.UInt32"/> value.
355 </summary>
356 <param name="value">The <see cref="T:System.UInt32"/> value to write.</param>
357 </member>
358 <member name="M:Newtonsoft.Json.JsonWriter.WriteValue(System.Int64)">
359 <summary>
360 Writes a <see cref="T:System.Int64"/> value.
361 </summary>
362 <param name="value">The <see cref="T:System.Int64"/> value to write.</param>
363 </member>
364 <member name="M:Newtonsoft.Json.JsonWriter.WriteValue(System.UInt64)">
365 <summary>
366 Writes a <see cref="T:System.UInt64"/> value.
367 </summary>
368 <param name="value">The <see cref="T:System.UInt64"/> value to write.</param>
369 </member>
370 <member name="M:Newtonsoft.Json.JsonWriter.WriteValue(System.Single)">
371 <summary>
372 Writes a <see cref="T:System.Single"/> value.
373 </summary>
374 <param name="value">The <see cref="T:System.Single"/> value to write.</param>
375 </member>
376 <member name="M:Newtonsoft.Json.JsonWriter.WriteValue(System.Double)">
377 <summary>
378 Writes a <see cref="T:System.Double"/> value.
379 </summary>
380 <param name="value">The <see cref="T:System.Double"/> value to write.</param>
381 </member>
382 <member name="M:Newtonsoft.Json.JsonWriter.WriteValue(System.Boolean)">
383 <summary>
384 Writes a <see cref="T:System.Boolean"/> value.
385 </summary>
386 <param name="value">The <see cref="T:System.Boolean"/> value to write.</param>
387 </member>
388 <member name="M:Newtonsoft.Json.JsonWriter.WriteValue(System.Int16)">
389 <summary>
390 Writes a <see cref="T:System.Int16"/> value.
391 </summary>
392 <param name="value">The <see cref="T:System.Int16"/> value to write.</param>
393 </member>
394 <member name="M:Newtonsoft.Json.JsonWriter.WriteValue(System.UInt16)">
395 <summary>
396 Writes a <see cref="T:System.UInt16"/> value.
397 </summary>
398 <param name="value">The <see cref="T:System.UInt16"/> value to write.</param>
399 </member>
400 <member name="M:Newtonsoft.Json.JsonWriter.WriteValue(System.Char)">
401 <summary>
402 Writes a <see cref="T:System.Char"/> value.
403 </summary>
404 <param name="value">The <see cref="T:System.Char"/> value to write.</param>
405 </member>
406 <member name="M:Newtonsoft.Json.JsonWriter.WriteValue(System.Byte)">
407 <summary>
408 Writes a <see cref="T:System.Byte"/> value.
409 </summary>
410 <param name="value">The <see cref="T:System.Byte"/> value to write.</param>
411 </member>
412 <member name="M:Newtonsoft.Json.JsonWriter.WriteValue(System.SByte)">
413 <summary>
414 Writes a <see cref="T:System.SByte"/> value.
415 </summary>
416 <param name="value">The <see cref="T:System.SByte"/> value to write.</param>
417 </member>
418 <member name="M:Newtonsoft.Json.JsonWriter.WriteValue(System.Decimal)">
419 <summary>
420 Writes a <see cref="T:System.Decimal"/> value.
421 </summary>
422 <param name="value">The <see cref="T:System.Decimal"/> value to write.</param>
423 </member>
424 <member name="M:Newtonsoft.Json.JsonWriter.WriteValue(System.DateTime)">
425 <summary>
426 Writes a <see cref="T:System.DateTime"/> value.
427 </summary>
428 <param name="value">The <see cref="T:System.DateTime"/> value to write.</param>
429 </member>
430 <member name="M:Newtonsoft.Json.JsonWriter.WriteValue(System.Nullable{System.Int32})">
431 <summary>
432 Writes a <see cref="T:System.Nullable`1"/> value.
433 </summary>
434 <param name="value">The <see cref="T:System.Nullable`1"/> value to write.</param>
435 </member>
436 <member name="M:Newtonsoft.Json.JsonWriter.WriteValue(System.Nullable{System.UInt32})">
437 <summary>
438 Writes a <see cref="T:System.Nullable`1"/> value.
439 </summary>
440 <param name="value">The <see cref="T:System.Nullable`1"/> value to write.</param>
441 </member>
442 <member name="M:Newtonsoft.Json.JsonWriter.WriteValue(System.Nullable{System.Int64})">
443 <summary>
444 Writes a <see cref="T:System.Nullable`1"/> value.
445 </summary>
446 <param name="value">The <see cref="T:System.Nullable`1"/> value to write.</param>
447 </member>
448 <member name="M:Newtonsoft.Json.JsonWriter.WriteValue(System.Nullable{System.UInt64})">
449 <summary>
450 Writes a <see cref="T:System.Nullable`1"/> value.
451 </summary>
452 <param name="value">The <see cref="T:System.Nullable`1"/> value to write.</param>
453 </member>
454 <member name="M:Newtonsoft.Json.JsonWriter.WriteValue(System.Nullable{System.Single})">
455 <summary>
456 Writes a <see cref="T:System.Nullable`1"/> value.
457 </summary>
458 <param name="value">The <see cref="T:System.Nullable`1"/> value to write.</param>
459 </member>
460 <member name="M:Newtonsoft.Json.JsonWriter.WriteValue(System.Nullable{System.Double})">
461 <summary>
462 Writes a <see cref="T:System.Nullable`1"/> value.
463 </summary>
464 <param name="value">The <see cref="T:System.Nullable`1"/> value to write.</param>
465 </member>
466 <member name="M:Newtonsoft.Json.JsonWriter.WriteValue(System.Nullable{System.Boolean})">
467 <summary>
468 Writes a <see cref="T:System.Nullable`1"/> value.
469 </summary>
470 <param name="value">The <see cref="T:System.Nullable`1"/> value to write.</param>
471 </member>
472 <member name="M:Newtonsoft.Json.JsonWriter.WriteValue(System.Nullable{System.Int16})">
473 <summary>
474 Writes a <see cref="T:System.Nullable`1"/> value.
475 </summary>
476 <param name="value">The <see cref="T:System.Nullable`1"/> value to write.</param>
477 </member>
478 <member name="M:Newtonsoft.Json.JsonWriter.WriteValue(System.Nullable{System.UInt16})">
479 <summary>
480 Writes a <see cref="T:System.Nullable`1"/> value.
481 </summary>
482 <param name="value">The <see cref="T:System.Nullable`1"/> value to write.</param>
483 </member>
484 <member name="M:Newtonsoft.Json.JsonWriter.WriteValue(System.Nullable{System.Char})">
485 <summary>
486 Writes a <see cref="T:System.Nullable`1"/> value.
487 </summary>
488 <param name="value">The <see cref="T:System.Nullable`1"/> value to write.</param>
489 </member>
490 <member name="M:Newtonsoft.Json.JsonWriter.WriteValue(System.Nullable{System.Byte})">
491 <summary>
492 Writes a <see cref="T:System.Nullable`1"/> value.
493 </summary>
494 <param name="value">The <see cref="T:System.Nullable`1"/> value to write.</param>
495 </member>
496 <member name="M:Newtonsoft.Json.JsonWriter.WriteValue(System.Nullable{System.SByte})">
497 <summary>
498 Writes a <see cref="T:System.Nullable`1"/> value.
499 </summary>
500 <param name="value">The <see cref="T:System.Nullable`1"/> value to write.</param>
501 </member>
502 <member name="M:Newtonsoft.Json.JsonWriter.WriteValue(System.Nullable{System.Decimal})">
503 <summary>
504 Writes a <see cref="T:System.Nullable`1"/> value.
505 </summary>
506 <param name="value">The <see cref="T:System.Nullable`1"/> value to write.</param>
507 </member>
508 <member name="M:Newtonsoft.Json.JsonWriter.WriteValue(System.Nullable{System.DateTime})">
509 <summary>
510 Writes a <see cref="T:System.Nullable`1"/> value.
511 </summary>
512 <param name="value">The <see cref="T:System.Nullable`1"/> value to write.</param>
513 </member>
514 <member name="M:Newtonsoft.Json.JsonWriter.WriteValue(System.Byte[])">
515 <summary>
516 Writes a <see cref="T:Byte[]"/> value.
517 </summary>
518 <param name="value">The <see cref="T:Byte[]"/> value to write.</param>
519 </member>
520 <member name="M:Newtonsoft.Json.JsonWriter.WriteValue(System.Object)">
521 <summary>
522 Writes a <see cref="T:System.Object"/> value.
523 An error will raised if the value cannot be written as a single JSON token.
524 </summary>
525 <param name="value">The <see cref="T:System.Object"/> value to write.</param>
526 </member>
527 <member name="M:Newtonsoft.Json.JsonWriter.WriteComment(System.String)">
528 <summary>
529 Writes out a comment <code>/*...*/</code> containing the specified text.
530 </summary>
531 <param name="text">Text to place inside the comment.</param>
532 </member>
533 <member name="M:Newtonsoft.Json.JsonWriter.WriteWhitespace(System.String)">
534 <summary>
535 Writes out the given white space.
536 </summary>
537 <param name="ws">The string of white space characters.</param>
538 </member>
539 <member name="P:Newtonsoft.Json.JsonWriter.Top">
540 <summary>
541 Gets the top.
542 </summary>
543 <value>The top.</value>
544 </member>
545 <member name="P:Newtonsoft.Json.JsonWriter.WriteState">
546 <summary>
547 Gets the state of the writer.
548 </summary>
549 </member>
550 <member name="P:Newtonsoft.Json.JsonWriter.Formatting">
551 <summary>
552 Indicates how the output is formatted.
553 </summary>
554 </member>
555 <member name="M:Newtonsoft.Json.Linq.JTokenWriter.#ctor(Newtonsoft.Json.Linq.JContainer)">
556 <summary>
557 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Linq.JTokenWriter"/> class writing to the given <see cref="T:Newtonsoft.Json.Linq.JContainer"/>.
558 </summary>
559 <param name="container">The container being written to.</param>
560 </member>
561 <member name="M:Newtonsoft.Json.Linq.JTokenWriter.#ctor">
562 <summary>
563 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Linq.JTokenWriter"/> class.
564 </summary>
565 </member>
566 <member name="M:Newtonsoft.Json.Linq.JTokenWriter.Flush">
567 <summary>
568 Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream.
569 </summary>
570 </member>
571 <member name="M:Newtonsoft.Json.Linq.JTokenWriter.Close">
572 <summary>
573 Closes this stream and the underlying stream.
574 </summary>
575 </member>
576 <member name="M:Newtonsoft.Json.Linq.JTokenWriter.WriteStartObject">
577 <summary>
578 Writes the beginning of a Json object.
579 </summary>
580 </member>
581 <member name="M:Newtonsoft.Json.Linq.JTokenWriter.WriteStartArray">
582 <summary>
583 Writes the beginning of a Json array.
584 </summary>
585 </member>
586 <member name="M:Newtonsoft.Json.Linq.JTokenWriter.WriteStartConstructor(System.String)">
587 <summary>
588 Writes the start of a constructor with the given name.
589 </summary>
590 <param name="name">The name of the constructor.</param>
591 </member>
592 <member name="M:Newtonsoft.Json.Linq.JTokenWriter.WriteEnd(Newtonsoft.Json.JsonToken)">
593 <summary>
594 Writes the end.
595 </summary>
596 <param name="token">The token.</param>
597 </member>
598 <member name="M:Newtonsoft.Json.Linq.JTokenWriter.WritePropertyName(System.String)">
599 <summary>
600 Writes the property name of a name/value pair on a Json object.
601 </summary>
602 <param name="name">The name of the property.</param>
603 </member>
604 <member name="M:Newtonsoft.Json.Linq.JTokenWriter.WriteNull">
605 <summary>
606 Writes a null value.
607 </summary>
608 </member>
609 <member name="M:Newtonsoft.Json.Linq.JTokenWriter.WriteUndefined">
610 <summary>
611 Writes an undefined value.
612 </summary>
613 </member>
614 <member name="M:Newtonsoft.Json.Linq.JTokenWriter.WriteRaw(System.String)">
615 <summary>
616 Writes raw JSON.
617 </summary>
618 <param name="json">The raw JSON to write.</param>
619 </member>
620 <member name="M:Newtonsoft.Json.Linq.JTokenWriter.WriteComment(System.String)">
621 <summary>
622 Writes out a comment <code>/*...*/</code> containing the specified text.
623 </summary>
624 <param name="text">Text to place inside the comment.</param>
625 </member>
626 <member name="M:Newtonsoft.Json.Linq.JTokenWriter.WriteValue(System.String)">
627 <summary>
628 Writes a <see cref="T:System.String"/> value.
629 </summary>
630 <param name="value">The <see cref="T:System.String"/> value to write.</param>
631 </member>
632 <member name="M:Newtonsoft.Json.Linq.JTokenWriter.WriteValue(System.Int32)">
633 <summary>
634 Writes a <see cref="T:System.Int32"/> value.
635 </summary>
636 <param name="value">The <see cref="T:System.Int32"/> value to write.</param>
637 </member>
638 <member name="M:Newtonsoft.Json.Linq.JTokenWriter.WriteValue(System.UInt32)">
639 <summary>
640 Writes a <see cref="T:System.UInt32"/> value.
641 </summary>
642 <param name="value">The <see cref="T:System.UInt32"/> value to write.</param>
643 </member>
644 <member name="M:Newtonsoft.Json.Linq.JTokenWriter.WriteValue(System.Int64)">
645 <summary>
646 Writes a <see cref="T:System.Int64"/> value.
647 </summary>
648 <param name="value">The <see cref="T:System.Int64"/> value to write.</param>
649 </member>
650 <member name="M:Newtonsoft.Json.Linq.JTokenWriter.WriteValue(System.UInt64)">
651 <summary>
652 Writes a <see cref="T:System.UInt64"/> value.
653 </summary>
654 <param name="value">The <see cref="T:System.UInt64"/> value to write.</param>
655 </member>
656 <member name="M:Newtonsoft.Json.Linq.JTokenWriter.WriteValue(System.Single)">
657 <summary>
658 Writes a <see cref="T:System.Single"/> value.
659 </summary>
660 <param name="value">The <see cref="T:System.Single"/> value to write.</param>
661 </member>
662 <member name="M:Newtonsoft.Json.Linq.JTokenWriter.WriteValue(System.Double)">
663 <summary>
664 Writes a <see cref="T:System.Double"/> value.
665 </summary>
666 <param name="value">The <see cref="T:System.Double"/> value to write.</param>
667 </member>
668 <member name="M:Newtonsoft.Json.Linq.JTokenWriter.WriteValue(System.Boolean)">
669 <summary>
670 Writes a <see cref="T:System.Boolean"/> value.
671 </summary>
672 <param name="value">The <see cref="T:System.Boolean"/> value to write.</param>
673 </member>
674 <member name="M:Newtonsoft.Json.Linq.JTokenWriter.WriteValue(System.Int16)">
675 <summary>
676 Writes a <see cref="T:System.Int16"/> value.
677 </summary>
678 <param name="value">The <see cref="T:System.Int16"/> value to write.</param>
679 </member>
680 <member name="M:Newtonsoft.Json.Linq.JTokenWriter.WriteValue(System.UInt16)">
681 <summary>
682 Writes a <see cref="T:System.UInt16"/> value.
683 </summary>
684 <param name="value">The <see cref="T:System.UInt16"/> value to write.</param>
685 </member>
686 <member name="M:Newtonsoft.Json.Linq.JTokenWriter.WriteValue(System.Char)">
687 <summary>
688 Writes a <see cref="T:System.Char"/> value.
689 </summary>
690 <param name="value">The <see cref="T:System.Char"/> value to write.</param>
691 </member>
692 <member name="M:Newtonsoft.Json.Linq.JTokenWriter.WriteValue(System.Byte)">
693 <summary>
694 Writes a <see cref="T:System.Byte"/> value.
695 </summary>
696 <param name="value">The <see cref="T:System.Byte"/> value to write.</param>
697 </member>
698 <member name="M:Newtonsoft.Json.Linq.JTokenWriter.WriteValue(System.SByte)">
699 <summary>
700 Writes a <see cref="T:System.SByte"/> value.
701 </summary>
702 <param name="value">The <see cref="T:System.SByte"/> value to write.</param>
703 </member>
704 <member name="M:Newtonsoft.Json.Linq.JTokenWriter.WriteValue(System.Decimal)">
705 <summary>
706 Writes a <see cref="T:System.Decimal"/> value.
707 </summary>
708 <param name="value">The <see cref="T:System.Decimal"/> value to write.</param>
709 </member>
710 <member name="M:Newtonsoft.Json.Linq.JTokenWriter.WriteValue(System.DateTime)">
711 <summary>
712 Writes a <see cref="T:System.DateTime"/> value.
713 </summary>
714 <param name="value">The <see cref="T:System.DateTime"/> value to write.</param>
715 </member>
716 <member name="M:Newtonsoft.Json.Linq.JTokenWriter.WriteValue(System.Byte[])">
717 <summary>
718 Writes a <see cref="T:Byte[]"/> value.
719 </summary>
720 <param name="value">The <see cref="T:Byte[]"/> value to write.</param>
721 </member>
722 <member name="P:Newtonsoft.Json.Linq.JTokenWriter.Token">
723 <summary>
724 Gets the token being writen.
725 </summary>
726 <value>The token being writen.</value>
727 </member>
728 <member name="M:Newtonsoft.Json.Bson.BsonWriter.#ctor(System.IO.Stream)">
729 <summary>
730 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Bson.BsonWriter"/> class.
731 </summary>
732 <param name="stream">The stream.</param>
733 </member>
734 <member name="M:Newtonsoft.Json.Bson.BsonWriter.Flush">
735 <summary>
736 Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream.
737 </summary>
738 </member>
739 <member name="M:Newtonsoft.Json.Bson.BsonWriter.WriteEnd(Newtonsoft.Json.JsonToken)">
740 <summary>
741 Writes the end.
742 </summary>
743 <param name="token">The token.</param>
744 </member>
745 <member name="M:Newtonsoft.Json.Bson.BsonWriter.WriteComment(System.String)">
746 <summary>
747 Writes out a comment <code>/*...*/</code> containing the specified text.
748 </summary>
749 <param name="text">Text to place inside the comment.</param>
750 </member>
751 <member name="M:Newtonsoft.Json.Bson.BsonWriter.WriteStartConstructor(System.String)">
752 <summary>
753 Writes the start of a constructor with the given name.
754 </summary>
755 <param name="name">The name of the constructor.</param>
756 </member>
757 <member name="M:Newtonsoft.Json.Bson.BsonWriter.WriteRaw(System.String)">
758 <summary>
759 Writes raw JSON.
760 </summary>
761 <param name="json">The raw JSON to write.</param>
762 </member>
763 <member name="M:Newtonsoft.Json.Bson.BsonWriter.WriteRawValue(System.String)">
764 <summary>
765 Writes raw JSON where a value is expected and updates the writer's state.
766 </summary>
767 <param name="json">The raw JSON to write.</param>
768 </member>
769 <member name="T:Newtonsoft.Json.ConstructorHandling">
770 <summary>
771 Specifies how constructors are used when initializing objects during deserialization by the <see cref="T:Newtonsoft.Json.JsonSerializer"/>.
772 </summary>
773 </member>
774 <member name="F:Newtonsoft.Json.ConstructorHandling.Default">
775 <summary>
776 First attempt to use the public default constructor then fall back to single paramatized constructor.
777 </summary>
778 </member>
779 <member name="F:Newtonsoft.Json.ConstructorHandling.AllowNonPublicDefaultConstructor">
780 <summary>
781 Allow Json.NET to use a non-public default constructor.
782 </summary>
783 </member>
784 <member name="T:Newtonsoft.Json.Converters.BinaryConverter">
785 <summary>
786 Converts a binary value to and from a base 64 string value.
787 </summary>
788 </member>
789 <member name="T:Newtonsoft.Json.JsonConverter">
790 <summary>
791 Converts an object to and from JSON.
792 </summary>
793 </member>
794 <member name="M:Newtonsoft.Json.JsonConverter.WriteJson(Newtonsoft.Json.JsonWriter,System.Object,Newtonsoft.Json.JsonSerializer)">
795 <summary>
796 Writes the JSON representation of the object.
797 </summary>
798 <param name="writer">The <see cref="T:Newtonsoft.Json.JsonWriter"/> to write to.</param>
799 <param name="value">The value.</param>
800 <param name="serializer">The calling serializer.</param>
801 </member>
802 <member name="M:Newtonsoft.Json.JsonConverter.ReadJson(Newtonsoft.Json.JsonReader,System.Type,Newtonsoft.Json.JsonSerializer)">
803 <summary>
804 Reads the JSON representation of the object.
805 </summary>
806 <param name="reader">The <see cref="T:Newtonsoft.Json.JsonReader"/> to read from.</param>
807 <param name="objectType">Type of the object.</param>
808 <param name="serializer">The calling serializer.</param>
809 <returns>The object value.</returns>
810 </member>
811 <member name="M:Newtonsoft.Json.JsonConverter.CanConvert(System.Type)">
812 <summary>
813 Determines whether this instance can convert the specified object type.
814 </summary>
815 <param name="objectType">Type of the object.</param>
816 <returns>
817 <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
818 </returns>
819 </member>
820 <member name="M:Newtonsoft.Json.Converters.BinaryConverter.WriteJson(Newtonsoft.Json.JsonWriter,System.Object,Newtonsoft.Json.JsonSerializer)">
821 <summary>
822 Writes the JSON representation of the object.
823 </summary>
824 <param name="writer">The <see cref="T:Newtonsoft.Json.JsonWriter"/> to write to.</param>
825 <param name="value">The value.</param>
826 <param name="serializer">The calling serializer.</param>
827 </member>
828 <member name="M:Newtonsoft.Json.Converters.BinaryConverter.ReadJson(Newtonsoft.Json.JsonReader,System.Type,Newtonsoft.Json.JsonSerializer)">
829 <summary>
830 Reads the JSON representation of the object.
831 </summary>
832 <param name="reader">The <see cref="T:Newtonsoft.Json.JsonReader"/> to read from.</param>
833 <param name="objectType">Type of the object.</param>
834 <param name="serializer">The calling serializer.</param>
835 <returns>The object value.</returns>
836 </member>
837 <member name="M:Newtonsoft.Json.Converters.BinaryConverter.CanConvert(System.Type)">
838 <summary>
839 Determines whether this instance can convert the specified object type.
840 </summary>
841 <param name="objectType">Type of the object.</param>
842 <returns>
843 <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
844 </returns>
845 </member>
846 <member name="T:Newtonsoft.Json.Converters.CustomCreationConverter`1">
847 <summary>
848 Create a custom object
849 </summary>
850 <typeparam name="T"></typeparam>
851 </member>
852 <member name="M:Newtonsoft.Json.Converters.CustomCreationConverter`1.WriteJson(Newtonsoft.Json.JsonWriter,System.Object,Newtonsoft.Json.JsonSerializer)">
853 <summary>
854 Writes the JSON representation of the object.
855 </summary>
856 <param name="writer">The <see cref="T:Newtonsoft.Json.JsonWriter"/> to write to.</param>
857 <param name="value">The value.</param>
858 <param name="serializer">The calling serializer.</param>
859 </member>
860 <member name="M:Newtonsoft.Json.Converters.CustomCreationConverter`1.ReadJson(Newtonsoft.Json.JsonReader,System.Type,Newtonsoft.Json.JsonSerializer)">
861 <summary>
862 Reads the JSON representation of the object.
863 </summary>
864 <param name="reader">The <see cref="T:Newtonsoft.Json.JsonReader"/> to read from.</param>
865 <param name="objectType">Type of the object.</param>
866 <param name="serializer">The calling serializer.</param>
867 <returns>The object value.</returns>
868 </member>
869 <member name="M:Newtonsoft.Json.Converters.CustomCreationConverter`1.Create(System.Type)">
870 <summary>
871 Creates an object which will then be populated by the serializer.
872 </summary>
873 <param name="objectType">Type of the object.</param>
874 <returns></returns>
875 </member>
876 <member name="M:Newtonsoft.Json.Converters.CustomCreationConverter`1.CanConvert(System.Type)">
877 <summary>
878 Determines whether this instance can convert the specified object type.
879 </summary>
880 <param name="objectType">Type of the object.</param>
881 <returns>
882 <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
883 </returns>
884 </member>
885 <member name="T:Newtonsoft.Json.Converters.DataSetConverter">
886 <summary>
887 Converts a <see cref="T:System.Data.DataSet"/> to and from JSON.
888 </summary>
889 </member>
890 <member name="M:Newtonsoft.Json.Converters.DataSetConverter.WriteJson(Newtonsoft.Json.JsonWriter,System.Object,Newtonsoft.Json.JsonSerializer)">
891 <summary>
892 Writes the JSON representation of the object.
893 </summary>
894 <param name="writer">The <see cref="T:Newtonsoft.Json.JsonWriter"/> to write to.</param>
895 <param name="value">The value.</param>
896 <param name="serializer">The calling serializer.</param>
897 </member>
898 <member name="M:Newtonsoft.Json.Converters.DataSetConverter.ReadJson(Newtonsoft.Json.JsonReader,System.Type,Newtonsoft.Json.JsonSerializer)">
899 <summary>
900 Reads the JSON representation of the object.
901 </summary>
902 <param name="reader">The <see cref="T:Newtonsoft.Json.JsonReader"/> to read from.</param>
903 <param name="objectType">Type of the object.</param>
904 <param name="serializer">The calling serializer.</param>
905 <returns>The object value.</returns>
906 </member>
907 <member name="M:Newtonsoft.Json.Converters.DataSetConverter.CanConvert(System.Type)">
908 <summary>
909 Determines whether this instance can convert the specified value type.
910 </summary>
911 <param name="valueType">Type of the value.</param>
912 <returns>
913 <c>true</c> if this instance can convert the specified value type; otherwise, <c>false</c>.
914 </returns>
915 </member>
916 <member name="T:Newtonsoft.Json.Converters.DataTableConverter">
917 <summary>
918 Converts a <see cref="T:System.Data.DataTable"/> to and from JSON.
919 </summary>
920 </member>
921 <member name="M:Newtonsoft.Json.Converters.DataTableConverter.WriteJson(Newtonsoft.Json.JsonWriter,System.Object,Newtonsoft.Json.JsonSerializer)">
922 <summary>
923 Writes the JSON representation of the object.
924 </summary>
925 <param name="writer">The <see cref="T:Newtonsoft.Json.JsonWriter"/> to write to.</param>
926 <param name="value">The value.</param>
927 <param name="serializer">The calling serializer.</param>
928 </member>
929 <member name="M:Newtonsoft.Json.Converters.DataTableConverter.ReadJson(Newtonsoft.Json.JsonReader,System.Type,Newtonsoft.Json.JsonSerializer)">
930 <summary>
931 Reads the JSON representation of the object.
932 </summary>
933 <param name="reader">The <see cref="T:Newtonsoft.Json.JsonReader"/> to read from.</param>
934 <param name="objectType">Type of the object.</param>
935 <param name="serializer">The calling serializer.</param>
936 <returns>The object value.</returns>
937 </member>
938 <member name="M:Newtonsoft.Json.Converters.DataTableConverter.CanConvert(System.Type)">
939 <summary>
940 Determines whether this instance can convert the specified value type.
941 </summary>
942 <param name="valueType">Type of the value.</param>
943 <returns>
944 <c>true</c> if this instance can convert the specified value type; otherwise, <c>false</c>.
945 </returns>
946 </member>
947 <member name="T:Newtonsoft.Json.Converters.DateTimeConverterBase">
948 <summary>
949 Provides a base class for converting a <see cref="T:System.DateTime"/> to and from JSON.
950 </summary>
951 </member>
952 <member name="M:Newtonsoft.Json.Converters.DateTimeConverterBase.CanConvert(System.Type)">
953 <summary>
954 Determines whether this instance can convert the specified object type.
955 </summary>
956 <param name="objectType">Type of the object.</param>
957 <returns>
958 <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
959 </returns>
960 </member>
961 <member name="T:Newtonsoft.Json.Converters.StringEnumConverter">
962 <summary>
963 Converts an <see cref="T:System.Enum"/> to and from its name string value.
964 </summary>
965 </member>
966 <member name="M:Newtonsoft.Json.Converters.StringEnumConverter.WriteJson(Newtonsoft.Json.JsonWriter,System.Object,Newtonsoft.Json.JsonSerializer)">
967 <summary>
968 Writes the JSON representation of the object.
969 </summary>
970 <param name="writer">The <see cref="T:Newtonsoft.Json.JsonWriter"/> to write to.</param>
971 <param name="value">The value.</param>
972 <param name="serializer">The calling serializer.</param>
973 </member>
974 <member name="M:Newtonsoft.Json.Converters.StringEnumConverter.ReadJson(Newtonsoft.Json.JsonReader,System.Type,Newtonsoft.Json.JsonSerializer)">
975 <summary>
976 Reads the JSON representation of the object.
977 </summary>
978 <param name="reader">The <see cref="T:Newtonsoft.Json.JsonReader"/> to read from.</param>
979 <param name="objectType">Type of the object.</param>
980 <param name="serializer">The calling serializer.</param>
981 <returns>The object value.</returns>
982 </member>
983 <member name="M:Newtonsoft.Json.Converters.StringEnumConverter.CanConvert(System.Type)">
984 <summary>
985 Determines whether this instance can convert the specified object type.
986 </summary>
987 <param name="objectType">Type of the object.</param>
988 <returns>
989 <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
990 </returns>
991 </member>
992 <member name="T:Newtonsoft.Json.Linq.ComponentModel.JPropertyDescriptor">
993 <summary>
994 Represents a view of a <see cref="T:Newtonsoft.Json.Linq.JProperty"/>.
995 </summary>
996 </member>
997 <member name="M:Newtonsoft.Json.Linq.ComponentModel.JPropertyDescriptor.#ctor(System.String,System.Type)">
998 <summary>
999 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Linq.ComponentModel.JPropertyDescriptor"/> class.
1000 </summary>
1001 <param name="name">The name.</param>
1002 <param name="propertyType">Type of the property.</param>
1003 </member>
1004 <member name="M:Newtonsoft.Json.Linq.ComponentModel.JPropertyDescriptor.CanResetValue(System.Object)">
1005 <summary>
1006 When overridden in a derived class, returns whether resetting an object changes its value.
1007 </summary>
1008 <returns>
1009 true if resetting the component changes its value; otherwise, false.
1010 </returns>
1011 <param name="component">The component to test for reset capability.
1012 </param>
1013 </member>
1014 <member name="M:Newtonsoft.Json.Linq.ComponentModel.JPropertyDescriptor.GetValue(System.Object)">
1015 <summary>
1016 When overridden in a derived class, gets the current value of the property on a component.
1017 </summary>
1018 <returns>
1019 The value of a property for a given component.
1020 </returns>
1021 <param name="component">The component with the property for which to retrieve the value.
1022 </param>
1023 </member>
1024 <member name="M:Newtonsoft.Json.Linq.ComponentModel.JPropertyDescriptor.ResetValue(System.Object)">
1025 <summary>
1026 When overridden in a derived class, resets the value for this property of the component to the default value.
1027 </summary>
1028 <param name="component">The component with the property value that is to be reset to the default value.
1029 </param>
1030 </member>
1031 <member name="M:Newtonsoft.Json.Linq.ComponentModel.JPropertyDescriptor.SetValue(System.Object,System.Object)">
1032 <summary>
1033 When overridden in a derived class, sets the value of the component to a different value.
1034 </summary>
1035 <param name="component">The component with the property value that is to be set.
1036 </param><param name="value">The new value.
1037 </param>
1038 </member>
1039 <member name="M:Newtonsoft.Json.Linq.ComponentModel.JPropertyDescriptor.ShouldSerializeValue(System.Object)">
1040 <summary>
1041 When overridden in a derived class, determines a value indicating whether the value of this property needs to be persisted.
1042 </summary>
1043 <returns>
1044 true if the property should be persisted; otherwise, false.
1045 </returns>
1046 <param name="component">The component with the property to be examined for persistence.
1047 </param>
1048 </member>
1049 <member name="P:Newtonsoft.Json.Linq.ComponentModel.JPropertyDescriptor.ComponentType">
1050 <summary>
1051 When overridden in a derived class, gets the type of the component this property is bound to.
1052 </summary>
1053 <returns>
1054 A <see cref="T:System.Type"/> that represents the type of component this property is bound to. When the <see cref="M:System.ComponentModel.PropertyDescriptor.GetValue(System.Object)"/> or <see cref="M:System.ComponentModel.PropertyDescriptor.SetValue(System.Object,System.Object)"/> methods are invoked, the object specified might be an instance of this type.
1055 </returns>
1056 </member>
1057 <member name="P:Newtonsoft.Json.Linq.ComponentModel.JPropertyDescriptor.IsReadOnly">
1058 <summary>
1059 When overridden in a derived class, gets a value indicating whether this property is read-only.
1060 </summary>
1061 <returns>
1062 true if the property is read-only; otherwise, false.
1063 </returns>
1064 </member>
1065 <member name="P:Newtonsoft.Json.Linq.ComponentModel.JPropertyDescriptor.PropertyType">
1066 <summary>
1067 When overridden in a derived class, gets the type of the property.
1068 </summary>
1069 <returns>
1070 A <see cref="T:System.Type"/> that represents the type of the property.
1071 </returns>
1072 </member>
1073 <member name="P:Newtonsoft.Json.Linq.ComponentModel.JPropertyDescriptor.NameHashCode">
1074 <summary>
1075 Gets the hash code for the name of the member.
1076 </summary>
1077 <value></value>
1078 <returns>
1079 The hash code for the name of the member.
1080 </returns>
1081 </member>
1082 <member name="T:Newtonsoft.Json.Linq.ComponentModel.JTypeDescriptor">
1083 <summary>
1084 Represents a view of a <see cref="T:Newtonsoft.Json.Linq.JObject"/>.
1085 </summary>
1086 </member>
1087 <member name="M:Newtonsoft.Json.Linq.ComponentModel.JTypeDescriptor.#ctor(Newtonsoft.Json.Linq.JObject)">
1088 <summary>
1089 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Linq.ComponentModel.JTypeDescriptor"/> class.
1090 </summary>
1091 <param name="value">The value.</param>
1092 </member>
1093 <member name="M:Newtonsoft.Json.Linq.ComponentModel.JTypeDescriptor.GetProperties">
1094 <summary>
1095 Returns the properties for this instance of a component.
1096 </summary>
1097 <returns>
1098 A <see cref="T:System.ComponentModel.PropertyDescriptorCollection"/> that represents the properties for this component instance.
1099 </returns>
1100 </member>
1101 <member name="M:Newtonsoft.Json.Linq.ComponentModel.JTypeDescriptor.GetProperties(System.Attribute[])">
1102 <summary>
1103 Returns the properties for this instance of a component using the attribute array as a filter.
1104 </summary>
1105 <param name="attributes">An array of type <see cref="T:System.Attribute"/> that is used as a filter.</param>
1106 <returns>
1107 A <see cref="T:System.ComponentModel.PropertyDescriptorCollection"/> that represents the filtered properties for this component instance.
1108 </returns>
1109 </member>
1110 <member name="M:Newtonsoft.Json.Linq.ComponentModel.JTypeDescriptor.GetAttributes">
1111 <summary>
1112 Returns a collection of custom attributes for this instance of a component.
1113 </summary>
1114 <returns>
1115 An <see cref="T:System.ComponentModel.AttributeCollection"/> containing the attributes for this object.
1116 </returns>
1117 </member>
1118 <member name="M:Newtonsoft.Json.Linq.ComponentModel.JTypeDescriptor.GetClassName">
1119 <summary>
1120 Returns the class name of this instance of a component.
1121 </summary>
1122 <returns>
1123 The class name of the object, or null if the class does not have a name.
1124 </returns>
1125 </member>
1126 <member name="M:Newtonsoft.Json.Linq.ComponentModel.JTypeDescriptor.GetComponentName">
1127 <summary>
1128 Returns the name of this instance of a component.
1129 </summary>
1130 <returns>
1131 The name of the object, or null if the object does not have a name.
1132 </returns>
1133 </member>
1134 <member name="M:Newtonsoft.Json.Linq.ComponentModel.JTypeDescriptor.GetConverter">
1135 <summary>
1136 Returns a type converter for this instance of a component.
1137 </summary>
1138 <returns>
1139 A <see cref="T:System.ComponentModel.TypeConverter"/> that is the converter for this object, or null if there is no <see cref="T:System.ComponentModel.TypeConverter"/> for this object.
1140 </returns>
1141 </member>
1142 <member name="M:Newtonsoft.Json.Linq.ComponentModel.JTypeDescriptor.GetDefaultEvent">
1143 <summary>
1144 Returns the default event for this instance of a component.
1145 </summary>
1146 <returns>
1147 An <see cref="T:System.ComponentModel.EventDescriptor"/> that represents the default event for this object, or null if this object does not have events.
1148 </returns>
1149 </member>
1150 <member name="M:Newtonsoft.Json.Linq.ComponentModel.JTypeDescriptor.GetDefaultProperty">
1151 <summary>
1152 Returns the default property for this instance of a component.
1153 </summary>
1154 <returns>
1155 A <see cref="T:System.ComponentModel.PropertyDescriptor"/> that represents the default property for this object, or null if this object does not have properties.
1156 </returns>
1157 </member>
1158 <member name="M:Newtonsoft.Json.Linq.ComponentModel.JTypeDescriptor.GetEditor(System.Type)">
1159 <summary>
1160 Returns an editor of the specified type for this instance of a component.
1161 </summary>
1162 <param name="editorBaseType">A <see cref="T:System.Type"/> that represents the editor for this object.</param>
1163 <returns>
1164 An <see cref="T:System.Object"/> of the specified type that is the editor for this object, or null if the editor cannot be found.
1165 </returns>
1166 </member>
1167 <member name="M:Newtonsoft.Json.Linq.ComponentModel.JTypeDescriptor.GetEvents(System.Attribute[])">
1168 <summary>
1169 Returns the events for this instance of a component using the specified attribute array as a filter.
1170 </summary>
1171 <param name="attributes">An array of type <see cref="T:System.Attribute"/> that is used as a filter.</param>
1172 <returns>
1173 An <see cref="T:System.ComponentModel.EventDescriptorCollection"/> that represents the filtered events for this component instance.
1174 </returns>
1175 </member>
1176 <member name="M:Newtonsoft.Json.Linq.ComponentModel.JTypeDescriptor.GetEvents">
1177 <summary>
1178 Returns the events for this instance of a component.
1179 </summary>
1180 <returns>
1181 An <see cref="T:System.ComponentModel.EventDescriptorCollection"/> that represents the events for this component instance.
1182 </returns>
1183 </member>
1184 <member name="M:Newtonsoft.Json.Linq.ComponentModel.JTypeDescriptor.GetPropertyOwner(System.ComponentModel.PropertyDescriptor)">
1185 <summary>
1186 Returns an object that contains the property described by the specified property descriptor.
1187 </summary>
1188 <param name="pd">A <see cref="T:System.ComponentModel.PropertyDescriptor"/> that represents the property whose owner is to be found.</param>
1189 <returns>
1190 An <see cref="T:System.Object"/> that represents the owner of the specified property.
1191 </returns>
1192 </member>
1193 <member name="T:Newtonsoft.Json.Linq.JRaw">
1194 <summary>
1195 Represents a raw JSON string.
1196 </summary>
1197 </member>
1198 <member name="T:Newtonsoft.Json.Linq.JValue">
1199 <summary>
1200 Represents a value in JSON (string, integer, date, etc).
1201 </summary>
1202 </member>
1203 <member name="T:Newtonsoft.Json.Linq.JToken">
1204 <summary>
1205 Represents an abstract JSON token.
1206 </summary>
1207 </member>
1208 <member name="T:Newtonsoft.Json.Linq.IJEnumerable`1">
1209 <summary>
1210 Represents a collection of <see cref="T:Newtonsoft.Json.Linq.JToken"/> objects.
1211 </summary>
1212 <typeparam name="T">The type of token</typeparam>
1213 </member>
1214 <member name="P:Newtonsoft.Json.Linq.IJEnumerable`1.Item(System.Object)">
1215 <summary>
1216 Gets the <see cref="T:Newtonsoft.Json.Linq.IJEnumerable`1"/> with the specified key.
1217 </summary>
1218 <value></value>
1219 </member>
1220 <member name="T:Newtonsoft.Json.IJsonLineInfo">
1221 <summary>
1222 Provides an interface to enable a class to return line and position information.
1223 </summary>
1224 </member>
1225 <member name="M:Newtonsoft.Json.IJsonLineInfo.HasLineInfo">
1226 <summary>
1227 Gets a value indicating whether the class can return line information.
1228 </summary>
1229 <returns>
1230 <c>true</c> if LineNumber and LinePosition can be provided; otherwise, <c>false</c>.
1231 </returns>
1232 </member>
1233 <member name="P:Newtonsoft.Json.IJsonLineInfo.LineNumber">
1234 <summary>
1235 Gets the current line number.
1236 </summary>
1237 <value>The current line number or 0 if no line information is available (for example, HasLineInfo returns false).</value>
1238 </member>
1239 <member name="P:Newtonsoft.Json.IJsonLineInfo.LinePosition">
1240 <summary>
1241 Gets the current line position.
1242 </summary>
1243 <value>The current line position or 0 if no line information is available (for example, HasLineInfo returns false).</value>
1244 </member>
1245 <member name="M:Newtonsoft.Json.Linq.JToken.DeepEquals(Newtonsoft.Json.Linq.JToken,Newtonsoft.Json.Linq.JToken)">
1246 <summary>
1247 Compares the values of two tokens, including the values of all descendant tokens.
1248 </summary>
1249 <param name="t1">The first <see cref="T:Newtonsoft.Json.Linq.JToken"/> to compare.</param>
1250 <param name="t2">The second <see cref="T:Newtonsoft.Json.Linq.JToken"/> to compare.</param>
1251 <returns>true if the tokens are equal; otherwise false.</returns>
1252 </member>
1253 <member name="M:Newtonsoft.Json.Linq.JToken.AddAfterSelf(System.Object)">
1254 <summary>
1255 Adds the specified content immediately after this token.
1256 </summary>
1257 <param name="content">A content object that contains simple content or a collection of content objects to be added after this token.</param>
1258 </member>
1259 <member name="M:Newtonsoft.Json.Linq.JToken.AddBeforeSelf(System.Object)">
1260 <summary>
1261 Adds the specified content immediately before this token.
1262 </summary>
1263 <param name="content">A content object that contains simple content or a collection of content objects to be added before this token.</param>
1264 </member>
1265 <member name="M:Newtonsoft.Json.Linq.JToken.Ancestors">
1266 <summary>
1267 Returns a collection of the ancestor tokens of this token.
1268 </summary>
1269 <returns>A collection of the ancestor tokens of this token.</returns>
1270 </member>
1271 <member name="M:Newtonsoft.Json.Linq.JToken.AfterSelf">
1272 <summary>
1273 Returns a collection of the sibling tokens after this token, in document order.
1274 </summary>
1275 <returns>A collection of the sibling tokens after this tokens, in document order.</returns>
1276 </member>
1277 <member name="M:Newtonsoft.Json.Linq.JToken.BeforeSelf">
1278 <summary>
1279 Returns a collection of the sibling tokens before this token, in document order.
1280 </summary>
1281 <returns>A collection of the sibling tokens before this token, in document order.</returns>
1282 </member>
1283 <member name="M:Newtonsoft.Json.Linq.JToken.Value``1(System.Object)">
1284 <summary>
1285 Gets the <see cref="T:Newtonsoft.Json.Linq.JToken"/> with the specified key converted to the specified type.
1286 </summary>
1287 <typeparam name="T">The type to convert the token to.</typeparam>
1288 <param name="key">The token key.</param>
1289 <returns>The converted token value.</returns>
1290 </member>
1291 <member name="M:Newtonsoft.Json.Linq.JToken.Children">
1292 <summary>
1293 Returns a collection of the child tokens of this token, in document order.
1294 </summary>
1295 <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1"/> of <see cref="T:Newtonsoft.Json.Linq.JToken"/> containing the child tokens of this <see cref="T:Newtonsoft.Json.Linq.JToken"/>, in document order.</returns>
1296 </member>
1297 <member name="M:Newtonsoft.Json.Linq.JToken.Children``1">
1298 <summary>
1299 Returns a collection of the child tokens of this token, in document order, filtered by the specified type.
1300 </summary>
1301 <typeparam name="T">The type to filter the child tokens on.</typeparam>
1302 <returns>A <see cref="T:Newtonsoft.Json.Linq.JEnumerable`1"/> containing the child tokens of this <see cref="T:Newtonsoft.Json.Linq.JToken"/>, in document order.</returns>
1303 </member>
1304 <member name="M:Newtonsoft.Json.Linq.JToken.Values``1">
1305 <summary>
1306 Returns a collection of the child values of this token, in document order.
1307 </summary>
1308 <typeparam name="T">The type to convert the values to.</typeparam>
1309 <returns>A <see cref="T:System.Collections.Generic.IEnumerable`1"/> containing the child values of this <see cref="T:Newtonsoft.Json.Linq.JToken"/>, in document order.</returns>
1310 </member>
1311 <member name="M:Newtonsoft.Json.Linq.JToken.Remove">
1312 <summary>
1313 Removes this token from its parent.
1314 </summary>
1315 </member>
1316 <member name="M:Newtonsoft.Json.Linq.JToken.Replace(Newtonsoft.Json.Linq.JToken)">
1317 <summary>
1318 Replaces this token with the specified token.
1319 </summary>
1320 <param name="value">The value.</param>
1321 </member>
1322 <member name="M:Newtonsoft.Json.Linq.JToken.WriteTo(Newtonsoft.Json.JsonWriter,Newtonsoft.Json.JsonConverter[])">
1323 <summary>
1324 Writes this token to a <see cref="T:Newtonsoft.Json.JsonWriter"/>.
1325 </summary>
1326 <param name="writer">A <see cref="T:Newtonsoft.Json.JsonWriter"/> into which this method will write.</param>
1327 <param name="converters">A collection of <see cref="T:Newtonsoft.Json.JsonConverter"/> which will be used when writing the token.</param>
1328 </member>
1329 <member name="M:Newtonsoft.Json.Linq.JToken.ToString">
1330 <summary>
1331 Returns the indented JSON for this token.
1332 </summary>
1333 <returns>
1334 The indented JSON for this token.
1335 </returns>
1336 </member>
1337 <member name="M:Newtonsoft.Json.Linq.JToken.ToString(Newtonsoft.Json.Formatting,Newtonsoft.Json.JsonConverter[])">
1338 <summary>
1339 Returns the JSON for this token using the given formatting and converters.
1340 </summary>
1341 <param name="formatting">Indicates how the output is formatted.</param>
1342 <param name="converters">A collection of <see cref="T:Newtonsoft.Json.JsonConverter"/> which will be used when writing the token.</param>
1343 <returns>The JSON for this token using the given formatting and converters.</returns>
1344 </member>
1345 <member name="M:Newtonsoft.Json.Linq.JToken.op_Explicit(Newtonsoft.Json.Linq.JToken)~System.Boolean">
1346 <summary>
1347 Performs an explicit conversion from <see cref="T:Newtonsoft.Json.Linq.JToken"/> to <see cref="T:System.Boolean"/>.
1348 </summary>
1349 <param name="value">The value.</param>
1350 <returns>The result of the conversion.</returns>
1351 </member>
1352 <member name="M:Newtonsoft.Json.Linq.JToken.op_Explicit(Newtonsoft.Json.Linq.JToken)~System.Nullable{System.Boolean}">
1353 <summary>
1354 Performs an explicit conversion from <see cref="T:Newtonsoft.Json.Linq.JToken"/> to <see cref="T:System.Nullable`1"/>.
1355 </summary>
1356 <param name="value">The value.</param>
1357 <returns>The result of the conversion.</returns>
1358 </member>
1359 <member name="M:Newtonsoft.Json.Linq.JToken.op_Explicit(Newtonsoft.Json.Linq.JToken)~System.Int64">
1360 <summary>
1361 Performs an explicit conversion from <see cref="T:Newtonsoft.Json.Linq.JToken"/> to <see cref="T:System.Int64"/>.
1362 </summary>
1363 <param name="value">The value.</param>
1364 <returns>The result of the conversion.</returns>
1365 </member>
1366 <member name="M:Newtonsoft.Json.Linq.JToken.op_Explicit(Newtonsoft.Json.Linq.JToken)~System.Nullable{System.DateTime}">
1367 <summary>
1368 Performs an explicit conversion from <see cref="T:Newtonsoft.Json.Linq.JToken"/> to <see cref="T:System.Nullable`1"/>.
1369 </summary>
1370 <param name="value">The value.</param>
1371 <returns>The result of the conversion.</returns>
1372 </member>
1373 <member name="M:Newtonsoft.Json.Linq.JToken.op_Explicit(Newtonsoft.Json.Linq.JToken)~System.Nullable{System.Decimal}">
1374 <summary>
1375 Performs an explicit conversion from <see cref="T:Newtonsoft.Json.Linq.JToken"/> to <see cref="T:System.Nullable`1"/>.
1376 </summary>
1377 <param name="value">The value.</param>
1378 <returns>The result of the conversion.</returns>
1379 </member>
1380 <member name="M:Newtonsoft.Json.Linq.JToken.op_Explicit(Newtonsoft.Json.Linq.JToken)~System.Nullable{System.Double}">
1381 <summary>
1382 Performs an explicit conversion from <see cref="T:Newtonsoft.Json.Linq.JToken"/> to <see cref="T:System.Nullable`1"/>.
1383 </summary>
1384 <param name="value">The value.</param>
1385 <returns>The result of the conversion.</returns>
1386 </member>
1387 <member name="M:Newtonsoft.Json.Linq.JToken.op_Explicit(Newtonsoft.Json.Linq.JToken)~System.Int32">
1388 <summary>
1389 Performs an explicit conversion from <see cref="T:Newtonsoft.Json.Linq.JToken"/> to <see cref="T:System.Int32"/>.
1390 </summary>
1391 <param name="value">The value.</param>
1392 <returns>The result of the conversion.</returns>
1393 </member>
1394 <member name="M:Newtonsoft.Json.Linq.JToken.op_Explicit(Newtonsoft.Json.Linq.JToken)~System.Nullable{System.Int32}">
1395 <summary>
1396 Performs an explicit conversion from <see cref="T:Newtonsoft.Json.Linq.JToken"/> to <see cref="T:System.Nullable`1"/>.
1397 </summary>
1398 <param name="value">The value.</param>
1399 <returns>The result of the conversion.</returns>
1400 </member>
1401 <member name="M:Newtonsoft.Json.Linq.JToken.op_Explicit(Newtonsoft.Json.Linq.JToken)~System.DateTime">
1402 <summary>
1403 Performs an explicit conversion from <see cref="T:Newtonsoft.Json.Linq.JToken"/> to <see cref="T:System.DateTime"/>.
1404 </summary>
1405 <param name="value">The value.</param>
1406 <returns>The result of the conversion.</returns>
1407 </member>
1408 <member name="M:Newtonsoft.Json.Linq.JToken.op_Explicit(Newtonsoft.Json.Linq.JToken)~System.Nullable{System.Int64}">
1409 <summary>
1410 Performs an explicit conversion from <see cref="T:Newtonsoft.Json.Linq.JToken"/> to <see cref="T:System.Nullable`1"/>.
1411 </summary>
1412 <param name="value">The value.</param>
1413 <returns>The result of the conversion.</returns>
1414 </member>
1415 <member name="M:Newtonsoft.Json.Linq.JToken.op_Explicit(Newtonsoft.Json.Linq.JToken)~System.Nullable{System.Single}">
1416 <summary>
1417 Performs an explicit conversion from <see cref="T:Newtonsoft.Json.Linq.JToken"/> to <see cref="T:System.Nullable`1"/>.
1418 </summary>
1419 <param name="value">The value.</param>
1420 <returns>The result of the conversion.</returns>
1421 </member>
1422 <member name="M:Newtonsoft.Json.Linq.JToken.op_Explicit(Newtonsoft.Json.Linq.JToken)~System.Decimal">
1423 <summary>
1424 Performs an explicit conversion from <see cref="T:Newtonsoft.Json.Linq.JToken"/> to <see cref="T:System.Decimal"/>.
1425 </summary>
1426 <param name="value">The value.</param>
1427 <returns>The result of the conversion.</returns>
1428 </member>
1429 <member name="M:Newtonsoft.Json.Linq.JToken.op_Explicit(Newtonsoft.Json.Linq.JToken)~System.Nullable{System.UInt32}">
1430 <summary>
1431 Performs an explicit conversion from <see cref="T:Newtonsoft.Json.Linq.JToken"/> to <see cref="T:System.Nullable`1"/>.
1432 </summary>
1433 <param name="value">The value.</param>
1434 <returns>The result of the conversion.</returns>
1435 </member>
1436 <member name="M:Newtonsoft.Json.Linq.JToken.op_Explicit(Newtonsoft.Json.Linq.JToken)~System.Nullable{System.UInt64}">
1437 <summary>
1438 Performs an explicit conversion from <see cref="T:Newtonsoft.Json.Linq.JToken"/> to <see cref="T:System.Nullable`1"/>.
1439 </summary>
1440 <param name="value">The value.</param>
1441 <returns>The result of the conversion.</returns>
1442 </member>
1443 <member name="M:Newtonsoft.Json.Linq.JToken.op_Explicit(Newtonsoft.Json.Linq.JToken)~System.Double">
1444 <summary>
1445 Performs an explicit conversion from <see cref="T:Newtonsoft.Json.Linq.JToken"/> to <see cref="T:System.Double"/>.
1446 </summary>
1447 <param name="value">The value.</param>
1448 <returns>The result of the conversion.</returns>
1449 </member>
1450 <member name="M:Newtonsoft.Json.Linq.JToken.op_Explicit(Newtonsoft.Json.Linq.JToken)~System.Single">
1451 <summary>
1452 Performs an explicit conversion from <see cref="T:Newtonsoft.Json.Linq.JToken"/> to <see cref="T:System.Single"/>.
1453 </summary>
1454 <param name="value">The value.</param>
1455 <returns>The result of the conversion.</returns>
1456 </member>
1457 <member name="M:Newtonsoft.Json.Linq.JToken.op_Explicit(Newtonsoft.Json.Linq.JToken)~System.String">
1458 <summary>
1459 Performs an explicit conversion from <see cref="T:Newtonsoft.Json.Linq.JToken"/> to <see cref="T:System.String"/>.
1460 </summary>
1461 <param name="value">The value.</param>
1462 <returns>The result of the conversion.</returns>
1463 </member>
1464 <member name="M:Newtonsoft.Json.Linq.JToken.op_Explicit(Newtonsoft.Json.Linq.JToken)~System.UInt32">
1465 <summary>
1466 Performs an explicit conversion from <see cref="T:Newtonsoft.Json.Linq.JToken"/> to <see cref="T:System.UInt32"/>.
1467 </summary>
1468 <param name="value">The value.</param>
1469 <returns>The result of the conversion.</returns>
1470 </member>
1471 <member name="M:Newtonsoft.Json.Linq.JToken.op_Explicit(Newtonsoft.Json.Linq.JToken)~System.UInt64">
1472 <summary>
1473 Performs an explicit conversion from <see cref="T:Newtonsoft.Json.Linq.JToken"/> to <see cref="T:System.UInt64"/>.
1474 </summary>
1475 <param name="value">The value.</param>
1476 <returns>The result of the conversion.</returns>
1477 </member>
1478 <member name="M:Newtonsoft.Json.Linq.JToken.op_Explicit(Newtonsoft.Json.Linq.JToken)~System.Byte[]">
1479 <summary>
1480 Performs an explicit conversion from <see cref="T:Newtonsoft.Json.Linq.JToken"/> to <see cref="T:System.Byte[]"/>.
1481 </summary>
1482 <param name="value">The value.</param>
1483 <returns>The result of the conversion.</returns>
1484 </member>
1485 <member name="M:Newtonsoft.Json.Linq.JToken.op_Implicit(System.Boolean)~Newtonsoft.Json.Linq.JToken">
1486 <summary>
1487 Performs an implicit conversion from <see cref="T:System.Boolean"/> to <see cref="T:Newtonsoft.Json.Linq.JToken"/>.
1488 </summary>
1489 <param name="value">The value to create a <see cref="T:Newtonsoft.Json.Linq.JValue"/> from.</param>
1490 <returns>The <see cref="T:Newtonsoft.Json.Linq.JValue"/> initialized with the specified value.</returns>
1491 </member>
1492 <member name="M:Newtonsoft.Json.Linq.JToken.op_Implicit(System.Nullable{System.Boolean})~Newtonsoft.Json.Linq.JToken">
1493 <summary>
1494 Performs an implicit conversion from <see cref="T:System.Nullable`1"/> to <see cref="T:Newtonsoft.Json.Linq.JToken"/>.
1495 </summary>
1496 <param name="value">The value to create a <see cref="T:Newtonsoft.Json.Linq.JValue"/> from.</param>
1497 <returns>The <see cref="T:Newtonsoft.Json.Linq.JValue"/> initialized with the specified value.</returns>
1498 </member>
1499 <member name="M:Newtonsoft.Json.Linq.JToken.op_Implicit(System.Int64)~Newtonsoft.Json.Linq.JToken">
1500 <summary>
1501 Performs an implicit conversion from <see cref="T:System.Nullable`1"/> to <see cref="T:Newtonsoft.Json.Linq.JToken"/>.
1502 </summary>
1503 <param name="value">The value to create a <see cref="T:Newtonsoft.Json.Linq.JValue"/> from.</param>
1504 <returns>The <see cref="T:Newtonsoft.Json.Linq.JValue"/> initialized with the specified value.</returns>
1505 </member>
1506 <member name="M:Newtonsoft.Json.Linq.JToken.op_Implicit(System.Nullable{System.DateTime})~Newtonsoft.Json.Linq.JToken">
1507 <summary>
1508 Performs an implicit conversion from <see cref="T:System.Nullable`1"/> to <see cref="T:Newtonsoft.Json.Linq.JToken"/>.
1509 </summary>
1510 <param name="value">The value to create a <see cref="T:Newtonsoft.Json.Linq.JValue"/> from.</param>
1511 <returns>The <see cref="T:Newtonsoft.Json.Linq.JValue"/> initialized with the specified value.</returns>
1512 </member>
1513 <member name="M:Newtonsoft.Json.Linq.JToken.op_Implicit(System.Nullable{System.Decimal})~Newtonsoft.Json.Linq.JToken">
1514 <summary>
1515 Performs an implicit conversion from <see cref="T:System.Nullable`1"/> to <see cref="T:Newtonsoft.Json.Linq.JToken"/>.
1516 </summary>
1517 <param name="value">The value to create a <see cref="T:Newtonsoft.Json.Linq.JValue"/> from.</param>
1518 <returns>The <see cref="T:Newtonsoft.Json.Linq.JValue"/> initialized with the specified value.</returns>
1519 </member>
1520 <member name="M:Newtonsoft.Json.Linq.JToken.op_Implicit(System.Nullable{System.Double})~Newtonsoft.Json.Linq.JToken">
1521 <summary>
1522 Performs an implicit conversion from <see cref="T:System.Nullable`1"/> to <see cref="T:Newtonsoft.Json.Linq.JToken"/>.
1523 </summary>
1524 <param name="value">The value to create a <see cref="T:Newtonsoft.Json.Linq.JValue"/> from.</param>
1525 <returns>The <see cref="T:Newtonsoft.Json.Linq.JValue"/> initialized with the specified value.</returns>
1526 </member>
1527 <member name="M:Newtonsoft.Json.Linq.JToken.op_Implicit(System.UInt16)~Newtonsoft.Json.Linq.JToken">
1528 <summary>
1529 Performs an implicit conversion from <see cref="T:System.UInt16"/> to <see cref="T:Newtonsoft.Json.Linq.JToken"/>.
1530 </summary>
1531 <param name="value">The value to create a <see cref="T:Newtonsoft.Json.Linq.JValue"/> from.</param>
1532 <returns>The <see cref="T:Newtonsoft.Json.Linq.JValue"/> initialized with the specified value.</returns>
1533 </member>
1534 <member name="M:Newtonsoft.Json.Linq.JToken.op_Implicit(System.Int32)~Newtonsoft.Json.Linq.JToken">
1535 <summary>
1536 Performs an implicit conversion from <see cref="T:System.Int32"/> to <see cref="T:Newtonsoft.Json.Linq.JToken"/>.
1537 </summary>
1538 <param name="value">The value to create a <see cref="T:Newtonsoft.Json.Linq.JValue"/> from.</param>
1539 <returns>The <see cref="T:Newtonsoft.Json.Linq.JValue"/> initialized with the specified value.</returns>
1540 </member>
1541 <member name="M:Newtonsoft.Json.Linq.JToken.op_Implicit(System.Nullable{System.Int32})~Newtonsoft.Json.Linq.JToken">
1542 <summary>
1543 Performs an implicit conversion from <see cref="T:System.Nullable`1"/> to <see cref="T:Newtonsoft.Json.Linq.JToken"/>.
1544 </summary>
1545 <param name="value">The value to create a <see cref="T:Newtonsoft.Json.Linq.JValue"/> from.</param>
1546 <returns>The <see cref="T:Newtonsoft.Json.Linq.JValue"/> initialized with the specified value.</returns>
1547 </member>
1548 <member name="M:Newtonsoft.Json.Linq.JToken.op_Implicit(System.DateTime)~Newtonsoft.Json.Linq.JToken">
1549 <summary>
1550 Performs an implicit conversion from <see cref="T:System.DateTime"/> to <see cref="T:Newtonsoft.Json.Linq.JToken"/>.
1551 </summary>
1552 <param name="value">The value to create a <see cref="T:Newtonsoft.Json.Linq.JValue"/> from.</param>
1553 <returns>The <see cref="T:Newtonsoft.Json.Linq.JValue"/> initialized with the specified value.</returns>
1554 </member>
1555 <member name="M:Newtonsoft.Json.Linq.JToken.op_Implicit(System.Nullable{System.Int64})~Newtonsoft.Json.Linq.JToken">
1556 <summary>
1557 Performs an implicit conversion from <see cref="T:System.Nullable`1"/> to <see cref="T:Newtonsoft.Json.Linq.JToken"/>.
1558 </summary>
1559 <param name="value">The value to create a <see cref="T:Newtonsoft.Json.Linq.JValue"/> from.</param>
1560 <returns>The <see cref="T:Newtonsoft.Json.Linq.JValue"/> initialized with the specified value.</returns>
1561 </member>
1562 <member name="M:Newtonsoft.Json.Linq.JToken.op_Implicit(System.Nullable{System.Single})~Newtonsoft.Json.Linq.JToken">
1563 <summary>
1564 Performs an implicit conversion from <see cref="T:System.Nullable`1"/> to <see cref="T:Newtonsoft.Json.Linq.JToken"/>.
1565 </summary>
1566 <param name="value">The value to create a <see cref="T:Newtonsoft.Json.Linq.JValue"/> from.</param>
1567 <returns>The <see cref="T:Newtonsoft.Json.Linq.JValue"/> initialized with the specified value.</returns>
1568 </member>
1569 <member name="M:Newtonsoft.Json.Linq.JToken.op_Implicit(System.Decimal)~Newtonsoft.Json.Linq.JToken">
1570 <summary>
1571 Performs an implicit conversion from <see cref="T:System.Decimal"/> to <see cref="T:Newtonsoft.Json.Linq.JToken"/>.
1572 </summary>
1573 <param name="value">The value to create a <see cref="T:Newtonsoft.Json.Linq.JValue"/> from.</param>
1574 <returns>The <see cref="T:Newtonsoft.Json.Linq.JValue"/> initialized with the specified value.</returns>
1575 </member>
1576 <member name="M:Newtonsoft.Json.Linq.JToken.op_Implicit(System.Nullable{System.UInt16})~Newtonsoft.Json.Linq.JToken">
1577 <summary>
1578 Performs an implicit conversion from <see cref="T:System.Nullable`1"/> to <see cref="T:Newtonsoft.Json.Linq.JToken"/>.
1579 </summary>
1580 <param name="value">The value to create a <see cref="T:Newtonsoft.Json.Linq.JValue"/> from.</param>
1581 <returns>The <see cref="T:Newtonsoft.Json.Linq.JValue"/> initialized with the specified value.</returns>
1582 </member>
1583 <member name="M:Newtonsoft.Json.Linq.JToken.op_Implicit(System.Nullable{System.UInt32})~Newtonsoft.Json.Linq.JToken">
1584 <summary>
1585 Performs an implicit conversion from <see cref="T:System.Nullable`1"/> to <see cref="T:Newtonsoft.Json.Linq.JToken"/>.
1586 </summary>
1587 <param name="value">The value to create a <see cref="T:Newtonsoft.Json.Linq.JValue"/> from.</param>
1588 <returns>The <see cref="T:Newtonsoft.Json.Linq.JValue"/> initialized with the specified value.</returns>
1589 </member>
1590 <member name="M:Newtonsoft.Json.Linq.JToken.op_Implicit(System.Nullable{System.UInt64})~Newtonsoft.Json.Linq.JToken">
1591 <summary>
1592 Performs an implicit conversion from <see cref="T:System.Nullable`1"/> to <see cref="T:Newtonsoft.Json.Linq.JToken"/>.
1593 </summary>
1594 <param name="value">The value to create a <see cref="T:Newtonsoft.Json.Linq.JValue"/> from.</param>
1595 <returns>The <see cref="T:Newtonsoft.Json.Linq.JValue"/> initialized with the specified value.</returns>
1596 </member>
1597 <member name="M:Newtonsoft.Json.Linq.JToken.op_Implicit(System.Double)~Newtonsoft.Json.Linq.JToken">
1598 <summary>
1599 Performs an implicit conversion from <see cref="T:System.Double"/> to <see cref="T:Newtonsoft.Json.Linq.JToken"/>.
1600 </summary>
1601 <param name="value">The value to create a <see cref="T:Newtonsoft.Json.Linq.JValue"/> from.</param>
1602 <returns>The <see cref="T:Newtonsoft.Json.Linq.JValue"/> initialized with the specified value.</returns>
1603 </member>
1604 <member name="M:Newtonsoft.Json.Linq.JToken.op_Implicit(System.Single)~Newtonsoft.Json.Linq.JToken">
1605 <summary>
1606 Performs an implicit conversion from <see cref="T:System.Single"/> to <see cref="T:Newtonsoft.Json.Linq.JToken"/>.
1607 </summary>
1608 <param name="value">The value to create a <see cref="T:Newtonsoft.Json.Linq.JValue"/> from.</param>
1609 <returns>The <see cref="T:Newtonsoft.Json.Linq.JValue"/> initialized with the specified value.</returns>
1610 </member>
1611 <member name="M:Newtonsoft.Json.Linq.JToken.op_Implicit(System.String)~Newtonsoft.Json.Linq.JToken">
1612 <summary>
1613 Performs an implicit conversion from <see cref="T:System.String"/> to <see cref="T:Newtonsoft.Json.Linq.JToken"/>.
1614 </summary>
1615 <param name="value">The value to create a <see cref="T:Newtonsoft.Json.Linq.JValue"/> from.</param>
1616 <returns>The <see cref="T:Newtonsoft.Json.Linq.JValue"/> initialized with the specified value.</returns>
1617 </member>
1618 <member name="M:Newtonsoft.Json.Linq.JToken.op_Implicit(System.UInt32)~Newtonsoft.Json.Linq.JToken">
1619 <summary>
1620 Performs an implicit conversion from <see cref="T:System.UInt32"/> to <see cref="T:Newtonsoft.Json.Linq.JToken"/>.
1621 </summary>
1622 <param name="value">The value to create a <see cref="T:Newtonsoft.Json.Linq.JValue"/> from.</param>
1623 <returns>The <see cref="T:Newtonsoft.Json.Linq.JValue"/> initialized with the specified value.</returns>
1624 </member>
1625 <member name="M:Newtonsoft.Json.Linq.JToken.op_Implicit(System.UInt64)~Newtonsoft.Json.Linq.JToken">
1626 <summary>
1627 Performs an implicit conversion from <see cref="T:System.UInt64"/> to <see cref="T:Newtonsoft.Json.Linq.JToken"/>.
1628 </summary>
1629 <param name="value">The value to create a <see cref="T:Newtonsoft.Json.Linq.JValue"/> from.</param>
1630 <returns>The <see cref="T:Newtonsoft.Json.Linq.JValue"/> initialized with the specified value.</returns>
1631 </member>
1632 <member name="M:Newtonsoft.Json.Linq.JToken.op_Implicit(System.Byte[])~Newtonsoft.Json.Linq.JToken">
1633 <summary>
1634 Performs an implicit conversion from <see cref="T:System.Byte[]"/> to <see cref="T:Newtonsoft.Json.Linq.JToken"/>.
1635 </summary>
1636 <param name="value">The value to create a <see cref="T:Newtonsoft.Json.Linq.JValue"/> from.</param>
1637 <returns>The <see cref="T:Newtonsoft.Json.Linq.JValue"/> initialized with the specified value.</returns>
1638 </member>
1639 <member name="M:Newtonsoft.Json.Linq.JToken.CreateReader">
1640 <summary>
1641 Creates an <see cref="T:Newtonsoft.Json.JsonReader"/> for this token.
1642 </summary>
1643 <returns>An <see cref="T:Newtonsoft.Json.JsonReader"/> that can be used to read this token and its descendants.</returns>
1644 </member>
1645 <member name="M:Newtonsoft.Json.Linq.JToken.FromObject(System.Object)">
1646 <summary>
1647 Creates a <see cref="T:Newtonsoft.Json.Linq.JToken"/> from an object.
1648 </summary>
1649 <param name="o">The object that will be used to create <see cref="T:Newtonsoft.Json.Linq.JToken"/>.</param>
1650 <returns>A <see cref="T:Newtonsoft.Json.Linq.JToken"/> with the value of the specified object</returns>
1651 </member>
1652 <member name="M:Newtonsoft.Json.Linq.JToken.FromObject(System.Object,Newtonsoft.Json.JsonSerializer)">
1653 <summary>
1654 Creates a <see cref="T:Newtonsoft.Json.Linq.JToken"/> from an object using the specified <see cref="T:Newtonsoft.Json.JsonSerializer"/>.
1655 </summary>
1656 <param name="o">The object that will be used to create <see cref="T:Newtonsoft.Json.Linq.JToken"/>.</param>
1657 <param name="jsonSerializer">The <see cref="T:Newtonsoft.Json.JsonSerializer"/> that will be used when reading the object.</param>
1658 <returns>A <see cref="T:Newtonsoft.Json.Linq.JToken"/> with the value of the specified object</returns>
1659 </member>
1660 <member name="M:Newtonsoft.Json.Linq.JToken.ReadFrom(Newtonsoft.Json.JsonReader)">
1661 <summary>
1662 Creates a <see cref="T:Newtonsoft.Json.Linq.JToken"/> from a <see cref="T:Newtonsoft.Json.JsonReader"/>.
1663 </summary>
1664 <param name="reader">An <see cref="T:Newtonsoft.Json.JsonReader"/> positioned at the token to read into this <see cref="T:Newtonsoft.Json.Linq.JToken"/>.</param>
1665 <returns>
1666 An <see cref="T:Newtonsoft.Json.Linq.JToken"/> that contains the token and its descendant tokens
1667 that were read from the reader. The runtime type of the token is determined
1668 by the token type of the first token encountered in the reader.
1669 </returns>
1670 </member>
1671 <member name="M:Newtonsoft.Json.Linq.JToken.SelectToken(System.String)">
1672 <summary>
1673 Selects the token that matches the object path.
1674 </summary>
1675 <param name="path">
1676 The object path from the current <see cref="T:Newtonsoft.Json.Linq.JToken"/> to the <see cref="T:Newtonsoft.Json.Linq.JToken"/>
1677 to be returned. This must be a string of property names or array indexes separated
1678 by periods, such as <code>Tables[0].DefaultView[0].Price</code> in C# or
1679 <code>Tables(0).DefaultView(0).Price</code> in Visual Basic.
1680 </param>
1681 <returns>The <see cref="T:Newtonsoft.Json.Linq.JToken"/> that matches the object path or a null reference if no matching token is found.</returns>
1682 </member>
1683 <member name="M:Newtonsoft.Json.Linq.JToken.SelectToken(System.String,System.Boolean)">
1684 <summary>
1685 Selects the token that matches the object path.
1686 </summary>
1687 <param name="path">
1688 The object path from the current <see cref="T:Newtonsoft.Json.Linq.JToken"/> to the <see cref="T:Newtonsoft.Json.Linq.JToken"/>
1689 to be returned. This must be a string of property names or array indexes separated
1690 by periods, such as <code>Tables[0].DefaultView[0].Price</code> in C# or
1691 <code>Tables(0).DefaultView(0).Price</code> in Visual Basic.
1692 </param>
1693 <param name="errorWhenNoMatch">A flag to indicate whether an error should be thrown if no token is found.</param>
1694 <returns>The <see cref="T:Newtonsoft.Json.Linq.JToken"/> that matches the object path.</returns>
1695 </member>
1696 <member name="P:Newtonsoft.Json.Linq.JToken.EqualityComparer">
1697 <summary>
1698 Gets a comparer that can compare two tokens for value equality.
1699 </summary>
1700 <value>A <see cref="T:Newtonsoft.Json.Linq.JTokenEqualityComparer"/> that can compare two nodes for value equality.</value>
1701 </member>
1702 <member name="P:Newtonsoft.Json.Linq.JToken.Parent">
1703 <summary>
1704 Gets or sets the parent.
1705 </summary>
1706 <value>The parent.</value>
1707 </member>
1708 <member name="P:Newtonsoft.Json.Linq.JToken.Root">
1709 <summary>
1710 Gets the root <see cref="T:Newtonsoft.Json.Linq.JToken"/> of this <see cref="T:Newtonsoft.Json.Linq.JToken"/>.
1711 </summary>
1712 <value>The root <see cref="T:Newtonsoft.Json.Linq.JToken"/> of this <see cref="T:Newtonsoft.Json.Linq.JToken"/>.</value>
1713 </member>
1714 <member name="P:Newtonsoft.Json.Linq.JToken.Type">
1715 <summary>
1716 Gets the node type for this <see cref="T:Newtonsoft.Json.Linq.JToken"/>.
1717 </summary>
1718 <value>The type.</value>
1719 </member>
1720 <member name="P:Newtonsoft.Json.Linq.JToken.HasValues">
1721 <summary>
1722 Gets a value indicating whether this token has childen tokens.
1723 </summary>
1724 <value>
1725 <c>true</c> if this token has child values; otherwise, <c>false</c>.
1726 </value>
1727 </member>
1728 <member name="P:Newtonsoft.Json.Linq.JToken.Next">
1729 <summary>
1730 Gets the next sibling token of this node.
1731 </summary>
1732 <value>The <see cref="T:Newtonsoft.Json.Linq.JToken"/> that contains the next sibling token.</value>
1733 </member>
1734 <member name="P:Newtonsoft.Json.Linq.JToken.Previous">
1735 <summary>
1736 Gets the previous sibling token of this node.
1737 </summary>
1738 <value>The <see cref="T:Newtonsoft.Json.Linq.JToken"/> that contains the previous sibling token.</value>
1739 </member>
1740 <member name="P:Newtonsoft.Json.Linq.JToken.Item(System.Object)">
1741 <summary>
1742 Gets the <see cref="T:Newtonsoft.Json.Linq.JToken"/> with the specified key.
1743 </summary>
1744 <value>The <see cref="T:Newtonsoft.Json.Linq.JToken"/> with the specified key.</value>
1745 </member>
1746 <member name="P:Newtonsoft.Json.Linq.JToken.First">
1747 <summary>
1748 Get the first child token of this token.
1749 </summary>
1750 <value>A <see cref="T:Newtonsoft.Json.Linq.JToken"/> containing the first child token of the <see cref="T:Newtonsoft.Json.Linq.JToken"/>.</value>
1751 </member>
1752 <member name="P:Newtonsoft.Json.Linq.JToken.Last">
1753 <summary>
1754 Get the last child token of this token.
1755 </summary>
1756 <value>A <see cref="T:Newtonsoft.Json.Linq.JToken"/> containing the last child token of the <see cref="T:Newtonsoft.Json.Linq.JToken"/>.</value>
1757 </member>
1758 <member name="M:Newtonsoft.Json.Linq.JValue.#ctor(Newtonsoft.Json.Linq.JValue)">
1759 <summary>
1760 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Linq.JValue"/> class from another <see cref="T:Newtonsoft.Json.Linq.JValue"/> object.
1761 </summary>
1762 <param name="other">A <see cref="T:Newtonsoft.Json.Linq.JValue"/> object to copy from.</param>
1763 </member>
1764 <member name="M:Newtonsoft.Json.Linq.JValue.#ctor(System.Int64)">
1765 <summary>
1766 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Linq.JValue"/> class with the given value.
1767 </summary>
1768 <param name="value">The value.</param>
1769 </member>
1770 <member name="M:Newtonsoft.Json.Linq.JValue.#ctor(System.UInt64)">
1771 <summary>
1772 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Linq.JValue"/> class with the given value.
1773 </summary>
1774 <param name="value">The value.</param>
1775 </member>
1776 <member name="M:Newtonsoft.Json.Linq.JValue.#ctor(System.Double)">
1777 <summary>
1778 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Linq.JValue"/> class with the given value.
1779 </summary>
1780 <param name="value">The value.</param>
1781 </member>
1782 <member name="M:Newtonsoft.Json.Linq.JValue.#ctor(System.DateTime)">
1783 <summary>
1784 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Linq.JValue"/> class with the given value.
1785 </summary>
1786 <param name="value">The value.</param>
1787 </member>
1788 <member name="M:Newtonsoft.Json.Linq.JValue.#ctor(System.Boolean)">
1789 <summary>
1790 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Linq.JValue"/> class with the given value.
1791 </summary>
1792 <param name="value">The value.</param>
1793 </member>
1794 <member name="M:Newtonsoft.Json.Linq.JValue.#ctor(System.String)">
1795 <summary>
1796 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Linq.JValue"/> class with the given value.
1797 </summary>
1798 <param name="value">The value.</param>
1799 </member>
1800 <member name="M:Newtonsoft.Json.Linq.JValue.#ctor(System.Object)">
1801 <summary>
1802 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Linq.JValue"/> class with the given value.
1803 </summary>
1804 <param name="value">The value.</param>
1805 </member>
1806 <member name="M:Newtonsoft.Json.Linq.JValue.CreateComment(System.String)">
1807 <summary>
1808 Creates a <see cref="T:Newtonsoft.Json.Linq.JValue"/> comment with the given value.
1809 </summary>
1810 <param name="value">The value.</param>
1811 <returns>A <see cref="T:Newtonsoft.Json.Linq.JValue"/> comment with the given value.</returns>
1812 </member>
1813 <member name="M:Newtonsoft.Json.Linq.JValue.CreateString(System.String)">
1814 <summary>
1815 Creates a <see cref="T:Newtonsoft.Json.Linq.JValue"/> string with the given value.
1816 </summary>
1817 <param name="value">The value.</param>
1818 <returns>A <see cref="T:Newtonsoft.Json.Linq.JValue"/> string with the given value.</returns>
1819 </member>
1820 <member name="M:Newtonsoft.Json.Linq.JValue.WriteTo(Newtonsoft.Json.JsonWriter,Newtonsoft.Json.JsonConverter[])">
1821 <summary>
1822 Writes this token to a <see cref="T:Newtonsoft.Json.JsonWriter"/>.
1823 </summary>
1824 <param name="writer">A <see cref="T:Newtonsoft.Json.JsonWriter"/> into which this method will write.</param>
1825 <param name="converters">A collection of <see cref="T:Newtonsoft.Json.JsonConverter"/> which will be used when writing the token.</param>
1826 </member>
1827 <member name="M:Newtonsoft.Json.Linq.JValue.Equals(Newtonsoft.Json.Linq.JValue)">
1828 <summary>
1829 Indicates whether the current object is equal to another object of the same type.
1830 </summary>
1831 <returns>
1832 true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.
1833 </returns>
1834 <param name="other">An object to compare with this object.</param>
1835 </member>
1836 <member name="M:Newtonsoft.Json.Linq.JValue.Equals(System.Object)">
1837 <summary>
1838 Determines whether the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>.
1839 </summary>
1840 <param name="obj">The <see cref="T:System.Object"/> to compare with the current <see cref="T:System.Object"/>.</param>
1841 <returns>
1842 true if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, false.
1843 </returns>
1844 <exception cref="T:System.NullReferenceException">
1845 The <paramref name="obj"/> parameter is null.
1846 </exception>
1847 </member>
1848 <member name="M:Newtonsoft.Json.Linq.JValue.GetHashCode">
1849 <summary>
1850 Serves as a hash function for a particular type.
1851 </summary>
1852 <returns>
1853 A hash code for the current <see cref="T:System.Object"/>.
1854 </returns>
1855 </member>
1856 <member name="P:Newtonsoft.Json.Linq.JValue.HasValues">
1857 <summary>
1858 Gets a value indicating whether this token has childen tokens.
1859 </summary>
1860 <value>
1861 <c>true</c> if this token has child values; otherwise, <c>false</c>.
1862 </value>
1863 </member>
1864 <member name="P:Newtonsoft.Json.Linq.JValue.Type">
1865 <summary>
1866 Gets the node type for this <see cref="T:Newtonsoft.Json.Linq.JToken"/>.
1867 </summary>
1868 <value>The type.</value>
1869 </member>
1870 <member name="P:Newtonsoft.Json.Linq.JValue.Value">
1871 <summary>
1872 Gets or sets the underlying token value.
1873 </summary>
1874 <value>The underlying token value.</value>
1875 </member>
1876 <member name="M:Newtonsoft.Json.Linq.JRaw.#ctor(Newtonsoft.Json.Linq.JRaw)">
1877 <summary>
1878 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Linq.JRaw"/> class from another <see cref="T:Newtonsoft.Json.Linq.JRaw"/> object.
1879 </summary>
1880 <param name="other">A <see cref="T:Newtonsoft.Json.Linq.JRaw"/> object to copy from.</param>
1881 </member>
1882 <member name="M:Newtonsoft.Json.Linq.JRaw.#ctor(System.String)">
1883 <summary>
1884 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Linq.JRaw"/> class.
1885 </summary>
1886 <param name="rawJson">The raw json.</param>
1887 </member>
1888 <member name="M:Newtonsoft.Json.Linq.JRaw.Create(Newtonsoft.Json.JsonReader)">
1889 <summary>
1890 Creates an instance of <see cref="T:Newtonsoft.Json.Linq.JRaw"/> with the content of the reader's current token.
1891 </summary>
1892 <param name="reader">The reader.</param>
1893 <returns>An instance of <see cref="T:Newtonsoft.Json.Linq.JRaw"/> with the content of the reader's current token.</returns>
1894 </member>
1895 <member name="T:Newtonsoft.Json.Required">
1896 <summary>
1897 Indicating whether a property is required.
1898 </summary>
1899 </member>
1900 <member name="F:Newtonsoft.Json.Required.Default">
1901 <summary>
1902 The property is not required. The default state.
1903 </summary>
1904 </member>
1905 <member name="F:Newtonsoft.Json.Required.AllowNull">
1906 <summary>
1907 The property must be defined in JSON but can be a null value.
1908 </summary>
1909 </member>
1910 <member name="F:Newtonsoft.Json.Required.Always">
1911 <summary>
1912 The property must be defined in JSON and cannot be a null value.
1913 </summary>
1914 </member>
1915 <member name="T:Newtonsoft.Json.Serialization.IReferenceResolver">
1916 <summary>
1917 Used to resolve references when serializing and deserializing JSON by the <see cref="T:Newtonsoft.Json.JsonSerializer"/>.
1918 </summary>
1919 </member>
1920 <member name="M:Newtonsoft.Json.Serialization.IReferenceResolver.ResolveReference(System.String)">
1921 <summary>
1922 Resolves a reference to its object.
1923 </summary>
1924 <param name="reference">The reference to resolve.</param>
1925 <returns>The object that</returns>
1926 </member>
1927 <member name="M:Newtonsoft.Json.Serialization.IReferenceResolver.GetReference(System.Object)">
1928 <summary>
1929 Gets the reference for the sepecified object.
1930 </summary>
1931 <param name="value">The object to get a reference for.</param>
1932 <returns>The reference to the object.</returns>
1933 </member>
1934 <member name="M:Newtonsoft.Json.Serialization.IReferenceResolver.IsReferenced(System.Object)">
1935 <summary>
1936 Determines whether the specified object is referenced.
1937 </summary>
1938 <param name="value">The object to test for a reference.</param>
1939 <returns>
1940 <c>true</c> if the specified object is referenced; otherwise, <c>false</c>.
1941 </returns>
1942 </member>
1943 <member name="M:Newtonsoft.Json.Serialization.IReferenceResolver.AddReference(System.String,System.Object)">
1944 <summary>
1945 Adds a reference to the specified object.
1946 </summary>
1947 <param name="reference">The reference.</param>
1948 <param name="value">The object to reference.</param>
1949 </member>
1950 <member name="T:Newtonsoft.Json.PreserveReferencesHandling">
1951 <summary>
1952 Specifies reference handling options for the <see cref="T:Newtonsoft.Json.JsonSerializer"/>.
1953 </summary>
1954 </member>
1955 <member name="F:Newtonsoft.Json.PreserveReferencesHandling.None">
1956 <summary>
1957 Do not preserve references when serializing types.
1958 </summary>
1959 </member>
1960 <member name="F:Newtonsoft.Json.PreserveReferencesHandling.Objects">
1961 <summary>
1962 Preserve references when serializing into a JSON object structure.
1963 </summary>
1964 </member>
1965 <member name="F:Newtonsoft.Json.PreserveReferencesHandling.Arrays">
1966 <summary>
1967 Preserve references when serializing into a JSON array structure.
1968 </summary>
1969 </member>
1970 <member name="F:Newtonsoft.Json.PreserveReferencesHandling.All">
1971 <summary>
1972 Preserve references when serializing.
1973 </summary>
1974 </member>
1975 <member name="T:Newtonsoft.Json.JsonArrayAttribute">
1976 <summary>
1977 Instructs the <see cref="T:Newtonsoft.Json.JsonSerializer"/> how to serialize the collection.
1978 </summary>
1979 </member>
1980 <member name="T:Newtonsoft.Json.JsonContainerAttribute">
1981 <summary>
1982 Instructs the <see cref="T:Newtonsoft.Json.JsonSerializer"/> how to serialize the object.
1983 </summary>
1984 </member>
1985 <member name="M:Newtonsoft.Json.JsonContainerAttribute.#ctor">
1986 <summary>
1987 Initializes a new instance of the <see cref="T:Newtonsoft.Json.JsonContainerAttribute"/> class.
1988 </summary>
1989 </member>
1990 <member name="M:Newtonsoft.Json.JsonContainerAttribute.#ctor(System.String)">
1991 <summary>
1992 Initializes a new instance of the <see cref="T:Newtonsoft.Json.JsonContainerAttribute"/> class with the specified container Id.
1993 </summary>
1994 <param name="id">The container Id.</param>
1995 </member>
1996 <member name="P:Newtonsoft.Json.JsonContainerAttribute.Id">
1997 <summary>
1998 Gets or sets the id.
1999 </summary>
2000 <value>The id.</value>
2001 </member>
2002 <member name="P:Newtonsoft.Json.JsonContainerAttribute.Title">
2003 <summary>
2004 Gets or sets the title.
2005 </summary>
2006 <value>The title.</value>
2007 </member>
2008 <member name="P:Newtonsoft.Json.JsonContainerAttribute.Description">
2009 <summary>
2010 Gets or sets the description.
2011 </summary>
2012 <value>The description.</value>
2013 </member>
2014 <member name="P:Newtonsoft.Json.JsonContainerAttribute.IsReference">
2015 <summary>
2016 Gets or sets a value that indicates whether to preserve object reference data.
2017 </summary>
2018 <value>
2019 <c>true</c> to keep object reference; otherwise, <c>false</c>. The default is <c>false</c>.
2020 </value>
2021 </member>
2022 <member name="M:Newtonsoft.Json.JsonArrayAttribute.#ctor">
2023 <summary>
2024 Initializes a new instance of the <see cref="T:Newtonsoft.Json.JsonArrayAttribute"/> class.
2025 </summary>
2026 </member>
2027 <member name="M:Newtonsoft.Json.JsonArrayAttribute.#ctor(System.Boolean)">
2028 <summary>
2029 Initializes a new instance of the <see cref="T:Newtonsoft.Json.JsonObjectAttribute"/> class with a flag indicating whether the array can contain null items
2030 </summary>
2031 <param name="allowNullItems">A flag indicating whether the array can contain null items.</param>
2032 </member>
2033 <member name="M:Newtonsoft.Json.JsonArrayAttribute.#ctor(System.String)">
2034 <summary>
2035 Initializes a new instance of the <see cref="T:Newtonsoft.Json.JsonArrayAttribute"/> class with the specified container Id.
2036 </summary>
2037 <param name="id">The container Id.</param>
2038 </member>
2039 <member name="P:Newtonsoft.Json.JsonArrayAttribute.AllowNullItems">
2040 <summary>
2041 Gets or sets a value indicating whether null items are allowed in the collection.
2042 </summary>
2043 <value><c>true</c> if null items are allowed in the collection; otherwise, <c>false</c>.</value>
2044 </member>
2045 <member name="T:Newtonsoft.Json.DefaultValueHandling">
2046 <summary>
2047 Specifies default value handling options for the <see cref="T:Newtonsoft.Json.JsonSerializer"/>.
2048 </summary>
2049 </member>
2050 <member name="F:Newtonsoft.Json.DefaultValueHandling.Include">
2051 <summary>
2052 Include null values when serializing and deserializing objects.
2053 </summary>
2054 </member>
2055 <member name="F:Newtonsoft.Json.DefaultValueHandling.Ignore">
2056 <summary>
2057 Ignore null values when serializing and deserializing objects.
2058 </summary>
2059 </member>
2060 <member name="T:Newtonsoft.Json.JsonConverterAttribute">
2061 <summary>
2062 Instructs the <see cref="T:Newtonsoft.Json.JsonSerializer"/> to use the specified <see cref="T:Newtonsoft.Json.JsonConverter"/> when serializing the member or class.
2063 </summary>
2064 </member>
2065 <member name="M:Newtonsoft.Json.JsonConverterAttribute.#ctor(System.Type)">
2066 <summary>
2067 Initializes a new instance of the <see cref="T:Newtonsoft.Json.JsonConverterAttribute"/> class.
2068 </summary>
2069 <param name="converterType">Type of the converter.</param>
2070 </member>
2071 <member name="P:Newtonsoft.Json.JsonConverterAttribute.ConverterType">
2072 <summary>
2073 Gets the type of the converter.
2074 </summary>
2075 <value>The type of the converter.</value>
2076 </member>
2077 <member name="T:Newtonsoft.Json.JsonObjectAttribute">
2078 <summary>
2079 Instructs the <see cref="T:Newtonsoft.Json.JsonSerializer"/> how to serialize the object.
2080 </summary>
2081 </member>
2082 <member name="M:Newtonsoft.Json.JsonObjectAttribute.#ctor">
2083 <summary>
2084 Initializes a new instance of the <see cref="T:Newtonsoft.Json.JsonObjectAttribute"/> class.
2085 </summary>
2086 </member>
2087 <member name="M:Newtonsoft.Json.JsonObjectAttribute.#ctor(Newtonsoft.Json.MemberSerialization)">
2088 <summary>
2089 Initializes a new instance of the <see cref="T:Newtonsoft.Json.JsonObjectAttribute"/> class with the specified member serialization.
2090 </summary>
2091 <param name="memberSerialization">The member serialization.</param>
2092 </member>
2093 <member name="M:Newtonsoft.Json.JsonObjectAttribute.#ctor(System.String)">
2094 <summary>
2095 Initializes a new instance of the <see cref="T:Newtonsoft.Json.JsonObjectAttribute"/> class with the specified container Id.
2096 </summary>
2097 <param name="id">The container Id.</param>
2098 </member>
2099 <member name="P:Newtonsoft.Json.JsonObjectAttribute.MemberSerialization">
2100 <summary>
2101 Gets or sets the member serialization.
2102 </summary>
2103 <value>The member serialization.</value>
2104 </member>
2105 <member name="T:Newtonsoft.Json.JsonSerializerSettings">
2106 <summary>
2107 Specifies the settings on a <see cref="T:Newtonsoft.Json.JsonSerializer"/> object.
2108 </summary>
2109 </member>
2110 <member name="M:Newtonsoft.Json.JsonSerializerSettings.#ctor">
2111 <summary>
2112 Initializes a new instance of the <see cref="T:Newtonsoft.Json.JsonSerializerSettings"/> class.
2113 </summary>
2114 </member>
2115 <member name="P:Newtonsoft.Json.JsonSerializerSettings.ReferenceLoopHandling">
2116 <summary>
2117 Gets or sets how reference loops (e.g. a class referencing itself) is handled.
2118 </summary>
2119 <value>Reference loop handling.</value>
2120 </member>
2121 <member name="P:Newtonsoft.Json.JsonSerializerSettings.MissingMemberHandling">
2122 <summary>
2123 Gets or sets how missing members (e.g. JSON contains a property that isn't a member on the object) are handled during deserialization.
2124 </summary>
2125 <value>Missing member handling.</value>
2126 </member>
2127 <member name="P:Newtonsoft.Json.JsonSerializerSettings.ObjectCreationHandling">
2128 <summary>
2129 Gets or sets how objects are created during deserialization.
2130 </summary>
2131 <value>The object creation handling.</value>
2132 </member>
2133 <member name="P:Newtonsoft.Json.JsonSerializerSettings.NullValueHandling">
2134 <summary>
2135 Gets or sets how null values are handled during serialization and deserialization.
2136 </summary>
2137 <value>Null value handling.</value>
2138 </member>
2139 <member name="P:Newtonsoft.Json.JsonSerializerSettings.DefaultValueHandling">
2140 <summary>
2141 Gets or sets how null default are handled during serialization and deserialization.
2142 </summary>
2143 <value>The default value handling.</value>
2144 </member>
2145 <member name="P:Newtonsoft.Json.JsonSerializerSettings.Converters">
2146 <summary>
2147 Gets or sets a collection <see cref="T:Newtonsoft.Json.JsonConverter"/> that will be used during serialization.
2148 </summary>
2149 <value>The converters.</value>
2150 </member>
2151 <member name="P:Newtonsoft.Json.JsonSerializerSettings.PreserveReferencesHandling">
2152 <summary>
2153 Gets or sets how object references are preserved by the serializer.
2154 </summary>
2155 <value>The preserve references handling.</value>
2156 </member>
2157 <member name="P:Newtonsoft.Json.JsonSerializerSettings.TypeNameHandling">
2158 <summary>
2159 Gets or sets how type name writing and reading is handled by the serializer.
2160 </summary>
2161 <value>The type name handling.</value>
2162 </member>
2163 <member name="P:Newtonsoft.Json.JsonSerializerSettings.ConstructorHandling">
2164 <summary>
2165 Gets or sets how constructors are used during deserialization.
2166 </summary>
2167 <value>The constructor handling.</value>
2168 </member>
2169 <member name="P:Newtonsoft.Json.JsonSerializerSettings.ContractResolver">
2170 <summary>
2171 Gets or sets the contract resolver used by the serializer when
2172 serializing .NET objects to JSON and vice versa.
2173 </summary>
2174 <value>The contract resolver.</value>
2175 </member>
2176 <member name="P:Newtonsoft.Json.JsonSerializerSettings.ReferenceResolver">
2177 <summary>
2178 Gets or sets the <see cref="T:Newtonsoft.Json.Serialization.IReferenceResolver"/> used by the serializer when resolving references.
2179 </summary>
2180 <value>The reference resolver.</value>
2181 </member>
2182 <member name="P:Newtonsoft.Json.JsonSerializerSettings.Binder">
2183 <summary>
2184 Gets or sets the <see cref="T:System.Runtime.Serialization.SerializationBinder"/> used by the serializer when resolving type names.
2185 </summary>
2186 <value>The binder.</value>
2187 </member>
2188 <member name="P:Newtonsoft.Json.JsonSerializerSettings.Error">
2189 <summary>
2190 Gets or sets the error handler called during serialization and deserialization.
2191 </summary>
2192 <value>The error handler called during serialization and deserialization.</value>
2193 </member>
2194 <member name="P:Newtonsoft.Json.JsonSerializerSettings.Context">
2195 <summary>
2196 Gets or sets the <see cref="T:System.Runtime.Serialization.StreamingContext"/> used by the serializer when invoking serialization callback methods.
2197 </summary>
2198 <value>The context.</value>
2199 </member>
2200 <member name="T:Newtonsoft.Json.JsonValidatingReader">
2201 <summary>
2202 Represents a reader that provides <see cref="T:Newtonsoft.Json.Schema.JsonSchema"/> validation.
2203 </summary>
2204 </member>
2205 <member name="M:Newtonsoft.Json.JsonValidatingReader.#ctor(Newtonsoft.Json.JsonReader)">
2206 <summary>
2207 Initializes a new instance of the <see cref="T:Newtonsoft.Json.JsonValidatingReader"/> class that
2208 validates the content returned from the given <see cref="T:Newtonsoft.Json.JsonReader"/>.
2209 </summary>
2210 <param name="reader">The <see cref="T:Newtonsoft.Json.JsonReader"/> to read from while validating.</param>
2211 </member>
2212 <member name="M:Newtonsoft.Json.JsonValidatingReader.ReadAsBytes">
2213 <summary>
2214 Reads the next JSON token from the stream as a <see cref="T:Byte[]"/>.
2215 </summary>
2216 <returns>
2217 A <see cref="T:Byte[]"/> or a null reference if the next JSON token is null.
2218 </returns>
2219 </member>
2220 <member name="M:Newtonsoft.Json.JsonValidatingReader.Read">
2221 <summary>
2222 Reads the next JSON token from the stream.
2223 </summary>
2224 <returns>
2225 true if the next token was read successfully; false if there are no more tokens to read.
2226 </returns>
2227 </member>
2228 <member name="E:Newtonsoft.Json.JsonValidatingReader.ValidationEventHandler">
2229 <summary>
2230 Sets an event handler for receiving schema validation errors.
2231 </summary>
2232 </member>
2233 <member name="P:Newtonsoft.Json.JsonValidatingReader.Value">
2234 <summary>
2235 Gets the text value of the current Json token.
2236 </summary>
2237 <value></value>
2238 </member>
2239 <member name="P:Newtonsoft.Json.JsonValidatingReader.Depth">
2240 <summary>
2241 Gets the depth of the current token in the JSON document.
2242 </summary>
2243 <value>The depth of the current token in the JSON document.</value>
2244 </member>
2245 <member name="P:Newtonsoft.Json.JsonValidatingReader.QuoteChar">
2246 <summary>
2247 Gets the quotation mark character used to enclose the value of a string.
2248 </summary>
2249 <value></value>
2250 </member>
2251 <member name="P:Newtonsoft.Json.JsonValidatingReader.TokenType">
2252 <summary>
2253 Gets the type of the current Json token.
2254 </summary>
2255 <value></value>
2256 </member>
2257 <member name="P:Newtonsoft.Json.JsonValidatingReader.ValueType">
2258 <summary>
2259 Gets The Common Language Runtime (CLR) type for the current Json token.
2260 </summary>
2261 <value></value>
2262 </member>
2263 <member name="P:Newtonsoft.Json.JsonValidatingReader.Schema">
2264 <summary>
2265 Gets or sets the schema.
2266 </summary>
2267 <value>The schema.</value>
2268 </member>
2269 <member name="P:Newtonsoft.Json.JsonValidatingReader.Reader">
2270 <summary>
2271 Gets the <see cref="T:Newtonsoft.Json.JsonReader"/> used to construct this <see cref="T:Newtonsoft.Json.JsonValidatingReader"/>.
2272 </summary>
2273 <value>The <see cref="T:Newtonsoft.Json.JsonReader"/> specified in the constructor.</value>
2274 </member>
2275 <member name="T:Newtonsoft.Json.Linq.JTokenEqualityComparer">
2276 <summary>
2277 Compares tokens to determine whether they are equal.
2278 </summary>
2279 </member>
2280 <member name="M:Newtonsoft.Json.Linq.JTokenEqualityComparer.Equals(Newtonsoft.Json.Linq.JToken,Newtonsoft.Json.Linq.JToken)">
2281 <summary>
2282 Determines whether the specified objects are equal.
2283 </summary>
2284 <param name="x">The first object of type <paramref name="T"/> to compare.</param>
2285 <param name="y">The second object of type <paramref name="T"/> to compare.</param>
2286 <returns>
2287 true if the specified objects are equal; otherwise, false.
2288 </returns>
2289 </member>
2290 <member name="M:Newtonsoft.Json.Linq.JTokenEqualityComparer.GetHashCode(Newtonsoft.Json.Linq.JToken)">
2291 <summary>
2292 Returns a hash code for the specified object.
2293 </summary>
2294 <param name="obj">The <see cref="T:System.Object"/> for which a hash code is to be returned.</param>
2295 <returns>A hash code for the specified object.</returns>
2296 <exception cref="T:System.ArgumentNullException">The type of <paramref name="obj"/> is a reference type and <paramref name="obj"/> is null.</exception>
2297 </member>
2298 <member name="T:Newtonsoft.Json.MemberSerialization">
2299 <summary>
2300 Specifies the member serialization options for the <see cref="T:Newtonsoft.Json.JsonSerializer"/>.
2301 </summary>
2302 </member>
2303 <member name="F:Newtonsoft.Json.MemberSerialization.OptOut">
2304 <summary>
2305 All members are serialized by default. Members can be excluded using the <see cref="T:Newtonsoft.Json.JsonIgnoreAttribute"/>.
2306 </summary>
2307 </member>
2308 <member name="F:Newtonsoft.Json.MemberSerialization.OptIn">
2309 <summary>
2310 Only members must be marked with the <see cref="T:Newtonsoft.Json.JsonPropertyAttribute"/> are serialized.
2311 </summary>
2312 </member>
2313 <member name="T:Newtonsoft.Json.ObjectCreationHandling">
2314 <summary>
2315 Specifies how object creation is handled by the <see cref="T:Newtonsoft.Json.JsonSerializer"/>.
2316 </summary>
2317 </member>
2318 <member name="F:Newtonsoft.Json.ObjectCreationHandling.Auto">
2319 <summary>
2320 Reuse existing objects, create new objects when needed.
2321 </summary>
2322 </member>
2323 <member name="F:Newtonsoft.Json.ObjectCreationHandling.Reuse">
2324 <summary>
2325 Only reuse existing objects.
2326 </summary>
2327 </member>
2328 <member name="F:Newtonsoft.Json.ObjectCreationHandling.Replace">
2329 <summary>
2330 Always create new objects.
2331 </summary>
2332 </member>
2333 <member name="T:Newtonsoft.Json.Converters.IsoDateTimeConverter">
2334 <summary>
2335 Converts a <see cref="T:System.DateTime"/> to and from the ISO 8601 date format (e.g. 2008-04-12T12:53Z).
2336 </summary>
2337 </member>
2338 <member name="M:Newtonsoft.Json.Converters.IsoDateTimeConverter.WriteJson(Newtonsoft.Json.JsonWriter,System.Object,Newtonsoft.Json.JsonSerializer)">
2339 <summary>
2340 Writes the JSON representation of the object.
2341 </summary>
2342 <param name="writer">The <see cref="T:Newtonsoft.Json.JsonWriter"/> to write to.</param>
2343 <param name="value">The value.</param>
2344 <param name="serializer">The calling serializer.</param>
2345 </member>
2346 <member name="M:Newtonsoft.Json.Converters.IsoDateTimeConverter.ReadJson(Newtonsoft.Json.JsonReader,System.Type,Newtonsoft.Json.JsonSerializer)">
2347 <summary>
2348 Reads the JSON representation of the object.
2349 </summary>
2350 <param name="reader">The <see cref="T:Newtonsoft.Json.JsonReader"/> to read from.</param>
2351 <param name="objectType">Type of the object.</param>
2352 <param name="serializer">The calling serializer.</param>
2353 <returns>The object value.</returns>
2354 </member>
2355 <member name="P:Newtonsoft.Json.Converters.IsoDateTimeConverter.DateTimeStyles">
2356 <summary>
2357 Gets or sets the date time styles used when converting a date to and from JSON.
2358 </summary>
2359 <value>The date time styles used when converting a date to and from JSON.</value>
2360 </member>
2361 <member name="P:Newtonsoft.Json.Converters.IsoDateTimeConverter.DateTimeFormat">
2362 <summary>
2363 Gets or sets the date time format used when converting a date to and from JSON.
2364 </summary>
2365 <value>The date time format used when converting a date to and from JSON.</value>
2366 </member>
2367 <member name="P:Newtonsoft.Json.Converters.IsoDateTimeConverter.Culture">
2368 <summary>
2369 Gets or sets the culture used when converting a date to and from JSON.
2370 </summary>
2371 <value>The culture used when converting a date to and from JSON.</value>
2372 </member>
2373 <member name="T:Newtonsoft.Json.Converters.JavaScriptDateTimeConverter">
2374 <summary>
2375 Converts a <see cref="T:System.DateTime"/> to and from a JavaScript date constructor (e.g. new Date(52231943)).
2376 </summary>
2377 </member>
2378 <member name="M:Newtonsoft.Json.Converters.JavaScriptDateTimeConverter.WriteJson(Newtonsoft.Json.JsonWriter,System.Object,Newtonsoft.Json.JsonSerializer)">
2379 <summary>
2380 Writes the JSON representation of the object.
2381 </summary>
2382 <param name="writer">The <see cref="T:Newtonsoft.Json.JsonWriter"/> to write to.</param>
2383 <param name="value">The value.</param>
2384 <param name="serializer">The calling serializer.</param>
2385 </member>
2386 <member name="M:Newtonsoft.Json.Converters.JavaScriptDateTimeConverter.ReadJson(Newtonsoft.Json.JsonReader,System.Type,Newtonsoft.Json.JsonSerializer)">
2387 <summary>
2388 Reads the JSON representation of the object.
2389 </summary>
2390 <param name="reader">The <see cref="T:Newtonsoft.Json.JsonReader"/> to read from.</param>
2391 <param name="objectType">Type of the object.</param>
2392 <param name="serializer">The calling serializer.</param>
2393 <returns>The object value.</returns>
2394 </member>
2395 <member name="T:Newtonsoft.Json.Converters.JsonDateTimeSerializationMode">
2396 <summary>
2397 Specifies whether a DateTime object represents a local time, a Coordinated Universal Time (UTC), or is not specified as either local time or UTC.
2398 </summary>
2399 </member>
2400 <member name="F:Newtonsoft.Json.Converters.JsonDateTimeSerializationMode.Local">
2401 <summary>
2402 The time represented is local time.
2403 </summary>
2404 </member>
2405 <member name="F:Newtonsoft.Json.Converters.JsonDateTimeSerializationMode.Utc">
2406 <summary>
2407 The time represented is UTC.
2408 </summary>
2409 </member>
2410 <member name="F:Newtonsoft.Json.Converters.JsonDateTimeSerializationMode.Unspecified">
2411 <summary>
2412 The time represented is not specified as either local time or Coordinated Universal Time (UTC).
2413 </summary>
2414 </member>
2415 <member name="F:Newtonsoft.Json.Converters.JsonDateTimeSerializationMode.RoundtripKind">
2416 <summary>
2417 Preserves the DateTimeKind field of a date when a DateTime object is converted to a string and the string is then converted back to a DateTime object.
2418 </summary>
2419 </member>
2420 <member name="T:Newtonsoft.Json.Converters.XmlNodeConverter">
2421 <summary>
2422 Converts an <see cref="T:System.Xml.XmlNode"/> to and from JSON.
2423 </summary>
2424 </member>
2425 <member name="M:Newtonsoft.Json.Converters.XmlNodeConverter.WriteJson(Newtonsoft.Json.JsonWriter,System.Object,Newtonsoft.Json.JsonSerializer)">
2426 <summary>
2427 Writes the JSON representation of the object.
2428 </summary>
2429 <param name="writer">The <see cref="T:Newtonsoft.Json.JsonWriter"/> to write to.</param>
2430 <param name="serializer">The calling serializer.</param>
2431 <param name="value">The value.</param>
2432 </member>
2433 <member name="M:Newtonsoft.Json.Converters.XmlNodeConverter.ReadJson(Newtonsoft.Json.JsonReader,System.Type,Newtonsoft.Json.JsonSerializer)">
2434 <summary>
2435 Reads the JSON representation of the object.
2436 </summary>
2437 <param name="reader">The <see cref="T:Newtonsoft.Json.JsonReader"/> to read from.</param>
2438 <param name="objectType">Type of the object.</param>
2439 <param name="serializer">The calling serializer.</param>
2440 <returns>The object value.</returns>
2441 </member>
2442 <member name="M:Newtonsoft.Json.Converters.XmlNodeConverter.IsNamespaceAttribute(System.String,System.String@)">
2443 <summary>
2444 Checks if the attributeName is a namespace attribute.
2445 </summary>
2446 <param name="attributeName">Attribute name to test.</param>
2447 <param name="prefix">The attribute name prefix if it has one, otherwise an empty string.</param>
2448 <returns>True if attribute name is for a namespace attribute, otherwise false.</returns>
2449 </member>
2450 <member name="M:Newtonsoft.Json.Converters.XmlNodeConverter.CanConvert(System.Type)">
2451 <summary>
2452 Determines whether this instance can convert the specified value type.
2453 </summary>
2454 <param name="valueType">Type of the value.</param>
2455 <returns>
2456 <c>true</c> if this instance can convert the specified value type; otherwise, <c>false</c>.
2457 </returns>
2458 </member>
2459 <member name="P:Newtonsoft.Json.Converters.XmlNodeConverter.DeserializeRootElementName">
2460 <summary>
2461 Gets or sets the name of the root element to insert when deserializing to XML if the JSON structure has produces multiple root elements.
2462 </summary>
2463 <value>The name of the deserialize root element.</value>
2464 </member>
2465 <member name="T:Newtonsoft.Json.Converters.HtmlColorConverter">
2466 <summary>
2467 Converts a <see cref="T:System.Drawing.Color"/> object to and from JSON.
2468 </summary>
2469 </member>
2470 <member name="M:Newtonsoft.Json.Converters.HtmlColorConverter.WriteJson(Newtonsoft.Json.JsonWriter,System.Object,Newtonsoft.Json.JsonSerializer)">
2471 <summary>
2472 Writes the JSON representation of the object.
2473 </summary>
2474 <param name="writer">The <see cref="T:Newtonsoft.Json.JsonWriter"/> to write to.</param>
2475 <param name="serializer">The calling serializer.</param>
2476 <param name="value">The value.</param>
2477 </member>
2478 <member name="M:Newtonsoft.Json.Converters.HtmlColorConverter.CanConvert(System.Type)">
2479 <summary>
2480 Determines whether this instance can convert the specified value type.
2481 </summary>
2482 <param name="valueType">Type of the value.</param>
2483 <returns>
2484 <c>true</c> if this instance can convert the specified value type; otherwise, <c>false</c>.
2485 </returns>
2486 </member>
2487 <member name="M:Newtonsoft.Json.Converters.HtmlColorConverter.ReadJson(Newtonsoft.Json.JsonReader,System.Type,Newtonsoft.Json.JsonSerializer)">
2488 <summary>
2489 Reads the JSON representation of the object.
2490 </summary>
2491 <param name="reader">The <see cref="T:Newtonsoft.Json.JsonReader"/> to read from.</param>
2492 <param name="objectType">Type of the object.</param>
2493 <param name="serializer">The calling serializer.</param>
2494 <returns>The object value.</returns>
2495 </member>
2496 <member name="T:Newtonsoft.Json.JsonTextReader">
2497 <summary>
2498 Represents a reader that provides fast, non-cached, forward-only access to serialized Json data.
2499 </summary>
2500 </member>
2501 <member name="M:Newtonsoft.Json.JsonTextReader.#ctor(System.IO.TextReader)">
2502 <summary>
2503 Initializes a new instance of the <see cref="T:Newtonsoft.Json.JsonReader"/> class with the specified <see cref="T:System.IO.TextReader"/>.
2504 </summary>
2505 <param name="reader">The <c>TextReader</c> containing the XML data to read.</param>
2506 </member>
2507 <member name="M:Newtonsoft.Json.JsonTextReader.Read">
2508 <summary>
2509 Reads the next JSON token from the stream.
2510 </summary>
2511 <returns>
2512 true if the next token was read successfully; false if there are no more tokens to read.
2513 </returns>
2514 </member>
2515 <member name="M:Newtonsoft.Json.JsonTextReader.ReadAsBytes">
2516 <summary>
2517 Reads the next JSON token from the stream as a <see cref="T:Byte[]"/>.
2518 </summary>
2519 <returns>
2520 A <see cref="T:Byte[]"/> or a null reference if the next JSON token is null.
2521 </returns>
2522 </member>
2523 <member name="M:Newtonsoft.Json.JsonTextReader.Close">
2524 <summary>
2525 Changes the state to closed.
2526 </summary>
2527 </member>
2528 <member name="M:Newtonsoft.Json.JsonTextReader.HasLineInfo">
2529 <summary>
2530 Gets a value indicating whether the class can return line information.
2531 </summary>
2532 <returns>
2533 <c>true</c> if LineNumber and LinePosition can be provided; otherwise, <c>false</c>.
2534 </returns>
2535 </member>
2536 <member name="P:Newtonsoft.Json.JsonTextReader.LineNumber">
2537 <summary>
2538 Gets the current line number.
2539 </summary>
2540 <value>
2541 The current line number or 0 if no line information is available (for example, HasLineInfo returns false).
2542 </value>
2543 </member>
2544 <member name="P:Newtonsoft.Json.JsonTextReader.LinePosition">
2545 <summary>
2546 Gets the current line position.
2547 </summary>
2548 <value>
2549 The current line position or 0 if no line information is available (for example, HasLineInfo returns false).
2550 </value>
2551 </member>
2552 <member name="T:Newtonsoft.Json.JsonPropertyAttribute">
2553 <summary>
2554 Instructs the <see cref="T:Newtonsoft.Json.JsonSerializer"/> to always serialize the member with the specified name.
2555 </summary>
2556 </member>
2557 <member name="M:Newtonsoft.Json.JsonPropertyAttribute.#ctor">
2558 <summary>
2559 Initializes a new instance of the <see cref="T:Newtonsoft.Json.JsonPropertyAttribute"/> class.
2560 </summary>
2561 </member>
2562 <member name="M:Newtonsoft.Json.JsonPropertyAttribute.#ctor(System.String)">
2563 <summary>
2564 Initializes a new instance of the <see cref="T:Newtonsoft.Json.JsonPropertyAttribute"/> class with the specified name.
2565 </summary>
2566 <param name="propertyName">Name of the property.</param>
2567 </member>
2568 <member name="P:Newtonsoft.Json.JsonPropertyAttribute.NullValueHandling">
2569 <summary>
2570 Gets or sets the null value handling used when serializing this property.
2571 </summary>
2572 <value>The null value handling.</value>
2573 </member>
2574 <member name="P:Newtonsoft.Json.JsonPropertyAttribute.DefaultValueHandling">
2575 <summary>
2576 Gets or sets the default value handling used when serializing this property.
2577 </summary>
2578 <value>The default value handling.</value>
2579 </member>
2580 <member name="P:Newtonsoft.Json.JsonPropertyAttribute.ReferenceLoopHandling">
2581 <summary>
2582 Gets or sets the reference loop handling used when serializing this property.
2583 </summary>
2584 <value>The reference loop handling.</value>
2585 </member>
2586 <member name="P:Newtonsoft.Json.JsonPropertyAttribute.ObjectCreationHandling">
2587 <summary>
2588 Gets or sets the object creation handling used when deserializing this property.
2589 </summary>
2590 <value>The object creation handling.</value>
2591 </member>
2592 <member name="P:Newtonsoft.Json.JsonPropertyAttribute.IsReference">
2593 <summary>
2594 Gets or sets whether this property's value is serialized as a reference.
2595 </summary>
2596 <value>Whether this property's value is serialized as a reference.</value>
2597 </member>
2598 <member name="P:Newtonsoft.Json.JsonPropertyAttribute.PropertyName">
2599 <summary>
2600 Gets or sets the name of the property.
2601 </summary>
2602 <value>The name of the property.</value>
2603 </member>
2604 <member name="P:Newtonsoft.Json.JsonPropertyAttribute.Required">
2605 <summary>
2606 Gets or sets a value indicating whether this property is required.
2607 </summary>
2608 <value>
2609 A value indicating whether this property is required.
2610 </value>
2611 </member>
2612 <member name="T:Newtonsoft.Json.JsonIgnoreAttribute">
2613 <summary>
2614 Instructs the <see cref="T:Newtonsoft.Json.JsonSerializer"/> not to serialize the public field or public read/write property value.
2615 </summary>
2616 </member>
2617 <member name="T:Newtonsoft.Json.JsonTextWriter">
2618 <summary>
2619 Represents a writer that provides a fast, non-cached, forward-only way of generating Json data.
2620 </summary>
2621 </member>
2622 <member name="M:Newtonsoft.Json.JsonTextWriter.#ctor(System.IO.TextWriter)">
2623 <summary>
2624 Creates an instance of the <c>JsonWriter</c> class using the specified <see cref="T:System.IO.TextWriter"/>.
2625 </summary>
2626 <param name="textWriter">The <c>TextWriter</c> to write to.</param>
2627 </member>
2628 <member name="M:Newtonsoft.Json.JsonTextWriter.Flush">
2629 <summary>
2630 Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream.
2631 </summary>
2632 </member>
2633 <member name="M:Newtonsoft.Json.JsonTextWriter.Close">
2634 <summary>
2635 Closes this stream and the underlying stream.
2636 </summary>
2637 </member>
2638 <member name="M:Newtonsoft.Json.JsonTextWriter.WriteStartObject">
2639 <summary>
2640 Writes the beginning of a Json object.
2641 </summary>
2642 </member>
2643 <member name="M:Newtonsoft.Json.JsonTextWriter.WriteStartArray">
2644 <summary>
2645 Writes the beginning of a Json array.
2646 </summary>
2647 </member>
2648 <member name="M:Newtonsoft.Json.JsonTextWriter.WriteStartConstructor(System.String)">
2649 <summary>
2650 Writes the start of a constructor with the given name.
2651 </summary>
2652 <param name="name">The name of the constructor.</param>
2653 </member>
2654 <member name="M:Newtonsoft.Json.JsonTextWriter.WriteEnd(Newtonsoft.Json.JsonToken)">
2655 <summary>
2656 Writes the specified end token.
2657 </summary>
2658 <param name="token">The end token to write.</param>
2659 </member>
2660 <member name="M:Newtonsoft.Json.JsonTextWriter.WritePropertyName(System.String)">
2661 <summary>
2662 Writes the property name of a name/value pair on a Json object.
2663 </summary>
2664 <param name="name">The name of the property.</param>
2665 </member>
2666 <member name="M:Newtonsoft.Json.JsonTextWriter.WriteIndent">
2667 <summary>
2668 Writes indent characters.
2669 </summary>
2670 </member>
2671 <member name="M:Newtonsoft.Json.JsonTextWriter.WriteValueDelimiter">
2672 <summary>
2673 Writes the JSON value delimiter.
2674 </summary>
2675 </member>
2676 <member name="M:Newtonsoft.Json.JsonTextWriter.WriteIndentSpace">
2677 <summary>
2678 Writes an indent space.
2679 </summary>
2680 </member>
2681 <member name="M:Newtonsoft.Json.JsonTextWriter.WriteNull">
2682 <summary>
2683 Writes a null value.
2684 </summary>
2685 </member>
2686 <member name="M:Newtonsoft.Json.JsonTextWriter.WriteUndefined">
2687 <summary>
2688 Writes an undefined value.
2689 </summary>
2690 </member>
2691 <member name="M:Newtonsoft.Json.JsonTextWriter.WriteRaw(System.String)">
2692 <summary>
2693 Writes raw JSON.
2694 </summary>
2695 <param name="json">The raw JSON to write.</param>
2696 </member>
2697 <member name="M:Newtonsoft.Json.JsonTextWriter.WriteValue(System.String)">
2698 <summary>
2699 Writes a <see cref="T:System.String"/> value.
2700 </summary>
2701 <param name="value">The <see cref="T:System.String"/> value to write.</param>
2702 </member>
2703 <member name="M:Newtonsoft.Json.JsonTextWriter.WriteValue(System.Int32)">
2704 <summary>
2705 Writes a <see cref="T:System.Int32"/> value.
2706 </summary>
2707 <param name="value">The <see cref="T:System.Int32"/> value to write.</param>
2708 </member>
2709 <member name="M:Newtonsoft.Json.JsonTextWriter.WriteValue(System.UInt32)">
2710 <summary>
2711 Writes a <see cref="T:System.UInt32"/> value.
2712 </summary>
2713 <param name="value">The <see cref="T:System.UInt32"/> value to write.</param>
2714 </member>
2715 <member name="M:Newtonsoft.Json.JsonTextWriter.WriteValue(System.Int64)">
2716 <summary>
2717 Writes a <see cref="T:System.Int64"/> value.
2718 </summary>
2719 <param name="value">The <see cref="T:System.Int64"/> value to write.</param>
2720 </member>
2721 <member name="M:Newtonsoft.Json.JsonTextWriter.WriteValue(System.UInt64)">
2722 <summary>
2723 Writes a <see cref="T:System.UInt64"/> value.
2724 </summary>
2725 <param name="value">The <see cref="T:System.UInt64"/> value to write.</param>
2726 </member>
2727 <member name="M:Newtonsoft.Json.JsonTextWriter.WriteValue(System.Single)">
2728 <summary>
2729 Writes a <see cref="T:System.Single"/> value.
2730 </summary>
2731 <param name="value">The <see cref="T:System.Single"/> value to write.</param>
2732 </member>
2733 <member name="M:Newtonsoft.Json.JsonTextWriter.WriteValue(System.Double)">
2734 <summary>
2735 Writes a <see cref="T:System.Double"/> value.
2736 </summary>
2737 <param name="value">The <see cref="T:System.Double"/> value to write.</param>
2738 </member>
2739 <member name="M:Newtonsoft.Json.JsonTextWriter.WriteValue(System.Boolean)">
2740 <summary>
2741 Writes a <see cref="T:System.Boolean"/> value.
2742 </summary>
2743 <param name="value">The <see cref="T:System.Boolean"/> value to write.</param>
2744 </member>
2745 <member name="M:Newtonsoft.Json.JsonTextWriter.WriteValue(System.Int16)">
2746 <summary>
2747 Writes a <see cref="T:System.Int16"/> value.
2748 </summary>
2749 <param name="value">The <see cref="T:System.Int16"/> value to write.</param>
2750 </member>
2751 <member name="M:Newtonsoft.Json.JsonTextWriter.WriteValue(System.UInt16)">
2752 <summary>
2753 Writes a <see cref="T:System.UInt16"/> value.
2754 </summary>
2755 <param name="value">The <see cref="T:System.UInt16"/> value to write.</param>
2756 </member>
2757 <member name="M:Newtonsoft.Json.JsonTextWriter.WriteValue(System.Char)">
2758 <summary>
2759 Writes a <see cref="T:System.Char"/> value.
2760 </summary>
2761 <param name="value">The <see cref="T:System.Char"/> value to write.</param>
2762 </member>
2763 <member name="M:Newtonsoft.Json.JsonTextWriter.WriteValue(System.Byte)">
2764 <summary>
2765 Writes a <see cref="T:System.Byte"/> value.
2766 </summary>
2767 <param name="value">The <see cref="T:System.Byte"/> value to write.</param>
2768 </member>
2769 <member name="M:Newtonsoft.Json.JsonTextWriter.WriteValue(System.SByte)">
2770 <summary>
2771 Writes a <see cref="T:System.SByte"/> value.
2772 </summary>
2773 <param name="value">The <see cref="T:System.SByte"/> value to write.</param>
2774 </member>
2775 <member name="M:Newtonsoft.Json.JsonTextWriter.WriteValue(System.Decimal)">
2776 <summary>
2777 Writes a <see cref="T:System.Decimal"/> value.
2778 </summary>
2779 <param name="value">The <see cref="T:System.Decimal"/> value to write.</param>
2780 </member>
2781 <member name="M:Newtonsoft.Json.JsonTextWriter.WriteValue(System.DateTime)">
2782 <summary>
2783 Writes a <see cref="T:System.DateTime"/> value.
2784 </summary>
2785 <param name="value">The <see cref="T:System.DateTime"/> value to write.</param>
2786 </member>
2787 <member name="M:Newtonsoft.Json.JsonTextWriter.WriteValue(System.Byte[])">
2788 <summary>
2789 Writes a <see cref="T:Byte[]"/> value.
2790 </summary>
2791 <param name="value">The <see cref="T:Byte[]"/> value to write.</param>
2792 </member>
2793 <member name="M:Newtonsoft.Json.JsonTextWriter.WriteComment(System.String)">
2794 <summary>
2795 Writes out a comment <code>/*...*/</code> containing the specified text.
2796 </summary>
2797 <param name="text">Text to place inside the comment.</param>
2798 </member>
2799 <member name="M:Newtonsoft.Json.JsonTextWriter.WriteWhitespace(System.String)">
2800 <summary>
2801 Writes out the given white space.
2802 </summary>
2803 <param name="ws">The string of white space characters.</param>
2804 </member>
2805 <member name="P:Newtonsoft.Json.JsonTextWriter.Indentation">
2806 <summary>
2807 Gets or sets how many IndentChars to write for each level in the hierarchy when <paramref name="Formatting"/> is set to <c>Formatting.Indented</c>.
2808 </summary>
2809 </member>
2810 <member name="P:Newtonsoft.Json.JsonTextWriter.QuoteChar">
2811 <summary>
2812 Gets or sets which character to use to quote attribute values.
2813 </summary>
2814 </member>
2815 <member name="P:Newtonsoft.Json.JsonTextWriter.IndentChar">
2816 <summary>
2817 Gets or sets which character to use for indenting when <paramref name="Formatting"/> is set to <c>Formatting.Indented</c>.
2818 </summary>
2819 </member>
2820 <member name="P:Newtonsoft.Json.JsonTextWriter.QuoteName">
2821 <summary>
2822 Gets or sets a value indicating whether object names will be surrounded with quotes.
2823 </summary>
2824 </member>
2825 <member name="T:Newtonsoft.Json.JsonWriterException">
2826 <summary>
2827 The exception thrown when an error occurs while reading Json text.
2828 </summary>
2829 </member>
2830 <member name="M:Newtonsoft.Json.JsonWriterException.#ctor">
2831 <summary>
2832 Initializes a new instance of the <see cref="T:Newtonsoft.Json.JsonWriterException"/> class.
2833 </summary>
2834 </member>
2835 <member name="M:Newtonsoft.Json.JsonWriterException.#ctor(System.String)">
2836 <summary>
2837 Initializes a new instance of the <see cref="T:Newtonsoft.Json.JsonWriterException"/> class
2838 with a specified error message.
2839 </summary>
2840 <param name="message">The error message that explains the reason for the exception.</param>
2841 </member>
2842 <member name="M:Newtonsoft.Json.JsonWriterException.#ctor(System.String,System.Exception)">
2843 <summary>
2844 Initializes a new instance of the <see cref="T:Newtonsoft.Json.JsonWriterException"/> class
2845 with a specified error message and a reference to the inner exception that is the cause of this exception.
2846 </summary>
2847 <param name="message">The error message that explains the reason for the exception.</param>
2848 <param name="innerException">The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified.</param>
2849 </member>
2850 <member name="T:Newtonsoft.Json.JsonReaderException">
2851 <summary>
2852 The exception thrown when an error occurs while reading Json text.
2853 </summary>
2854 </member>
2855 <member name="M:Newtonsoft.Json.JsonReaderException.#ctor">
2856 <summary>
2857 Initializes a new instance of the <see cref="T:Newtonsoft.Json.JsonReaderException"/> class.
2858 </summary>
2859 </member>
2860 <member name="M:Newtonsoft.Json.JsonReaderException.#ctor(System.String)">
2861 <summary>
2862 Initializes a new instance of the <see cref="T:Newtonsoft.Json.JsonReaderException"/> class
2863 with a specified error message.
2864 </summary>
2865 <param name="message">The error message that explains the reason for the exception.</param>
2866 </member>
2867 <member name="M:Newtonsoft.Json.JsonReaderException.#ctor(System.String,System.Exception)">
2868 <summary>
2869 Initializes a new instance of the <see cref="T:Newtonsoft.Json.JsonReaderException"/> class
2870 with a specified error message and a reference to the inner exception that is the cause of this exception.
2871 </summary>
2872 <param name="message">The error message that explains the reason for the exception.</param>
2873 <param name="innerException">The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified.</param>
2874 </member>
2875 <member name="P:Newtonsoft.Json.JsonReaderException.LineNumber">
2876 <summary>
2877 Gets the line number indicating where the error occurred.
2878 </summary>
2879 <value>The line number indicating where the error occurred.</value>
2880 </member>
2881 <member name="P:Newtonsoft.Json.JsonReaderException.LinePosition">
2882 <summary>
2883 Gets the line position indicating where the error occurred.
2884 </summary>
2885 <value>The line position indicating where the error occurred.</value>
2886 </member>
2887 <member name="T:Newtonsoft.Json.JsonConverterCollection">
2888 <summary>
2889 Represents a collection of <see cref="T:Newtonsoft.Json.JsonConverter"/>.
2890 </summary>
2891 </member>
2892 <member name="T:Newtonsoft.Json.JsonConvert">
2893 <summary>
2894 Provides methods for converting between common language runtime types and JSON types.
2895 </summary>
2896 </member>
2897 <member name="F:Newtonsoft.Json.JsonConvert.True">
2898 <summary>
2899 Represents JavaScript's boolean value true as a string. This field is read-only.
2900 </summary>
2901 </member>
2902 <member name="F:Newtonsoft.Json.JsonConvert.False">
2903 <summary>
2904 Represents JavaScript's boolean value false as a string. This field is read-only.
2905 </summary>
2906 </member>
2907 <member name="F:Newtonsoft.Json.JsonConvert.Null">
2908 <summary>
2909 Represents JavaScript's null as a string. This field is read-only.
2910 </summary>
2911 </member>
2912 <member name="F:Newtonsoft.Json.JsonConvert.Undefined">
2913 <summary>
2914 Represents JavaScript's undefined as a string. This field is read-only.
2915 </summary>
2916 </member>
2917 <member name="F:Newtonsoft.Json.JsonConvert.PositiveInfinity">
2918 <summary>
2919 Represents JavaScript's positive infinity as a string. This field is read-only.
2920 </summary>
2921 </member>
2922 <member name="F:Newtonsoft.Json.JsonConvert.NegativeInfinity">
2923 <summary>
2924 Represents JavaScript's negative infinity as a string. This field is read-only.
2925 </summary>
2926 </member>
2927 <member name="F:Newtonsoft.Json.JsonConvert.NaN">
2928 <summary>
2929 Represents JavaScript's NaN as a string. This field is read-only.
2930 </summary>
2931 </member>
2932 <member name="M:Newtonsoft.Json.JsonConvert.ToString(System.DateTime)">
2933 <summary>
2934 Converts the <see cref="T:System.DateTime"/> to its JSON string representation.
2935 </summary>
2936 <param name="value">The value to convert.</param>
2937 <returns>A JSON string representation of the <see cref="T:System.DateTime"/>.</returns>
2938 </member>
2939 <member name="M:Newtonsoft.Json.JsonConvert.ToString(System.Boolean)">
2940 <summary>
2941 Converts the <see cref="T:System.Boolean"/> to its JSON string representation.
2942 </summary>
2943 <param name="value">The value to convert.</param>
2944 <returns>A JSON string representation of the <see cref="T:System.Boolean"/>.</returns>
2945 </member>
2946 <member name="M:Newtonsoft.Json.JsonConvert.ToString(System.Char)">
2947 <summary>
2948 Converts the <see cref="T:System.Char"/> to its JSON string representation.
2949 </summary>
2950 <param name="value">The value to convert.</param>
2951 <returns>A JSON string representation of the <see cref="T:System.Char"/>.</returns>
2952 </member>
2953 <member name="M:Newtonsoft.Json.JsonConvert.ToString(System.Enum)">
2954 <summary>
2955 Converts the <see cref="T:System.Enum"/> to its JSON string representation.
2956 </summary>
2957 <param name="value">The value to convert.</param>
2958 <returns>A JSON string representation of the <see cref="T:System.Enum"/>.</returns>
2959 </member>
2960 <member name="M:Newtonsoft.Json.JsonConvert.ToString(System.Int32)">
2961 <summary>
2962 Converts the <see cref="T:System.Int32"/> to its JSON string representation.
2963 </summary>
2964 <param name="value">The value to convert.</param>
2965 <returns>A JSON string representation of the <see cref="T:System.Int32"/>.</returns>
2966 </member>
2967 <member name="M:Newtonsoft.Json.JsonConvert.ToString(System.Int16)">
2968 <summary>
2969 Converts the <see cref="T:System.Int16"/> to its JSON string representation.
2970 </summary>
2971 <param name="value">The value to convert.</param>
2972 <returns>A JSON string representation of the <see cref="T:System.Int16"/>.</returns>
2973 </member>
2974 <member name="M:Newtonsoft.Json.JsonConvert.ToString(System.UInt16)">
2975 <summary>
2976 Converts the <see cref="T:System.UInt16"/> to its JSON string representation.
2977 </summary>
2978 <param name="value">The value to convert.</param>
2979 <returns>A JSON string representation of the <see cref="T:System.UInt16"/>.</returns>
2980 </member>
2981 <member name="M:Newtonsoft.Json.JsonConvert.ToString(System.UInt32)">
2982 <summary>
2983 Converts the <see cref="T:System.UInt32"/> to its JSON string representation.
2984 </summary>
2985 <param name="value">The value to convert.</param>
2986 <returns>A JSON string representation of the <see cref="T:System.UInt32"/>.</returns>
2987 </member>
2988 <member name="M:Newtonsoft.Json.JsonConvert.ToString(System.Int64)">
2989 <summary>
2990 Converts the <see cref="T:System.Int64"/> to its JSON string representation.
2991 </summary>
2992 <param name="value">The value to convert.</param>
2993 <returns>A JSON string representation of the <see cref="T:System.Int64"/>.</returns>
2994 </member>
2995 <member name="M:Newtonsoft.Json.JsonConvert.ToString(System.UInt64)">
2996 <summary>
2997 Converts the <see cref="T:System.UInt64"/> to its JSON string representation.
2998 </summary>
2999 <param name="value">The value to convert.</param>
3000 <returns>A JSON string representation of the <see cref="T:System.UInt64"/>.</returns>
3001 </member>
3002 <member name="M:Newtonsoft.Json.JsonConvert.ToString(System.Single)">
3003 <summary>
3004 Converts the <see cref="T:System.Single"/> to its JSON string representation.
3005 </summary>
3006 <param name="value">The value to convert.</param>
3007 <returns>A JSON string representation of the <see cref="T:System.Single"/>.</returns>
3008 </member>
3009 <member name="M:Newtonsoft.Json.JsonConvert.ToString(System.Double)">
3010 <summary>
3011 Converts the <see cref="T:System.Double"/> to its JSON string representation.
3012 </summary>
3013 <param name="value">The value to convert.</param>
3014 <returns>A JSON string representation of the <see cref="T:System.Double"/>.</returns>
3015 </member>
3016 <member name="M:Newtonsoft.Json.JsonConvert.ToString(System.Byte)">
3017 <summary>
3018 Converts the <see cref="T:System.Byte"/> to its JSON string representation.
3019 </summary>
3020 <param name="value">The value to convert.</param>
3021 <returns>A JSON string representation of the <see cref="T:System.Byte"/>.</returns>
3022 </member>
3023 <member name="M:Newtonsoft.Json.JsonConvert.ToString(System.SByte)">
3024 <summary>
3025 Converts the <see cref="T:System.SByte"/> to its JSON string representation.
3026 </summary>
3027 <param name="value">The value to convert.</param>
3028 <returns>A JSON string representation of the <see cref="T:System.SByte"/>.</returns>
3029 </member>
3030 <member name="M:Newtonsoft.Json.JsonConvert.ToString(System.Decimal)">
3031 <summary>
3032 Converts the <see cref="T:System.Decimal"/> to its JSON string representation.
3033 </summary>
3034 <param name="value">The value to convert.</param>
3035 <returns>A JSON string representation of the <see cref="T:System.SByte"/>.</returns>
3036 </member>
3037 <member name="M:Newtonsoft.Json.JsonConvert.ToString(System.Guid)">
3038 <summary>
3039 Converts the <see cref="T:System.Guid"/> to its JSON string representation.
3040 </summary>
3041 <param name="value">The value to convert.</param>
3042 <returns>A JSON string representation of the <see cref="T:System.Guid"/>.</returns>
3043 </member>
3044 <member name="M:Newtonsoft.Json.JsonConvert.ToString(System.String)">
3045 <summary>
3046 Converts the <see cref="T:System.String"/> to its JSON string representation.
3047 </summary>
3048 <param name="value">The value to convert.</param>
3049 <returns>A JSON string representation of the <see cref="T:System.String"/>.</returns>
3050 </member>
3051 <member name="M:Newtonsoft.Json.JsonConvert.ToString(System.String,System.Char)">
3052 <summary>
3053 Converts the <see cref="T:System.String"/> to its JSON string representation.
3054 </summary>
3055 <param name="value">The value to convert.</param>
3056 <param name="delimter">The string delimiter character.</param>
3057 <returns>A JSON string representation of the <see cref="T:System.String"/>.</returns>
3058 </member>
3059 <member name="M:Newtonsoft.Json.JsonConvert.ToString(System.Object)">
3060 <summary>
3061 Converts the <see cref="T:System.Object"/> to its JSON string representation.
3062 </summary>
3063 <param name="value">The value to convert.</param>
3064 <returns>A JSON string representation of the <see cref="T:System.Object"/>.</returns>
3065 </member>
3066 <member name="M:Newtonsoft.Json.JsonConvert.SerializeObject(System.Object)">
3067 <summary>
3068 Serializes the specified object to a JSON string.
3069 </summary>
3070 <param name="value">The object to serialize.</param>
3071 <returns>A JSON string representation of the object.</returns>
3072 </member>
3073 <member name="M:Newtonsoft.Json.JsonConvert.SerializeObject(System.Object,Newtonsoft.Json.Formatting)">
3074 <summary>
3075 Serializes the specified object to a JSON string.
3076 </summary>
3077 <param name="value">The object to serialize.</param>
3078 <param name="formatting">Indicates how the output is formatted.</param>
3079 <returns>
3080 A JSON string representation of the object.
3081 </returns>
3082 </member>
3083 <member name="M:Newtonsoft.Json.JsonConvert.SerializeObject(System.Object,Newtonsoft.Json.JsonConverter[])">
3084 <summary>
3085 Serializes the specified object to a JSON string using a collection of <see cref="T:Newtonsoft.Json.JsonConverter"/>.
3086 </summary>
3087 <param name="value">The object to serialize.</param>
3088 <param name="converters">A collection converters used while serializing.</param>
3089 <returns>A JSON string representation of the object.</returns>
3090 </member>
3091 <member name="M:Newtonsoft.Json.JsonConvert.SerializeObject(System.Object,Newtonsoft.Json.Formatting,Newtonsoft.Json.JsonConverter[])">
3092 <summary>
3093 Serializes the specified object to a JSON string using a collection of <see cref="T:Newtonsoft.Json.JsonConverter"/>.
3094 </summary>
3095 <param name="value">The object to serialize.</param>
3096 <param name="formatting">Indicates how the output is formatted.</param>
3097 <param name="converters">A collection converters used while serializing.</param>
3098 <returns>A JSON string representation of the object.</returns>
3099 </member>
3100 <member name="M:Newtonsoft.Json.JsonConvert.SerializeObject(System.Object,Newtonsoft.Json.Formatting,Newtonsoft.Json.JsonSerializerSettings)">
3101 <summary>
3102 Serializes the specified object to a JSON string using a collection of <see cref="T:Newtonsoft.Json.JsonConverter"/>.
3103 </summary>
3104 <param name="value">The object to serialize.</param>
3105 <param name="formatting">Indicates how the output is formatted.</param>
3106 <param name="settings">The <see cref="T:Newtonsoft.Json.JsonSerializerSettings"/> used to serialize the object.
3107 If this is null, default serialization settings will be is used.</param>
3108 <returns>
3109 A JSON string representation of the object.
3110 </returns>
3111 </member>
3112 <member name="M:Newtonsoft.Json.JsonConvert.DeserializeObject(System.String)">
3113 <summary>
3114 Deserializes the specified object to a Json object.
3115 </summary>
3116 <param name="value">The object to deserialize.</param>
3117 <returns>The deserialized object from the Json string.</returns>
3118 </member>
3119 <member name="M:Newtonsoft.Json.JsonConvert.DeserializeObject(System.String,System.Type)">
3120 <summary>
3121 Deserializes the specified object to a Json object.
3122 </summary>
3123 <param name="value">The object to deserialize.</param>
3124 <param name="type">The <see cref="T:System.Type"/> of object being deserialized.</param>
3125 <returns>The deserialized object from the Json string.</returns>
3126 </member>
3127 <member name="M:Newtonsoft.Json.JsonConvert.DeserializeObject``1(System.String)">
3128 <summary>
3129 Deserializes the specified object to a Json object.
3130 </summary>
3131 <typeparam name="T">The type of the object to deserialize.</typeparam>
3132 <param name="value">The object to deserialize.</param>
3133 <returns>The deserialized object from the Json string.</returns>
3134 </member>
3135 <member name="M:Newtonsoft.Json.JsonConvert.DeserializeAnonymousType``1(System.String,``0)">
3136 <summary>
3137 Deserializes the specified JSON to the given anonymous type.
3138 </summary>
3139 <typeparam name="T">
3140 The anonymous type to deserialize to. This can't be specified
3141 traditionally and must be infered from the anonymous type passed
3142 as a parameter.
3143 </typeparam>
3144 <param name="value">The object to deserialize.</param>
3145 <param name="anonymousTypeObject">The anonymous type object.</param>
3146 <returns>The deserialized anonymous type from the JSON string.</returns>
3147 </member>
3148 <member name="M:Newtonsoft.Json.JsonConvert.DeserializeObject``1(System.String,Newtonsoft.Json.JsonConverter[])">
3149 <summary>
3150 Deserializes the JSON string to the specified type.
3151 </summary>
3152 <typeparam name="T">The type of the object to deserialize.</typeparam>
3153 <param name="value">The object to deserialize.</param>
3154 <param name="converters">Converters to use while deserializing.</param>
3155 <returns>The deserialized object from the JSON string.</returns>
3156 </member>
3157 <member name="M:Newtonsoft.Json.JsonConvert.DeserializeObject``1(System.String,Newtonsoft.Json.JsonSerializerSettings)">
3158 <summary>
3159 Deserializes the JSON string to the specified type.
3160 </summary>
3161 <typeparam name="T">The type of the object to deserialize.</typeparam>
3162 <param name="value">The object to deserialize.</param>
3163 <param name="settings">
3164 The <see cref="T:Newtonsoft.Json.JsonSerializerSettings"/> used to deserialize the object.
3165 If this is null, default serialization settings will be is used.
3166 </param>
3167 <returns>The deserialized object from the JSON string.</returns>
3168 </member>
3169 <member name="M:Newtonsoft.Json.JsonConvert.DeserializeObject(System.String,System.Type,Newtonsoft.Json.JsonConverter[])">
3170 <summary>
3171 Deserializes the JSON string to the specified type.
3172 </summary>
3173 <param name="value">The object to deserialize.</param>
3174 <param name="type">The type of the object to deserialize.</param>
3175 <param name="converters">Converters to use while deserializing.</param>
3176 <returns>The deserialized object from the JSON string.</returns>
3177 </member>
3178 <member name="M:Newtonsoft.Json.JsonConvert.DeserializeObject(System.String,System.Type,Newtonsoft.Json.JsonSerializerSettings)">
3179 <summary>
3180 Deserializes the JSON string to the specified type.
3181 </summary>
3182 <param name="value">The JSON to deserialize.</param>
3183 <param name="type">The type of the object to deserialize.</param>
3184 <param name="settings">
3185 The <see cref="T:Newtonsoft.Json.JsonSerializerSettings"/> used to deserialize the object.
3186 If this is null, default serialization settings will be is used.
3187 </param>
3188 <returns>The deserialized object from the JSON string.</returns>
3189 </member>
3190 <member name="M:Newtonsoft.Json.JsonConvert.PopulateObject(System.String,System.Object)">
3191 <summary>
3192 Populates the object with values from the JSON string.
3193 </summary>
3194 <param name="value">The JSON to populate values from.</param>
3195 <param name="target">The target object to populate values onto.</param>
3196 </member>
3197 <member name="M:Newtonsoft.Json.JsonConvert.PopulateObject(System.String,System.Object,Newtonsoft.Json.JsonSerializerSettings)">
3198 <summary>
3199 Populates the object with values from the JSON string.
3200 </summary>
3201 <param name="value">The JSON to populate values from.</param>
3202 <param name="target">The target object to populate values onto.</param>
3203 <param name="settings">
3204 The <see cref="T:Newtonsoft.Json.JsonSerializerSettings"/> used to deserialize the object.
3205 If this is null, default serialization settings will be is used.
3206 </param>
3207 </member>
3208 <member name="M:Newtonsoft.Json.JsonConvert.SerializeXmlNode(System.Xml.XmlNode)">
3209 <summary>
3210 Serializes the XML node to a JSON string.
3211 </summary>
3212 <param name="node">The node to serialize.</param>
3213 <returns>A JSON string of the XmlNode.</returns>
3214 </member>
3215 <member name="M:Newtonsoft.Json.JsonConvert.DeserializeXmlNode(System.String)">
3216 <summary>
3217 Deserializes the XmlNode from a JSON string.
3218 </summary>
3219 <param name="value">The JSON string.</param>
3220 <returns>The deserialized XmlNode</returns>
3221 </member>
3222 <member name="M:Newtonsoft.Json.JsonConvert.DeserializeXmlNode(System.String,System.String)">
3223 <summary>
3224 Deserializes the XmlNode from a JSON string nested in a root elment.
3225 </summary>
3226 <param name="value">The JSON string.</param>
3227 <param name="deserializeRootElementName">The name of the root element to append when deserializing.</param>
3228 <returns>The deserialized XmlNode</returns>
3229 </member>
3230 <member name="T:Newtonsoft.Json.JsonSerializationException">
3231 <summary>
3232 The exception thrown when an error occurs during Json serialization or deserialization.
3233 </summary>
3234 </member>
3235 <member name="M:Newtonsoft.Json.JsonSerializationException.#ctor">
3236 <summary>
3237 Initializes a new instance of the <see cref="T:Newtonsoft.Json.JsonSerializationException"/> class.
3238 </summary>
3239 </member>
3240 <member name="M:Newtonsoft.Json.JsonSerializationException.#ctor(System.String)">
3241 <summary>
3242 Initializes a new instance of the <see cref="T:Newtonsoft.Json.JsonSerializationException"/> class
3243 with a specified error message.
3244 </summary>
3245 <param name="message">The error message that explains the reason for the exception.</param>
3246 </member>
3247 <member name="M:Newtonsoft.Json.JsonSerializationException.#ctor(System.String,System.Exception)">
3248 <summary>
3249 Initializes a new instance of the <see cref="T:Newtonsoft.Json.JsonSerializationException"/> class
3250 with a specified error message and a reference to the inner exception that is the cause of this exception.
3251 </summary>
3252 <param name="message">The error message that explains the reason for the exception.</param>
3253 <param name="innerException">The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified.</param>
3254 </member>
3255 <member name="T:Newtonsoft.Json.JsonSerializer">
3256 <summary>
3257 Serializes and deserializes objects into and from the JSON format.
3258 The <see cref="T:Newtonsoft.Json.JsonSerializer"/> enables you to control how objects are encoded into JSON.
3259 </summary>
3260 </member>
3261 <member name="M:Newtonsoft.Json.JsonSerializer.#ctor">
3262 <summary>
3263 Initializes a new instance of the <see cref="T:Newtonsoft.Json.JsonSerializer"/> class.
3264 </summary>
3265 </member>
3266 <member name="M:Newtonsoft.Json.JsonSerializer.Create(Newtonsoft.Json.JsonSerializerSettings)">
3267 <summary>
3268 Creates a new <see cref="T:Newtonsoft.Json.JsonSerializer"/> instance using the specified <see cref="T:Newtonsoft.Json.JsonSerializerSettings"/>.
3269 </summary>
3270 <param name="settings">The settings to be applied to the <see cref="T:Newtonsoft.Json.JsonSerializer"/>.</param>
3271 <returns>A new <see cref="T:Newtonsoft.Json.JsonSerializer"/> instance using the specified <see cref="T:Newtonsoft.Json.JsonSerializerSettings"/>.</returns>
3272 </member>
3273 <member name="M:Newtonsoft.Json.JsonSerializer.Populate(System.IO.TextReader,System.Object)">
3274 <summary>
3275 Populates the JSON values onto the target object.
3276 </summary>
3277 <param name="reader">The <see cref="T:System.IO.TextReader"/> that contains the JSON structure to reader values from.</param>
3278 <param name="target">The target object to populate values onto.</param>
3279 </member>
3280 <member name="M:Newtonsoft.Json.JsonSerializer.Populate(Newtonsoft.Json.JsonReader,System.Object)">
3281 <summary>
3282 Populates the JSON values onto the target object.
3283 </summary>
3284 <param name="reader">The <see cref="T:Newtonsoft.Json.JsonReader"/> that contains the JSON structure to reader values from.</param>
3285 <param name="target">The target object to populate values onto.</param>
3286 </member>
3287 <member name="M:Newtonsoft.Json.JsonSerializer.Deserialize(Newtonsoft.Json.JsonReader)">
3288 <summary>
3289 Deserializes the Json structure contained by the specified <see cref="T:Newtonsoft.Json.JsonReader"/>.
3290 </summary>
3291 <param name="reader">The <see cref="T:Newtonsoft.Json.JsonReader"/> that contains the JSON structure to deserialize.</param>
3292 <returns>The <see cref="T:System.Object"/> being deserialized.</returns>
3293 </member>
3294 <member name="M:Newtonsoft.Json.JsonSerializer.Deserialize(System.IO.TextReader,System.Type)">
3295 <summary>
3296 Deserializes the Json structure contained by the specified <see cref="T:System.IO.StringReader"/>
3297 into an instance of the specified type.
3298 </summary>
3299 <param name="reader">The <see cref="T:System.IO.TextReader"/> containing the object.</param>
3300 <param name="objectType">The <see cref="T:System.Type"/> of object being deserialized.</param>
3301 <returns>The instance of <paramref name="objectType"/> being deserialized.</returns>
3302 </member>
3303 <member name="M:Newtonsoft.Json.JsonSerializer.Deserialize``1(Newtonsoft.Json.JsonReader)">
3304 <summary>
3305 Deserializes the Json structure contained by the specified <see cref="T:Newtonsoft.Json.JsonReader"/>
3306 into an instance of the specified type.
3307 </summary>
3308 <param name="reader">The <see cref="T:Newtonsoft.Json.JsonReader"/> containing the object.</param>
3309 <typeparam name="T">The type of the object to deserialize.</typeparam>
3310 <returns>The instance of <typeparamref name="T"/> being deserialized.</returns>
3311 </member>
3312 <member name="M:Newtonsoft.Json.JsonSerializer.Deserialize(Newtonsoft.Json.JsonReader,System.Type)">
3313 <summary>
3314 Deserializes the Json structure contained by the specified <see cref="T:Newtonsoft.Json.JsonReader"/>
3315 into an instance of the specified type.
3316 </summary>
3317 <param name="reader">The <see cref="T:Newtonsoft.Json.JsonReader"/> containing the object.</param>
3318 <param name="objectType">The <see cref="T:System.Type"/> of object being deserialized.</param>
3319 <returns>The instance of <paramref name="objectType"/> being deserialized.</returns>
3320 </member>
3321 <member name="M:Newtonsoft.Json.JsonSerializer.Serialize(System.IO.TextWriter,System.Object)">
3322 <summary>
3323 Serializes the specified <see cref="T:System.Object"/> and writes the Json structure
3324 to a <c>Stream</c> using the specified <see cref="T:System.IO.TextWriter"/>.
3325 </summary>
3326 <param name="textWriter">The <see cref="T:System.IO.TextWriter"/> used to write the Json structure.</param>
3327 <param name="value">The <see cref="T:System.Object"/> to serialize.</param>
3328 </member>
3329 <member name="M:Newtonsoft.Json.JsonSerializer.Serialize(Newtonsoft.Json.JsonWriter,System.Object)">
3330 <summary>
3331 Serializes the specified <see cref="T:System.Object"/> and writes the Json structure
3332 to a <c>Stream</c> using the specified <see cref="T:Newtonsoft.Json.JsonWriter"/>.
3333 </summary>
3334 <param name="jsonWriter">The <see cref="T:Newtonsoft.Json.JsonWriter"/> used to write the Json structure.</param>
3335 <param name="value">The <see cref="T:System.Object"/> to serialize.</param>
3336 </member>
3337 <member name="E:Newtonsoft.Json.JsonSerializer.Error">
3338 <summary>
3339 Occurs when the <see cref="T:Newtonsoft.Json.JsonSerializer"/> errors during serialization and deserialization.
3340 </summary>
3341 </member>
3342 <member name="P:Newtonsoft.Json.JsonSerializer.ReferenceResolver">
3343 <summary>
3344 Gets or sets the <see cref="T:Newtonsoft.Json.Serialization.IReferenceResolver"/> used by the serializer when resolving references.
3345 </summary>
3346 </member>
3347 <member name="P:Newtonsoft.Json.JsonSerializer.Binder">
3348 <summary>
3349 Gets or sets the <see cref="T:System.Runtime.Serialization.SerializationBinder"/> used by the serializer when resolving type names.
3350 </summary>
3351 </member>
3352 <member name="P:Newtonsoft.Json.JsonSerializer.TypeNameHandling">
3353 <summary>
3354 Gets or sets how type name writing and reading is handled by the serializer.
3355 </summary>
3356 </member>
3357 <member name="P:Newtonsoft.Json.JsonSerializer.PreserveReferencesHandling">
3358 <summary>
3359 Gets or sets how object references are preserved by the serializer.
3360 </summary>
3361 </member>
3362 <member name="P:Newtonsoft.Json.JsonSerializer.ReferenceLoopHandling">
3363 <summary>
3364 Get or set how reference loops (e.g. a class referencing itself) is handled.
3365 </summary>
3366 </member>
3367 <member name="P:Newtonsoft.Json.JsonSerializer.MissingMemberHandling">
3368 <summary>
3369 Get or set how missing members (e.g. JSON contains a property that isn't a member on the object) are handled during deserialization.
3370 </summary>
3371 </member>
3372 <member name="P:Newtonsoft.Json.JsonSerializer.NullValueHandling">
3373 <summary>
3374 Get or set how null values are handled during serialization and deserialization.
3375 </summary>
3376 </member>
3377 <member name="P:Newtonsoft.Json.JsonSerializer.DefaultValueHandling">
3378 <summary>
3379 Get or set how null default are handled during serialization and deserialization.
3380 </summary>
3381 </member>
3382 <member name="P:Newtonsoft.Json.JsonSerializer.ObjectCreationHandling">
3383 <summary>
3384 Gets or sets how objects are created during deserialization.
3385 </summary>
3386 <value>The object creation handling.</value>
3387 </member>
3388 <member name="P:Newtonsoft.Json.JsonSerializer.ConstructorHandling">
3389 <summary>
3390 Gets or sets how constructors are used during deserialization.
3391 </summary>
3392 <value>The constructor handling.</value>
3393 </member>
3394 <member name="P:Newtonsoft.Json.JsonSerializer.Converters">
3395 <summary>
3396 Gets a collection <see cref="T:Newtonsoft.Json.JsonConverter"/> that will be used during serialization.
3397 </summary>
3398 <value>Collection <see cref="T:Newtonsoft.Json.JsonConverter"/> that will be used during serialization.</value>
3399 </member>
3400 <member name="P:Newtonsoft.Json.JsonSerializer.ContractResolver">
3401 <summary>
3402 Gets or sets the contract resolver used by the serializer when
3403 serializing .NET objects to JSON and vice versa.
3404 </summary>
3405 </member>
3406 <member name="P:Newtonsoft.Json.JsonSerializer.Context">
3407 <summary>
3408 Gets or sets the <see cref="T:System.Runtime.Serialization.StreamingContext"/> used by the serializer when invoking serialization callback methods.
3409 </summary>
3410 <value>The context.</value>
3411 </member>
3412 <member name="T:Newtonsoft.Json.Linq.Extensions">
3413 <summary>
3414 Contains the LINQ to JSON extension methods.
3415 </summary>
3416 </member>
3417 <member name="M:Newtonsoft.Json.Linq.Extensions.Ancestors``1(System.Collections.Generic.IEnumerable{``0})">
3418 <summary>
3419 Returns a collection of tokens that contains the ancestors of every token in the source collection.
3420 </summary>
3421 <typeparam name="T">The type of the objects in source, constrained to <see cref="T:Newtonsoft.Json.Linq.JToken"/>.</typeparam>
3422 <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1"/> of <see cref="T:Newtonsoft.Json.Linq.JToken"/> that contains the source collection.</param>
3423 <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1"/> of <see cref="T:Newtonsoft.Json.Linq.JToken"/> that contains the ancestors of every node in the source collection.</returns>
3424 </member>
3425 <member name="M:Newtonsoft.Json.Linq.Extensions.Descendants``1(System.Collections.Generic.IEnumerable{``0})">
3426 <summary>
3427 Returns a collection of tokens that contains the descendants of every token in the source collection.
3428 </summary>
3429 <typeparam name="T">The type of the objects in source, constrained to <see cref="T:Newtonsoft.Json.Linq.JContainer"/>.</typeparam>
3430 <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1"/> of <see cref="T:Newtonsoft.Json.Linq.JToken"/> that contains the source collection.</param>
3431 <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1"/> of <see cref="T:Newtonsoft.Json.Linq.JToken"/> that contains the descendants of every node in the source collection.</returns>
3432 </member>
3433 <member name="M:Newtonsoft.Json.Linq.Extensions.Properties(System.Collections.Generic.IEnumerable{Newtonsoft.Json.Linq.JObject})">
3434 <summary>
3435 Returns a collection of child properties of every object in the source collection.
3436 </summary>
3437 <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1"/> of <see cref="T:Newtonsoft.Json.Linq.JObject"/> that contains the source collection.</param>
3438 <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1"/> of <see cref="T:Newtonsoft.Json.Linq.JProperty"/> that contains the properties of every object in the source collection.</returns>
3439 </member>
3440 <member name="M:Newtonsoft.Json.Linq.Extensions.Values(System.Collections.Generic.IEnumerable{Newtonsoft.Json.Linq.JToken},System.Object)">
3441 <summary>
3442 Returns a collection of child values of every object in the source collection with the given key.
3443 </summary>
3444 <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1"/> of <see cref="T:Newtonsoft.Json.Linq.JToken"/> that contains the source collection.</param>
3445 <param name="key">The token key.</param>
3446 <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1"/> of <see cref="T:Newtonsoft.Json.Linq.JToken"/> that contains the values of every node in the source collection with the given key.</returns>
3447 </member>
3448 <member name="M:Newtonsoft.Json.Linq.Extensions.Values(System.Collections.Generic.IEnumerable{Newtonsoft.Json.Linq.JToken})">
3449 <summary>
3450 Returns a collection of child values of every object in the source collection.
3451 </summary>
3452 <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1"/> of <see cref="T:Newtonsoft.Json.Linq.JToken"/> that contains the source collection.</param>
3453 <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1"/> of <see cref="T:Newtonsoft.Json.Linq.JToken"/> that contains the values of every node in the source collection.</returns>
3454 </member>
3455 <member name="M:Newtonsoft.Json.Linq.Extensions.Values``1(System.Collections.Generic.IEnumerable{Newtonsoft.Json.Linq.JToken},System.Object)">
3456 <summary>
3457 Returns a collection of converted child values of every object in the source collection with the given key.
3458 </summary>
3459 <typeparam name="U">The type to convert the values to.</typeparam>
3460 <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1"/> of <see cref="T:Newtonsoft.Json.Linq.JToken"/> that contains the source collection.</param>
3461 <param name="key">The token key.</param>
3462 <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1"/> that contains the converted values of every node in the source collection with the given key.</returns>
3463 </member>
3464 <member name="M:Newtonsoft.Json.Linq.Extensions.Values``1(System.Collections.Generic.IEnumerable{Newtonsoft.Json.Linq.JToken})">
3465 <summary>
3466 Returns a collection of converted child values of every object in the source collection.
3467 </summary>
3468 <typeparam name="U">The type to convert the values to.</typeparam>
3469 <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1"/> of <see cref="T:Newtonsoft.Json.Linq.JToken"/> that contains the source collection.</param>
3470 <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1"/> that contains the converted values of every node in the source collection.</returns>
3471 </member>
3472 <member name="M:Newtonsoft.Json.Linq.Extensions.Value``1(System.Collections.Generic.IEnumerable{Newtonsoft.Json.Linq.JToken})">
3473 <summary>
3474 Converts the value.
3475 </summary>
3476 <typeparam name="U">The type to convert the value to.</typeparam>
3477 <param name="value">A <see cref="T:Newtonsoft.Json.Linq.JToken"/> cast as a <see cref="T:System.Collections.Generic.IEnumerable`1"/> of <see cref="T:Newtonsoft.Json.Linq.JToken"/>.</param>
3478 <returns>A converted value.</returns>
3479 </member>
3480 <member name="M:Newtonsoft.Json.Linq.Extensions.Value``2(System.Collections.Generic.IEnumerable{``0})">
3481 <summary>
3482 Converts the value.
3483 </summary>
3484 <typeparam name="T">The source collection type.</typeparam>
3485 <typeparam name="U">The type to convert the value to.</typeparam>
3486 <param name="value">A <see cref="T:Newtonsoft.Json.Linq.JToken"/> cast as a <see cref="T:System.Collections.Generic.IEnumerable`1"/> of <see cref="T:Newtonsoft.Json.Linq.JToken"/>.</param>
3487 <returns>A converted value.</returns>
3488 </member>
3489 <member name="M:Newtonsoft.Json.Linq.Extensions.Children``1(System.Collections.Generic.IEnumerable{``0})">
3490 <summary>
3491 Returns a collection of child tokens of every array in the source collection.
3492 </summary>
3493 <typeparam name="T">The source collection type.</typeparam>
3494 <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1"/> of <see cref="T:Newtonsoft.Json.Linq.JToken"/> that contains the source collection.</param>
3495 <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1"/> of <see cref="T:Newtonsoft.Json.Linq.JToken"/> that contains the values of every node in the source collection.</returns>
3496 </member>
3497 <member name="M:Newtonsoft.Json.Linq.Extensions.Children``2(System.Collections.Generic.IEnumerable{``0})">
3498 <summary>
3499 Returns a collection of converted child tokens of every array in the source collection.
3500 </summary>
3501 <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1"/> of <see cref="T:Newtonsoft.Json.Linq.JToken"/> that contains the source collection.</param>
3502 <typeparam name="U">The type to convert the values to.</typeparam>
3503 <typeparam name="T">The source collection type.</typeparam>
3504 <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1"/> that contains the converted values of every node in the source collection.</returns>
3505 </member>
3506 <member name="M:Newtonsoft.Json.Linq.Extensions.AsJEnumerable(System.Collections.Generic.IEnumerable{Newtonsoft.Json.Linq.JToken})">
3507 <summary>
3508 Returns the input typed as <see cref="T:Newtonsoft.Json.Linq.IJEnumerable`1"/>.
3509 </summary>
3510 <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1"/> of <see cref="T:Newtonsoft.Json.Linq.JToken"/> that contains the source collection.</param>
3511 <returns>The input typed as <see cref="T:Newtonsoft.Json.Linq.IJEnumerable`1"/>.</returns>
3512 </member>
3513 <member name="M:Newtonsoft.Json.Linq.Extensions.AsJEnumerable``1(System.Collections.Generic.IEnumerable{``0})">
3514 <summary>
3515 Returns the input typed as <see cref="T:Newtonsoft.Json.Linq.IJEnumerable`1"/>.
3516 </summary>
3517 <typeparam name="T">The source collection type.</typeparam>
3518 <param name="source">An <see cref="T:System.Collections.Generic.IEnumerable`1"/> of <see cref="T:Newtonsoft.Json.Linq.JToken"/> that contains the source collection.</param>
3519 <returns>The input typed as <see cref="T:Newtonsoft.Json.Linq.IJEnumerable`1"/>.</returns>
3520 </member>
3521 <member name="T:Newtonsoft.Json.Linq.JConstructor">
3522 <summary>
3523 Represents a JSON constructor.
3524 </summary>
3525 </member>
3526 <member name="T:Newtonsoft.Json.Linq.JContainer">
3527 <summary>
3528 Represents a token that can contain other tokens.
3529 </summary>
3530 </member>
3531 <member name="M:Newtonsoft.Json.Linq.JContainer.OnAddingNew(System.ComponentModel.AddingNewEventArgs)">
3532 <summary>
3533 Raises the <see cref="E:Newtonsoft.Json.Linq.JContainer.AddingNew"/> event.
3534 </summary>
3535 <param name="e">The <see cref="T:System.ComponentModel.AddingNewEventArgs"/> instance containing the event data.</param>
3536 </member>
3537 <member name="M:Newtonsoft.Json.Linq.JContainer.OnListChanged(System.ComponentModel.ListChangedEventArgs)">
3538 <summary>
3539 Raises the <see cref="E:Newtonsoft.Json.Linq.JContainer.ListChanged"/> event.
3540 </summary>
3541 <param name="e">The <see cref="T:System.ComponentModel.ListChangedEventArgs"/> instance containing the event data.</param>
3542 </member>
3543 <member name="M:Newtonsoft.Json.Linq.JContainer.Children">
3544 <summary>
3545 Returns a collection of the child tokens of this token, in document order.
3546 </summary>
3547 <returns>
3548 An <see cref="T:System.Collections.Generic.IEnumerable`1"/> of <see cref="T:Newtonsoft.Json.Linq.JToken"/> containing the child tokens of this <see cref="T:Newtonsoft.Json.Linq.JToken"/>, in document order.
3549 </returns>
3550 </member>
3551 <member name="M:Newtonsoft.Json.Linq.JContainer.Values``1">
3552 <summary>
3553 Returns a collection of the child values of this token, in document order.
3554 </summary>
3555 <typeparam name="T">The type to convert the values to.</typeparam>
3556 <returns>
3557 A <see cref="T:System.Collections.Generic.IEnumerable`1"/> containing the child values of this <see cref="T:Newtonsoft.Json.Linq.JToken"/>, in document order.
3558 </returns>
3559 </member>
3560 <member name="M:Newtonsoft.Json.Linq.JContainer.Descendants">
3561 <summary>
3562 Returns a collection of the descendant tokens for this token in document order.
3563 </summary>
3564 <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1"/> containing the descendant tokens of the <see cref="T:Newtonsoft.Json.Linq.JToken"/>.</returns>
3565 </member>
3566 <member name="M:Newtonsoft.Json.Linq.JContainer.Add(System.Object)">
3567 <summary>
3568 Adds the specified content as children of this <see cref="T:Newtonsoft.Json.Linq.JToken"/>.
3569 </summary>
3570 <param name="content">The content to be added.</param>
3571 </member>
3572 <member name="M:Newtonsoft.Json.Linq.JContainer.AddFirst(System.Object)">
3573 <summary>
3574 Adds the specified content as the first children of this <see cref="T:Newtonsoft.Json.Linq.JToken"/>.
3575 </summary>
3576 <param name="content">The content to be added.</param>
3577 </member>
3578 <member name="M:Newtonsoft.Json.Linq.JContainer.CreateWriter">
3579 <summary>
3580 Creates an <see cref="T:Newtonsoft.Json.JsonWriter"/> that can be used to add tokens to the <see cref="T:Newtonsoft.Json.Linq.JToken"/>.
3581 </summary>
3582 <returns>An <see cref="T:Newtonsoft.Json.JsonWriter"/> that is ready to have content written to it.</returns>
3583 </member>
3584 <member name="M:Newtonsoft.Json.Linq.JContainer.ReplaceAll(System.Object)">
3585 <summary>
3586 Replaces the children nodes of this token with the specified content.
3587 </summary>
3588 <param name="content">The content.</param>
3589 </member>
3590 <member name="M:Newtonsoft.Json.Linq.JContainer.RemoveAll">
3591 <summary>
3592 Removes the child nodes from this token.
3593 </summary>
3594 </member>
3595 <member name="E:Newtonsoft.Json.Linq.JContainer.ListChanged">
3596 <summary>
3597 Occurs when the list changes or an item in the list changes.
3598 </summary>
3599 </member>
3600 <member name="E:Newtonsoft.Json.Linq.JContainer.AddingNew">
3601 <summary>
3602 Occurs before an item is added to the collection.
3603 </summary>
3604 </member>
3605 <member name="P:Newtonsoft.Json.Linq.JContainer.HasValues">
3606 <summary>
3607 Gets a value indicating whether this token has childen tokens.
3608 </summary>
3609 <value>
3610 <c>true</c> if this token has child values; otherwise, <c>false</c>.
3611 </value>
3612 </member>
3613 <member name="P:Newtonsoft.Json.Linq.JContainer.First">
3614 <summary>
3615 Get the first child token of this token.
3616 </summary>
3617 <value>
3618 A <see cref="T:Newtonsoft.Json.Linq.JToken"/> containing the first child token of the <see cref="T:Newtonsoft.Json.Linq.JToken"/>.
3619 </value>
3620 </member>
3621 <member name="P:Newtonsoft.Json.Linq.JContainer.Last">
3622 <summary>
3623 Get the last child token of this token.
3624 </summary>
3625 <value>
3626 A <see cref="T:Newtonsoft.Json.Linq.JToken"/> containing the last child token of the <see cref="T:Newtonsoft.Json.Linq.JToken"/>.
3627 </value>
3628 </member>
3629 <member name="M:Newtonsoft.Json.Linq.JConstructor.#ctor">
3630 <summary>
3631 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Linq.JConstructor"/> class.
3632 </summary>
3633 </member>
3634 <member name="M:Newtonsoft.Json.Linq.JConstructor.#ctor(Newtonsoft.Json.Linq.JConstructor)">
3635 <summary>
3636 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Linq.JConstructor"/> class from another <see cref="T:Newtonsoft.Json.Linq.JConstructor"/> object.
3637 </summary>
3638 <param name="other">A <see cref="T:Newtonsoft.Json.Linq.JConstructor"/> object to copy from.</param>
3639 </member>
3640 <member name="M:Newtonsoft.Json.Linq.JConstructor.#ctor(System.String,System.Object[])">
3641 <summary>
3642 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Linq.JConstructor"/> class with the specified name and content.
3643 </summary>
3644 <param name="name">The constructor name.</param>
3645 <param name="content">The contents of the constructor.</param>
3646 </member>
3647 <member name="M:Newtonsoft.Json.Linq.JConstructor.#ctor(System.String,System.Object)">
3648 <summary>
3649 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Linq.JConstructor"/> class with the specified name and content.
3650 </summary>
3651 <param name="name">The constructor name.</param>
3652 <param name="content">The contents of the constructor.</param>
3653 </member>
3654 <member name="M:Newtonsoft.Json.Linq.JConstructor.#ctor(System.String)">
3655 <summary>
3656 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Linq.JConstructor"/> class with the specified name.
3657 </summary>
3658 <param name="name">The constructor name.</param>
3659 </member>
3660 <member name="M:Newtonsoft.Json.Linq.JConstructor.WriteTo(Newtonsoft.Json.JsonWriter,Newtonsoft.Json.JsonConverter[])">
3661 <summary>
3662 Writes this token to a <see cref="T:Newtonsoft.Json.JsonWriter"/>.
3663 </summary>
3664 <param name="writer">A <see cref="T:Newtonsoft.Json.JsonWriter"/> into which this method will write.</param>
3665 <param name="converters">A collection of <see cref="T:Newtonsoft.Json.JsonConverter"/> which will be used when writing the token.</param>
3666 </member>
3667 <member name="M:Newtonsoft.Json.Linq.JConstructor.Load(Newtonsoft.Json.JsonReader)">
3668 <summary>
3669 Loads an <see cref="T:Newtonsoft.Json.Linq.JConstructor"/> from a <see cref="T:Newtonsoft.Json.JsonReader"/>.
3670 </summary>
3671 <param name="reader">A <see cref="T:Newtonsoft.Json.JsonReader"/> that will be read for the content of the <see cref="T:Newtonsoft.Json.Linq.JConstructor"/>.</param>
3672 <returns>A <see cref="T:Newtonsoft.Json.Linq.JConstructor"/> that contains the JSON that was read from the specified <see cref="T:Newtonsoft.Json.JsonReader"/>.</returns>
3673 </member>
3674 <member name="P:Newtonsoft.Json.Linq.JConstructor.Name">
3675 <summary>
3676 Gets or sets the name of this constructor.
3677 </summary>
3678 <value>The constructor name.</value>
3679 </member>
3680 <member name="P:Newtonsoft.Json.Linq.JConstructor.Type">
3681 <summary>
3682 Gets the node type for this <see cref="T:Newtonsoft.Json.Linq.JToken"/>.
3683 </summary>
3684 <value>The type.</value>
3685 </member>
3686 <member name="P:Newtonsoft.Json.Linq.JConstructor.Item(System.Object)">
3687 <summary>
3688 Gets the <see cref="T:Newtonsoft.Json.Linq.JToken"/> with the specified key.
3689 </summary>
3690 <value>The <see cref="T:Newtonsoft.Json.Linq.JToken"/> with the specified key.</value>
3691 </member>
3692 <member name="T:Newtonsoft.Json.Linq.JEnumerable`1">
3693 <summary>
3694 Represents a collection of <see cref="T:Newtonsoft.Json.Linq.JToken"/> objects.
3695 </summary>
3696 <typeparam name="T">The type of token</typeparam>
3697 </member>
3698 <member name="F:Newtonsoft.Json.Linq.JEnumerable`1.Empty">
3699 <summary>
3700 An empty collection of <see cref="T:Newtonsoft.Json.Linq.JToken"/> objects.
3701 </summary>
3702 </member>
3703 <member name="M:Newtonsoft.Json.Linq.JEnumerable`1.#ctor(System.Collections.Generic.IEnumerable{`0})">
3704 <summary>
3705 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Linq.JEnumerable`1"/> struct.
3706 </summary>
3707 <param name="enumerable">The enumerable.</param>
3708 </member>
3709 <member name="M:Newtonsoft.Json.Linq.JEnumerable`1.GetEnumerator">
3710 <summary>
3711 Returns an enumerator that iterates through the collection.
3712 </summary>
3713 <returns>
3714 A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.
3715 </returns>
3716 </member>
3717 <member name="M:Newtonsoft.Json.Linq.JEnumerable`1.System#Collections#IEnumerable#GetEnumerator">
3718 <summary>
3719 Returns an enumerator that iterates through a collection.
3720 </summary>
3721 <returns>
3722 An <see cref="T:System.Collections.IEnumerator"/> object that can be used to iterate through the collection.
3723 </returns>
3724 </member>
3725 <member name="M:Newtonsoft.Json.Linq.JEnumerable`1.Equals(System.Object)">
3726 <summary>
3727 Determines whether the specified <see cref="T:System.Object"/> is equal to this instance.
3728 </summary>
3729 <param name="obj">The <see cref="T:System.Object"/> to compare with this instance.</param>
3730 <returns>
3731 <c>true</c> if the specified <see cref="T:System.Object"/> is equal to this instance; otherwise, <c>false</c>.
3732 </returns>
3733 </member>
3734 <member name="M:Newtonsoft.Json.Linq.JEnumerable`1.GetHashCode">
3735 <summary>
3736 Returns a hash code for this instance.
3737 </summary>
3738 <returns>
3739 A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
3740 </returns>
3741 </member>
3742 <member name="P:Newtonsoft.Json.Linq.JEnumerable`1.Item(System.Object)">
3743 <summary>
3744 Gets the <see cref="T:Newtonsoft.Json.Linq.IJEnumerable`1"/> with the specified key.
3745 </summary>
3746 <value></value>
3747 </member>
3748 <member name="T:Newtonsoft.Json.Linq.JObject">
3749 <summary>
3750 Represents a JSON object.
3751 </summary>
3752 </member>
3753 <member name="M:Newtonsoft.Json.Linq.JObject.#ctor">
3754 <summary>
3755 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Linq.JObject"/> class.
3756 </summary>
3757 </member>
3758 <member name="M:Newtonsoft.Json.Linq.JObject.#ctor(Newtonsoft.Json.Linq.JObject)">
3759 <summary>
3760 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Linq.JObject"/> class from another <see cref="T:Newtonsoft.Json.Linq.JObject"/> object.
3761 </summary>
3762 <param name="other">A <see cref="T:Newtonsoft.Json.Linq.JObject"/> object to copy from.</param>
3763 </member>
3764 <member name="M:Newtonsoft.Json.Linq.JObject.#ctor(System.Object[])">
3765 <summary>
3766 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Linq.JObject"/> class with the specified content.
3767 </summary>
3768 <param name="content">The contents of the object.</param>
3769 </member>
3770 <member name="M:Newtonsoft.Json.Linq.JObject.#ctor(System.Object)">
3771 <summary>
3772 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Linq.JObject"/> class with the specified content.
3773 </summary>
3774 <param name="content">The contents of the object.</param>
3775 </member>
3776 <member name="M:Newtonsoft.Json.Linq.JObject.Properties">
3777 <summary>
3778 Gets an <see cref="T:System.Collections.Generic.IEnumerable`1"/> of this object's properties.
3779 </summary>
3780 <returns>An <see cref="T:System.Collections.Generic.IEnumerable`1"/> of this object's properties.</returns>
3781 </member>
3782 <member name="M:Newtonsoft.Json.Linq.JObject.Property(System.String)">
3783 <summary>
3784 Gets a <see cref="T:Newtonsoft.Json.Linq.JProperty"/> the specified name.
3785 </summary>
3786 <param name="name">The property name.</param>
3787 <returns>A <see cref="T:Newtonsoft.Json.Linq.JProperty"/> with the specified name or null.</returns>
3788 </member>
3789 <member name="M:Newtonsoft.Json.Linq.JObject.PropertyValues">
3790 <summary>
3791 Gets an <see cref="T:Newtonsoft.Json.Linq.JEnumerable`1"/> of this object's property values.
3792 </summary>
3793 <returns>An <see cref="T:Newtonsoft.Json.Linq.JEnumerable`1"/> of this object's property values.</returns>
3794 </member>
3795 <member name="M:Newtonsoft.Json.Linq.JObject.Load(Newtonsoft.Json.JsonReader)">
3796 <summary>
3797 Loads an <see cref="T:Newtonsoft.Json.Linq.JObject"/> from a <see cref="T:Newtonsoft.Json.JsonReader"/>.
3798 </summary>
3799 <param name="reader">A <see cref="T:Newtonsoft.Json.JsonReader"/> that will be read for the content of the <see cref="T:Newtonsoft.Json.Linq.JObject"/>.</param>
3800 <returns>A <see cref="T:Newtonsoft.Json.Linq.JObject"/> that contains the JSON that was read from the specified <see cref="T:Newtonsoft.Json.JsonReader"/>.</returns>
3801 </member>
3802 <member name="M:Newtonsoft.Json.Linq.JObject.Parse(System.String)">
3803 <summary>
3804 Load a <see cref="T:Newtonsoft.Json.Linq.JObject"/> from a string that contains JSON.
3805 </summary>
3806 <param name="json">A <see cref="T:System.String"/> that contains JSON.</param>
3807 <returns>A <see cref="T:Newtonsoft.Json.Linq.JObject"/> populated from the string that contains JSON.</returns>
3808 </member>
3809 <member name="M:Newtonsoft.Json.Linq.JObject.FromObject(System.Object)">
3810 <summary>
3811 Creates a <see cref="T:Newtonsoft.Json.Linq.JObject"/> from an object.
3812 </summary>
3813 <param name="o">The object that will be used to create <see cref="T:Newtonsoft.Json.Linq.JObject"/>.</param>
3814 <returns>A <see cref="T:Newtonsoft.Json.Linq.JObject"/> with the values of the specified object</returns>
3815 </member>
3816 <member name="M:Newtonsoft.Json.Linq.JObject.FromObject(System.Object,Newtonsoft.Json.JsonSerializer)">
3817 <summary>
3818 Creates a <see cref="T:Newtonsoft.Json.Linq.JArray"/> from an object.
3819 </summary>
3820 <param name="o">The object that will be used to create <see cref="T:Newtonsoft.Json.Linq.JArray"/>.</param>
3821 <param name="jsonSerializer">The <see cref="T:Newtonsoft.Json.JsonSerializer"/> that will be used to read the object.</param>
3822 <returns>A <see cref="T:Newtonsoft.Json.Linq.JArray"/> with the values of the specified object</returns>
3823 </member>
3824 <member name="M:Newtonsoft.Json.Linq.JObject.WriteTo(Newtonsoft.Json.JsonWriter,Newtonsoft.Json.JsonConverter[])">
3825 <summary>
3826 Writes this token to a <see cref="T:Newtonsoft.Json.JsonWriter"/>.
3827 </summary>
3828 <param name="writer">A <see cref="T:Newtonsoft.Json.JsonWriter"/> into which this method will write.</param>
3829 <param name="converters">A collection of <see cref="T:Newtonsoft.Json.JsonConverter"/> which will be used when writing the token.</param>
3830 </member>
3831 <member name="M:Newtonsoft.Json.Linq.JObject.Add(System.String,Newtonsoft.Json.Linq.JToken)">
3832 <summary>
3833 Adds the specified property name.
3834 </summary>
3835 <param name="propertyName">Name of the property.</param>
3836 <param name="value">The value.</param>
3837 </member>
3838 <member name="M:Newtonsoft.Json.Linq.JObject.Remove(System.String)">
3839 <summary>
3840 Removes the property with the specified name.
3841 </summary>
3842 <param name="propertyName">Name of the property.</param>
3843 <returns>true if item was successfully removed; otherwise, false.</returns>
3844 </member>
3845 <member name="M:Newtonsoft.Json.Linq.JObject.TryGetValue(System.String,Newtonsoft.Json.Linq.JToken@)">
3846 <summary>
3847 Tries the get value.
3848 </summary>
3849 <param name="propertyName">Name of the property.</param>
3850 <param name="value">The value.</param>
3851 <returns>true if a value was successfully retrieved; otherwise, false.</returns>
3852 </member>
3853 <member name="M:Newtonsoft.Json.Linq.JObject.GetEnumerator">
3854 <summary>
3855 Returns an enumerator that iterates through the collection.
3856 </summary>
3857 <returns>
3858 A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.
3859 </returns>
3860 </member>
3861 <member name="M:Newtonsoft.Json.Linq.JObject.OnPropertyChanged(System.String)">
3862 <summary>
3863 Raises the <see cref="E:Newtonsoft.Json.Linq.JObject.PropertyChanged"/> event with the provided arguments.
3864 </summary>
3865 <param name="propertyName">Name of the property.</param>
3866 </member>
3867 <member name="E:Newtonsoft.Json.Linq.JObject.PropertyChanged">
3868 <summary>
3869 Occurs when a property value changes.
3870 </summary>
3871 </member>
3872 <member name="P:Newtonsoft.Json.Linq.JObject.Type">
3873 <summary>
3874 Gets the node type for this <see cref="T:Newtonsoft.Json.Linq.JToken"/>.
3875 </summary>
3876 <value>The type.</value>
3877 </member>
3878 <member name="P:Newtonsoft.Json.Linq.JObject.Item(System.Object)">
3879 <summary>
3880 Gets the <see cref="T:Newtonsoft.Json.Linq.JToken"/> with the specified key.
3881 </summary>
3882 <value>The <see cref="T:Newtonsoft.Json.Linq.JToken"/> with the specified key.</value>
3883 </member>
3884 <member name="P:Newtonsoft.Json.Linq.JObject.Item(System.String)">
3885 <summary>
3886 Gets or sets the <see cref="T:Newtonsoft.Json.Linq.JToken"/> with the specified property name.
3887 </summary>
3888 <value></value>
3889 </member>
3890 <member name="P:Newtonsoft.Json.Linq.JObject.Count">
3891 <summary>
3892 Gets the number of elements contained in the <see cref="T:System.Collections.Generic.ICollection`1"/>.
3893 </summary>
3894 <value></value>
3895 <returns>The number of elements contained in the <see cref="T:System.Collections.Generic.ICollection`1"/>.</returns>
3896 </member>
3897 <member name="T:Newtonsoft.Json.Linq.JArray">
3898 <summary>
3899 Represents a JSON array.
3900 </summary>
3901 </member>
3902 <member name="M:Newtonsoft.Json.Linq.JArray.#ctor">
3903 <summary>
3904 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Linq.JArray"/> class.
3905 </summary>
3906 </member>
3907 <member name="M:Newtonsoft.Json.Linq.JArray.#ctor(Newtonsoft.Json.Linq.JArray)">
3908 <summary>
3909 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Linq.JArray"/> class from another <see cref="T:Newtonsoft.Json.Linq.JArray"/> object.
3910 </summary>
3911 <param name="other">A <see cref="T:Newtonsoft.Json.Linq.JArray"/> object to copy from.</param>
3912 </member>
3913 <member name="M:Newtonsoft.Json.Linq.JArray.#ctor(System.Object[])">
3914 <summary>
3915 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Linq.JArray"/> class with the specified content.
3916 </summary>
3917 <param name="content">The contents of the array.</param>
3918 </member>
3919 <member name="M:Newtonsoft.Json.Linq.JArray.#ctor(System.Object)">
3920 <summary>
3921 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Linq.JArray"/> class with the specified content.
3922 </summary>
3923 <param name="content">The contents of the array.</param>
3924 </member>
3925 <member name="M:Newtonsoft.Json.Linq.JArray.Load(Newtonsoft.Json.JsonReader)">
3926 <summary>
3927 Loads an <see cref="T:Newtonsoft.Json.Linq.JArray"/> from a <see cref="T:Newtonsoft.Json.JsonReader"/>.
3928 </summary>
3929 <param name="reader">A <see cref="T:Newtonsoft.Json.JsonReader"/> that will be read for the content of the <see cref="T:Newtonsoft.Json.Linq.JArray"/>.</param>
3930 <returns>A <see cref="T:Newtonsoft.Json.Linq.JArray"/> that contains the JSON that was read from the specified <see cref="T:Newtonsoft.Json.JsonReader"/>.</returns>
3931 </member>
3932 <member name="M:Newtonsoft.Json.Linq.JArray.Parse(System.String)">
3933 <summary>
3934 Load a <see cref="T:Newtonsoft.Json.Linq.JArray"/> from a string that contains JSON.
3935 </summary>
3936 <param name="json">A <see cref="T:System.String"/> that contains JSON.</param>
3937 <returns>A <see cref="T:Newtonsoft.Json.Linq.JArray"/> populated from the string that contains JSON.</returns>
3938 </member>
3939 <member name="M:Newtonsoft.Json.Linq.JArray.FromObject(System.Object)">
3940 <summary>
3941 Creates a <see cref="T:Newtonsoft.Json.Linq.JArray"/> from an object.
3942 </summary>
3943 <param name="o">The object that will be used to create <see cref="T:Newtonsoft.Json.Linq.JArray"/>.</param>
3944 <returns>A <see cref="T:Newtonsoft.Json.Linq.JArray"/> with the values of the specified object</returns>
3945 </member>
3946 <member name="M:Newtonsoft.Json.Linq.JArray.FromObject(System.Object,Newtonsoft.Json.JsonSerializer)">
3947 <summary>
3948 Creates a <see cref="T:Newtonsoft.Json.Linq.JArray"/> from an object.
3949 </summary>
3950 <param name="o">The object that will be used to create <see cref="T:Newtonsoft.Json.Linq.JArray"/>.</param>
3951 <param name="jsonSerializer">The <see cref="T:Newtonsoft.Json.JsonSerializer"/> that will be used to read the object.</param>
3952 <returns>A <see cref="T:Newtonsoft.Json.Linq.JArray"/> with the values of the specified object</returns>
3953 </member>
3954 <member name="M:Newtonsoft.Json.Linq.JArray.WriteTo(Newtonsoft.Json.JsonWriter,Newtonsoft.Json.JsonConverter[])">
3955 <summary>
3956 Writes this token to a <see cref="T:Newtonsoft.Json.JsonWriter"/>.
3957 </summary>
3958 <param name="writer">A <see cref="T:Newtonsoft.Json.JsonWriter"/> into which this method will write.</param>
3959 <param name="converters">A collection of <see cref="T:Newtonsoft.Json.JsonConverter"/> which will be used when writing the token.</param>
3960 </member>
3961 <member name="M:Newtonsoft.Json.Linq.JArray.IndexOf(Newtonsoft.Json.Linq.JToken)">
3962 <summary>
3963 Determines the index of a specific item in the <see cref="T:System.Collections.Generic.IList`1"/>.
3964 </summary>
3965 <param name="item">The object to locate in the <see cref="T:System.Collections.Generic.IList`1"/>.</param>
3966 <returns>
3967 The index of <paramref name="item"/> if found in the list; otherwise, -1.
3968 </returns>
3969 </member>
3970 <member name="M:Newtonsoft.Json.Linq.JArray.Insert(System.Int32,Newtonsoft.Json.Linq.JToken)">
3971 <summary>
3972 Inserts an item to the <see cref="T:System.Collections.Generic.IList`1"/> at the specified index.
3973 </summary>
3974 <param name="index">The zero-based index at which <paramref name="item"/> should be inserted.</param>
3975 <param name="item">The object to insert into the <see cref="T:System.Collections.Generic.IList`1"/>.</param>
3976 <exception cref="T:System.ArgumentOutOfRangeException">
3977 <paramref name="index"/> is not a valid index in the <see cref="T:System.Collections.Generic.IList`1"/>.</exception>
3978 <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.IList`1"/> is read-only.</exception>
3979 </member>
3980 <member name="M:Newtonsoft.Json.Linq.JArray.RemoveAt(System.Int32)">
3981 <summary>
3982 Removes the <see cref="T:System.Collections.Generic.IList`1"/> item at the specified index.
3983 </summary>
3984 <param name="index">The zero-based index of the item to remove.</param>
3985 <exception cref="T:System.ArgumentOutOfRangeException">
3986 <paramref name="index"/> is not a valid index in the <see cref="T:System.Collections.Generic.IList`1"/>.</exception>
3987 <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.IList`1"/> is read-only.</exception>
3988 </member>
3989 <member name="M:Newtonsoft.Json.Linq.JArray.Add(Newtonsoft.Json.Linq.JToken)">
3990 <summary>
3991 Adds an item to the <see cref="T:System.Collections.Generic.ICollection`1"/>.
3992 </summary>
3993 <param name="item">The object to add to the <see cref="T:System.Collections.Generic.ICollection`1"/>.</param>
3994 <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only.</exception>
3995 </member>
3996 <member name="M:Newtonsoft.Json.Linq.JArray.Clear">
3997 <summary>
3998 Removes all items from the <see cref="T:System.Collections.Generic.ICollection`1"/>.
3999 </summary>
4000 <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only. </exception>
4001 </member>
4002 <member name="M:Newtonsoft.Json.Linq.JArray.Contains(Newtonsoft.Json.Linq.JToken)">
4003 <summary>
4004 Determines whether the <see cref="T:System.Collections.Generic.ICollection`1"/> contains a specific value.
4005 </summary>
4006 <param name="item">The object to locate in the <see cref="T:System.Collections.Generic.ICollection`1"/>.</param>
4007 <returns>
4008 true if <paramref name="item"/> is found in the <see cref="T:System.Collections.Generic.ICollection`1"/>; otherwise, false.
4009 </returns>
4010 </member>
4011 <member name="M:Newtonsoft.Json.Linq.JArray.Remove(Newtonsoft.Json.Linq.JToken)">
4012 <summary>
4013 Removes the first occurrence of a specific object from the <see cref="T:System.Collections.Generic.ICollection`1"/>.
4014 </summary>
4015 <param name="item">The object to remove from the <see cref="T:System.Collections.Generic.ICollection`1"/>.</param>
4016 <returns>
4017 true if <paramref name="item"/> was successfully removed from the <see cref="T:System.Collections.Generic.ICollection`1"/>; otherwise, false. This method also returns false if <paramref name="item"/> is not found in the original <see cref="T:System.Collections.Generic.ICollection`1"/>.
4018 </returns>
4019 <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only.</exception>
4020 </member>
4021 <member name="P:Newtonsoft.Json.Linq.JArray.Type">
4022 <summary>
4023 Gets the node type for this <see cref="T:Newtonsoft.Json.Linq.JToken"/>.
4024 </summary>
4025 <value>The type.</value>
4026 </member>
4027 <member name="P:Newtonsoft.Json.Linq.JArray.Item(System.Object)">
4028 <summary>
4029 Gets the <see cref="T:Newtonsoft.Json.Linq.JToken"/> with the specified key.
4030 </summary>
4031 <value>The <see cref="T:Newtonsoft.Json.Linq.JToken"/> with the specified key.</value>
4032 </member>
4033 <member name="P:Newtonsoft.Json.Linq.JArray.Item(System.Int32)">
4034 <summary>
4035 Gets or sets the <see cref="T:Newtonsoft.Json.Linq.JToken"/> at the specified index.
4036 </summary>
4037 <value></value>
4038 </member>
4039 <member name="P:Newtonsoft.Json.Linq.JArray.Count">
4040 <summary>
4041 Gets the number of elements contained in the <see cref="T:System.Collections.Generic.ICollection`1"/>.
4042 </summary>
4043 <value></value>
4044 <returns>The number of elements contained in the <see cref="T:System.Collections.Generic.ICollection`1"/>.</returns>
4045 </member>
4046 <member name="T:Newtonsoft.Json.Linq.JTokenReader">
4047 <summary>
4048 Represents a reader that provides fast, non-cached, forward-only access to serialized Json data.
4049 </summary>
4050 </member>
4051 <member name="M:Newtonsoft.Json.Linq.JTokenReader.#ctor(Newtonsoft.Json.Linq.JToken)">
4052 <summary>
4053 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Linq.JTokenReader"/> class.
4054 </summary>
4055 <param name="token">The token to read from.</param>
4056 </member>
4057 <member name="M:Newtonsoft.Json.Linq.JTokenReader.ReadAsBytes">
4058 <summary>
4059 Reads the next JSON token from the stream as a <see cref="T:Byte[]"/>.
4060 </summary>
4061 <returns>
4062 A <see cref="T:Byte[]"/> or a null reference if the next JSON token is null.
4063 </returns>
4064 </member>
4065 <member name="M:Newtonsoft.Json.Linq.JTokenReader.Read">
4066 <summary>
4067 Reads the next JSON token from the stream.
4068 </summary>
4069 <returns>
4070 true if the next token was read successfully; false if there are no more tokens to read.
4071 </returns>
4072 </member>
4073 <member name="T:Newtonsoft.Json.Linq.JProperty">
4074 <summary>
4075 Represents a JSON property.
4076 </summary>
4077 </member>
4078 <member name="M:Newtonsoft.Json.Linq.JProperty.#ctor(Newtonsoft.Json.Linq.JProperty)">
4079 <summary>
4080 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Linq.JProperty"/> class from another <see cref="T:Newtonsoft.Json.Linq.JProperty"/> object.
4081 </summary>
4082 <param name="other">A <see cref="T:Newtonsoft.Json.Linq.JProperty"/> object to copy from.</param>
4083 </member>
4084 <member name="M:Newtonsoft.Json.Linq.JProperty.Children">
4085 <summary>
4086 Returns a collection of the child tokens of this token, in document order.
4087 </summary>
4088 <returns>
4089 An <see cref="T:System.Collections.Generic.IEnumerable`1"/> of <see cref="T:Newtonsoft.Json.Linq.JToken"/> containing the child tokens of this <see cref="T:Newtonsoft.Json.Linq.JToken"/>, in document order.
4090 </returns>
4091 </member>
4092 <member name="M:Newtonsoft.Json.Linq.JProperty.#ctor(System.String,System.Object[])">
4093 <summary>
4094 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Linq.JProperty"/> class.
4095 </summary>
4096 <param name="name">The property name.</param>
4097 <param name="content">The property content.</param>
4098 </member>
4099 <member name="M:Newtonsoft.Json.Linq.JProperty.#ctor(System.String,System.Object)">
4100 <summary>
4101 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Linq.JProperty"/> class.
4102 </summary>
4103 <param name="name">The property name.</param>
4104 <param name="content">The property content.</param>
4105 </member>
4106 <member name="M:Newtonsoft.Json.Linq.JProperty.WriteTo(Newtonsoft.Json.JsonWriter,Newtonsoft.Json.JsonConverter[])">
4107 <summary>
4108 Writes this token to a <see cref="T:Newtonsoft.Json.JsonWriter"/>.
4109 </summary>
4110 <param name="writer">A <see cref="T:Newtonsoft.Json.JsonWriter"/> into which this method will write.</param>
4111 <param name="converters">A collection of <see cref="T:Newtonsoft.Json.JsonConverter"/> which will be used when writing the token.</param>
4112 </member>
4113 <member name="M:Newtonsoft.Json.Linq.JProperty.Load(Newtonsoft.Json.JsonReader)">
4114 <summary>
4115 Loads an <see cref="T:Newtonsoft.Json.Linq.JProperty"/> from a <see cref="T:Newtonsoft.Json.JsonReader"/>.
4116 </summary>
4117 <param name="reader">A <see cref="T:Newtonsoft.Json.JsonReader"/> that will be read for the content of the <see cref="T:Newtonsoft.Json.Linq.JProperty"/>.</param>
4118 <returns>A <see cref="T:Newtonsoft.Json.Linq.JProperty"/> that contains the JSON that was read from the specified <see cref="T:Newtonsoft.Json.JsonReader"/>.</returns>
4119 </member>
4120 <member name="P:Newtonsoft.Json.Linq.JProperty.Name">
4121 <summary>
4122 Gets the property name.
4123 </summary>
4124 <value>The property name.</value>
4125 </member>
4126 <member name="P:Newtonsoft.Json.Linq.JProperty.Value">
4127 <summary>
4128 Gets or sets the property value.
4129 </summary>
4130 <value>The property value.</value>
4131 </member>
4132 <member name="P:Newtonsoft.Json.Linq.JProperty.Type">
4133 <summary>
4134 Gets the node type for this <see cref="T:Newtonsoft.Json.Linq.JToken"/>.
4135 </summary>
4136 <value>The type.</value>
4137 </member>
4138 <member name="T:Newtonsoft.Json.Linq.JTokenType">
4139 <summary>
4140 Specifies the type of token.
4141 </summary>
4142 </member>
4143 <member name="F:Newtonsoft.Json.Linq.JTokenType.None">
4144 <summary>
4145 No token type has been set.
4146 </summary>
4147 </member>
4148 <member name="F:Newtonsoft.Json.Linq.JTokenType.Object">
4149 <summary>
4150 A JSON object.
4151 </summary>
4152 </member>
4153 <member name="F:Newtonsoft.Json.Linq.JTokenType.Array">
4154 <summary>
4155 A JSON array.
4156 </summary>
4157 </member>
4158 <member name="F:Newtonsoft.Json.Linq.JTokenType.Constructor">
4159 <summary>
4160 A JSON constructor.
4161 </summary>
4162 </member>
4163 <member name="F:Newtonsoft.Json.Linq.JTokenType.Property">
4164 <summary>
4165 A JSON object property.
4166 </summary>
4167 </member>
4168 <member name="F:Newtonsoft.Json.Linq.JTokenType.Comment">
4169 <summary>
4170 A comment.
4171 </summary>
4172 </member>
4173 <member name="F:Newtonsoft.Json.Linq.JTokenType.Integer">
4174 <summary>
4175 An integer value.
4176 </summary>
4177 </member>
4178 <member name="F:Newtonsoft.Json.Linq.JTokenType.Float">
4179 <summary>
4180 A float value.
4181 </summary>
4182 </member>
4183 <member name="F:Newtonsoft.Json.Linq.JTokenType.String">
4184 <summary>
4185 A string value.
4186 </summary>
4187 </member>
4188 <member name="F:Newtonsoft.Json.Linq.JTokenType.Boolean">
4189 <summary>
4190 A boolean value.
4191 </summary>
4192 </member>
4193 <member name="F:Newtonsoft.Json.Linq.JTokenType.Null">
4194 <summary>
4195 A null value.
4196 </summary>
4197 </member>
4198 <member name="F:Newtonsoft.Json.Linq.JTokenType.Undefined">
4199 <summary>
4200 An undefined value.
4201 </summary>
4202 </member>
4203 <member name="F:Newtonsoft.Json.Linq.JTokenType.Date">
4204 <summary>
4205 A date value.
4206 </summary>
4207 </member>
4208 <member name="F:Newtonsoft.Json.Linq.JTokenType.Raw">
4209 <summary>
4210 A raw JSON value.
4211 </summary>
4212 </member>
4213 <member name="F:Newtonsoft.Json.Linq.JTokenType.Bytes">
4214 <summary>
4215 A collection of bytes value.
4216 </summary>
4217 </member>
4218 <member name="T:Newtonsoft.Json.Schema.Extensions">
4219 <summary>
4220 Contains the JSON schema extension methods.
4221 </summary>
4222 </member>
4223 <member name="M:Newtonsoft.Json.Schema.Extensions.IsValid(Newtonsoft.Json.Linq.JToken,Newtonsoft.Json.Schema.JsonSchema)">
4224 <summary>
4225 Determines whether the <see cref="T:Newtonsoft.Json.Linq.JToken"/> is valid.
4226 </summary>
4227 <param name="source">The source <see cref="T:Newtonsoft.Json.Linq.JToken"/> to test.</param>
4228 <param name="schema">The schema to test with.</param>
4229 <returns>
4230 <c>true</c> if the specified <see cref="T:Newtonsoft.Json.Linq.JToken"/> is valid; otherwise, <c>false</c>.
4231 </returns>
4232 </member>
4233 <member name="M:Newtonsoft.Json.Schema.Extensions.Validate(Newtonsoft.Json.Linq.JToken,Newtonsoft.Json.Schema.JsonSchema)">
4234 <summary>
4235 Validates the specified <see cref="T:Newtonsoft.Json.Linq.JToken"/>.
4236 </summary>
4237 <param name="source">The source <see cref="T:Newtonsoft.Json.Linq.JToken"/> to test.</param>
4238 <param name="schema">The schema to test with.</param>
4239 </member>
4240 <member name="M:Newtonsoft.Json.Schema.Extensions.Validate(Newtonsoft.Json.Linq.JToken,Newtonsoft.Json.Schema.JsonSchema,Newtonsoft.Json.Schema.ValidationEventHandler)">
4241 <summary>
4242 Validates the specified <see cref="T:Newtonsoft.Json.Linq.JToken"/>.
4243 </summary>
4244 <param name="source">The source <see cref="T:Newtonsoft.Json.Linq.JToken"/> to test.</param>
4245 <param name="schema">The schema to test with.</param>
4246 <param name="validationEventHandler">The validation event handler.</param>
4247 </member>
4248 <member name="T:Newtonsoft.Json.Schema.JsonSchemaException">
4249 <summary>
4250 Returns detailed information about the schema exception.
4251 </summary>
4252 </member>
4253 <member name="M:Newtonsoft.Json.Schema.JsonSchemaException.#ctor">
4254 <summary>
4255 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Schema.JsonSchemaException"/> class.
4256 </summary>
4257 </member>
4258 <member name="M:Newtonsoft.Json.Schema.JsonSchemaException.#ctor(System.String)">
4259 <summary>
4260 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Schema.JsonSchemaException"/> class
4261 with a specified error message.
4262 </summary>
4263 <param name="message">The error message that explains the reason for the exception.</param>
4264 </member>
4265 <member name="M:Newtonsoft.Json.Schema.JsonSchemaException.#ctor(System.String,System.Exception)">
4266 <summary>
4267 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Schema.JsonSchemaException"/> class
4268 with a specified error message and a reference to the inner exception that is the cause of this exception.
4269 </summary>
4270 <param name="message">The error message that explains the reason for the exception.</param>
4271 <param name="innerException">The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified.</param>
4272 </member>
4273 <member name="P:Newtonsoft.Json.Schema.JsonSchemaException.LineNumber">
4274 <summary>
4275 Gets the line number indicating where the error occurred.
4276 </summary>
4277 <value>The line number indicating where the error occurred.</value>
4278 </member>
4279 <member name="P:Newtonsoft.Json.Schema.JsonSchemaException.LinePosition">
4280 <summary>
4281 Gets the line position indicating where the error occurred.
4282 </summary>
4283 <value>The line position indicating where the error occurred.</value>
4284 </member>
4285 <member name="T:Newtonsoft.Json.Schema.JsonSchemaResolver">
4286 <summary>
4287 Resolves <see cref="T:Newtonsoft.Json.Schema.JsonSchema"/> from an id.
4288 </summary>
4289 </member>
4290 <member name="M:Newtonsoft.Json.Schema.JsonSchemaResolver.#ctor">
4291 <summary>
4292 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Schema.JsonSchemaResolver"/> class.
4293 </summary>
4294 </member>
4295 <member name="M:Newtonsoft.Json.Schema.JsonSchemaResolver.GetSchema(System.String)">
4296 <summary>
4297 Gets a <see cref="T:Newtonsoft.Json.Schema.JsonSchema"/> for the specified id.
4298 </summary>
4299 <param name="id">The id.</param>
4300 <returns>A <see cref="T:Newtonsoft.Json.Schema.JsonSchema"/> for the specified id.</returns>
4301 </member>
4302 <member name="P:Newtonsoft.Json.Schema.JsonSchemaResolver.LoadedSchemas">
4303 <summary>
4304 Gets or sets the loaded schemas.
4305 </summary>
4306 <value>The loaded schemas.</value>
4307 </member>
4308 <member name="T:Newtonsoft.Json.Schema.UndefinedSchemaIdHandling">
4309 <summary>
4310 Specifies undefined schema Id handling options for the <see cref="T:Newtonsoft.Json.Schema.JsonSchemaGenerator"/>.
4311 </summary>
4312 </member>
4313 <member name="F:Newtonsoft.Json.Schema.UndefinedSchemaIdHandling.None">
4314 <summary>
4315 Do not infer a schema Id.
4316 </summary>
4317 </member>
4318 <member name="F:Newtonsoft.Json.Schema.UndefinedSchemaIdHandling.UseTypeName">
4319 <summary>
4320 Use the .NET type name as the schema Id.
4321 </summary>
4322 </member>
4323 <member name="F:Newtonsoft.Json.Schema.UndefinedSchemaIdHandling.UseAssemblyQualifiedName">
4324 <summary>
4325 Use the assembly qualified .NET type name as the schema Id.
4326 </summary>
4327 </member>
4328 <member name="T:Newtonsoft.Json.Schema.ValidationEventArgs">
4329 <summary>
4330 Returns detailed information related to the <see cref="T:Newtonsoft.Json.Schema.ValidationEventHandler"/>.
4331 </summary>
4332 </member>
4333 <member name="P:Newtonsoft.Json.Schema.ValidationEventArgs.Exception">
4334 <summary>
4335 Gets the <see cref="T:Newtonsoft.Json.Schema.JsonSchemaException"/> associated with the validation event.
4336 </summary>
4337 <value>The JsonSchemaException associated with the validation event.</value>
4338 </member>
4339 <member name="P:Newtonsoft.Json.Schema.ValidationEventArgs.Message">
4340 <summary>
4341 Gets the text description corresponding to the validation event.
4342 </summary>
4343 <value>The text description.</value>
4344 </member>
4345 <member name="T:Newtonsoft.Json.Schema.ValidationEventHandler">
4346 <summary>
4347 Represents the callback method that will handle JSON schema validation events and the <see cref="T:Newtonsoft.Json.Schema.ValidationEventArgs"/>.
4348 </summary>
4349 </member>
4350 <member name="T:Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver">
4351 <summary>
4352 Resolves member mappings for a type, camel casing property names.
4353 </summary>
4354 </member>
4355 <member name="T:Newtonsoft.Json.Serialization.DefaultContractResolver">
4356 <summary>
4357 Used by <see cref="T:Newtonsoft.Json.JsonSerializer"/> to resolves a <see cref="T:Newtonsoft.Json.Serialization.JsonContract"/> for a given <see cref="T:System.Type"/>.
4358 </summary>
4359 </member>
4360 <member name="T:Newtonsoft.Json.Serialization.IContractResolver">
4361 <summary>
4362 Used by <see cref="T:Newtonsoft.Json.JsonSerializer"/> to resolves a <see cref="T:Newtonsoft.Json.Serialization.JsonContract"/> for a given <see cref="T:System.Type"/>.
4363 </summary>
4364 </member>
4365 <member name="M:Newtonsoft.Json.Serialization.IContractResolver.ResolveContract(System.Type)">
4366 <summary>
4367 Resolves the contract for a given type.
4368 </summary>
4369 <param name="type">The type to resolve a contract for.</param>
4370 <returns>The contract for a given type.</returns>
4371 </member>
4372 <member name="M:Newtonsoft.Json.Serialization.DefaultContractResolver.#ctor">
4373 <summary>
4374 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.DefaultContractResolver"/> class.
4375 </summary>
4376 </member>
4377 <member name="M:Newtonsoft.Json.Serialization.DefaultContractResolver.ResolveContract(System.Type)">
4378 <summary>
4379 Resolves the contract for a given type.
4380 </summary>
4381 <param name="type">The type to resolve a contract for.</param>
4382 <returns>The contract for a given type.</returns>
4383 </member>
4384 <member name="M:Newtonsoft.Json.Serialization.DefaultContractResolver.GetSerializableMembers(System.Type)">
4385 <summary>
4386 Gets the serializable members for the type.
4387 </summary>
4388 <param name="objectType">The type to get serializable members for.</param>
4389 <returns>The serializable members for the type.</returns>
4390 </member>
4391 <member name="M:Newtonsoft.Json.Serialization.DefaultContractResolver.CreateObjectContract(System.Type)">
4392 <summary>
4393 Creates a <see cref="T:Newtonsoft.Json.Serialization.JsonObjectContract"/> for the given type.
4394 </summary>
4395 <param name="objectType">Type of the object.</param>
4396 <returns>A <see cref="T:Newtonsoft.Json.Serialization.JsonObjectContract"/> for the given type.</returns>
4397 </member>
4398 <member name="M:Newtonsoft.Json.Serialization.DefaultContractResolver.ResolveContractConverter(System.Type)">
4399 <summary>
4400 Resolves the default <see cref="T:Newtonsoft.Json.JsonConverter"/> for the contract.
4401 </summary>
4402 <param name="objectType">Type of the object.</param>
4403 <returns></returns>
4404 </member>
4405 <member name="M:Newtonsoft.Json.Serialization.DefaultContractResolver.CreateDictionaryContract(System.Type)">
4406 <summary>
4407 Creates a <see cref="T:Newtonsoft.Json.Serialization.JsonDictionaryContract"/> for the given type.
4408 </summary>
4409 <param name="objectType">Type of the object.</param>
4410 <returns>A <see cref="T:Newtonsoft.Json.Serialization.JsonDictionaryContract"/> for the given type.</returns>
4411 </member>
4412 <member name="M:Newtonsoft.Json.Serialization.DefaultContractResolver.CreateArrayContract(System.Type)">
4413 <summary>
4414 Creates a <see cref="T:Newtonsoft.Json.Serialization.JsonArrayContract"/> for the given type.
4415 </summary>
4416 <param name="objectType">Type of the object.</param>
4417 <returns>A <see cref="T:Newtonsoft.Json.Serialization.JsonArrayContract"/> for the given type.</returns>
4418 </member>
4419 <member name="M:Newtonsoft.Json.Serialization.DefaultContractResolver.CreatePrimitiveContract(System.Type)">
4420 <summary>
4421 Creates a <see cref="T:Newtonsoft.Json.Serialization.JsonPrimitiveContract"/> for the given type.
4422 </summary>
4423 <param name="objectType">Type of the object.</param>
4424 <returns>A <see cref="T:Newtonsoft.Json.Serialization.JsonPrimitiveContract"/> for the given type.</returns>
4425 </member>
4426 <member name="M:Newtonsoft.Json.Serialization.DefaultContractResolver.CreateLinqContract(System.Type)">
4427 <summary>
4428 Creates a <see cref="T:Newtonsoft.Json.Serialization.JsonLinqContract"/> for the given type.
4429 </summary>
4430 <param name="objectType">Type of the object.</param>
4431 <returns>A <see cref="T:Newtonsoft.Json.Serialization.JsonLinqContract"/> for the given type.</returns>
4432 </member>
4433 <member name="M:Newtonsoft.Json.Serialization.DefaultContractResolver.CreateProperties(Newtonsoft.Json.Serialization.JsonObjectContract)">
4434 <summary>
4435 Creates properties for the given <see cref="T:Newtonsoft.Json.Serialization.JsonObjectContract"/>.
4436 </summary>
4437 <param name="contract">The contract to create properties for.</param>
4438 <returns>Properties for the given <see cref="T:Newtonsoft.Json.Serialization.JsonObjectContract"/>.</returns>
4439 </member>
4440 <member name="M:Newtonsoft.Json.Serialization.DefaultContractResolver.CreateMemberValueProvider(System.Reflection.MemberInfo)">
4441 <summary>
4442 Creates the <see cref="T:Newtonsoft.Json.Serialization.IValueProvider"/> used by the serializer to get and set values from a member.
4443 </summary>
4444 <param name="member">The member.</param>
4445 <returns>The <see cref="T:Newtonsoft.Json.Serialization.IValueProvider"/> used by the serializer to get and set values from a member.</returns>
4446 </member>
4447 <member name="M:Newtonsoft.Json.Serialization.DefaultContractResolver.CreateProperty(Newtonsoft.Json.Serialization.JsonObjectContract,System.Reflection.MemberInfo)">
4448 <summary>
4449 Creates a <see cref="T:Newtonsoft.Json.Serialization.JsonProperty"/> for the given <see cref="T:System.Reflection.MemberInfo"/>.
4450 </summary>
4451 <param name="contract">The member's declaring types <see cref="T:Newtonsoft.Json.Serialization.JsonObjectContract"/>.</param>
4452 <param name="member">The member to create a <see cref="T:Newtonsoft.Json.Serialization.JsonProperty"/> for.</param>
4453 <returns>A created <see cref="T:Newtonsoft.Json.Serialization.JsonProperty"/> for the given <see cref="T:System.Reflection.MemberInfo"/>.</returns>
4454 </member>
4455 <member name="M:Newtonsoft.Json.Serialization.DefaultContractResolver.ResolvePropertyName(System.String)">
4456 <summary>
4457 Resolves the name of the property.
4458 </summary>
4459 <param name="propertyName">Name of the property.</param>
4460 <returns>Name of the property.</returns>
4461 </member>
4462 <member name="P:Newtonsoft.Json.Serialization.DefaultContractResolver.DefaultMembersSearchFlags">
4463 <summary>
4464 Gets or sets the default members search flags.
4465 </summary>
4466 <value>The default members search flags.</value>
4467 </member>
4468 <member name="M:Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver.ResolvePropertyName(System.String)">
4469 <summary>
4470 Resolves the name of the property.
4471 </summary>
4472 <param name="propertyName">Name of the property.</param>
4473 <returns>The property name camel cased.</returns>
4474 </member>
4475 <member name="T:Newtonsoft.Json.Serialization.DefaultSerializationBinder">
4476 <summary>
4477 The default serialization binder used when resolving and loading classes from type names.
4478 </summary>
4479 </member>
4480 <member name="M:Newtonsoft.Json.Serialization.DefaultSerializationBinder.BindToType(System.String,System.String)">
4481 <summary>
4482 When overridden in a derived class, controls the binding of a serialized object to a type.
4483 </summary>
4484 <param name="assemblyName">Specifies the <see cref="T:System.Reflection.Assembly"/> name of the serialized object.</param>
4485 <param name="typeName">Specifies the <see cref="T:System.Type"/> name of the serialized object.</param>
4486 <returns>
4487 The type of the object the formatter creates a new instance of.
4488 </returns>
4489 </member>
4490 <member name="T:Newtonsoft.Json.Serialization.DynamicValueProvider">
4491 <summary>
4492 Get and set values for a <see cref="T:System.Reflection.MemberInfo"/> using dynamic methods.
4493 </summary>
4494 </member>
4495 <member name="T:Newtonsoft.Json.Serialization.IValueProvider">
4496 <summary>
4497 Provides methods to get and set values.
4498 </summary>
4499 </member>
4500 <member name="M:Newtonsoft.Json.Serialization.IValueProvider.SetValue(System.Object,System.Object)">
4501 <summary>
4502 Sets the value.
4503 </summary>
4504 <param name="target">The target to set the value on.</param>
4505 <param name="value">The value to set on the target.</param>
4506 </member>
4507 <member name="M:Newtonsoft.Json.Serialization.IValueProvider.GetValue(System.Object)">
4508 <summary>
4509 Gets the value.
4510 </summary>
4511 <param name="target">The target to get the value from.</param>
4512 <returns>The value.</returns>
4513 </member>
4514 <member name="M:Newtonsoft.Json.Serialization.DynamicValueProvider.#ctor(System.Reflection.MemberInfo)">
4515 <summary>
4516 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.DynamicValueProvider"/> class.
4517 </summary>
4518 <param name="memberInfo">The member info.</param>
4519 </member>
4520 <member name="M:Newtonsoft.Json.Serialization.DynamicValueProvider.SetValue(System.Object,System.Object)">
4521 <summary>
4522 Sets the value.
4523 </summary>
4524 <param name="target">The target to set the value on.</param>
4525 <param name="value">The value to set on the target.</param>
4526 </member>
4527 <member name="M:Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(System.Object)">
4528 <summary>
4529 Gets the value.
4530 </summary>
4531 <param name="target">The target to get the value from.</param>
4532 <returns>The value.</returns>
4533 </member>
4534 <member name="T:Newtonsoft.Json.Serialization.ErrorContext">
4535 <summary>
4536 Provides information surrounding an error.
4537 </summary>
4538 </member>
4539 <member name="P:Newtonsoft.Json.Serialization.ErrorContext.Error">
4540 <summary>
4541 Gets or sets the error.
4542 </summary>
4543 <value>The error.</value>
4544 </member>
4545 <member name="P:Newtonsoft.Json.Serialization.ErrorContext.OriginalObject">
4546 <summary>
4547 Gets the original object that caused the error.
4548 </summary>
4549 <value>The original object that caused the error.</value>
4550 </member>
4551 <member name="P:Newtonsoft.Json.Serialization.ErrorContext.Member">
4552 <summary>
4553 Gets the member that caused the error.
4554 </summary>
4555 <value>The member that caused the error.</value>
4556 </member>
4557 <member name="P:Newtonsoft.Json.Serialization.ErrorContext.Handled">
4558 <summary>
4559 Gets or sets a value indicating whether this <see cref="T:Newtonsoft.Json.Serialization.ErrorContext"/> is handled.
4560 </summary>
4561 <value><c>true</c> if handled; otherwise, <c>false</c>.</value>
4562 </member>
4563 <member name="T:Newtonsoft.Json.Serialization.ErrorEventArgs">
4564 <summary>
4565 Provides data for the Error event.
4566 </summary>
4567 </member>
4568 <member name="M:Newtonsoft.Json.Serialization.ErrorEventArgs.#ctor(System.Object,Newtonsoft.Json.Serialization.ErrorContext)">
4569 <summary>
4570 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.ErrorEventArgs"/> class.
4571 </summary>
4572 <param name="currentObject">The current object.</param>
4573 <param name="errorContext">The error context.</param>
4574 </member>
4575 <member name="P:Newtonsoft.Json.Serialization.ErrorEventArgs.CurrentObject">
4576 <summary>
4577 Gets the current object the error event is being raised against.
4578 </summary>
4579 <value>The current object the error event is being raised against.</value>
4580 </member>
4581 <member name="P:Newtonsoft.Json.Serialization.ErrorEventArgs.ErrorContext">
4582 <summary>
4583 Gets the error context.
4584 </summary>
4585 <value>The error context.</value>
4586 </member>
4587 <member name="T:Newtonsoft.Json.Serialization.JsonArrayContract">
4588 <summary>
4589 Contract details for a <see cref="T:System.Type"/> used by the <see cref="T:Newtonsoft.Json.JsonSerializer"/>.
4590 </summary>
4591 </member>
4592 <member name="T:Newtonsoft.Json.Serialization.JsonContract">
4593 <summary>
4594 Contract details for a <see cref="T:System.Type"/> used by the <see cref="T:Newtonsoft.Json.JsonSerializer"/>.
4595 </summary>
4596 </member>
4597 <member name="P:Newtonsoft.Json.Serialization.JsonContract.UnderlyingType">
4598 <summary>
4599 Gets the underlying type for the contract.
4600 </summary>
4601 <value>The underlying type for the contract.</value>
4602 </member>
4603 <member name="P:Newtonsoft.Json.Serialization.JsonContract.CreatedType">
4604 <summary>
4605 Gets or sets the type created during deserialization.
4606 </summary>
4607 <value>The type created during deserialization.</value>
4608 </member>
4609 <member name="P:Newtonsoft.Json.Serialization.JsonContract.IsReference">
4610 <summary>
4611 Gets or sets whether this type contract is serialized as a reference.
4612 </summary>
4613 <value>Whether this type contract is serialized as a reference.</value>
4614 </member>
4615 <member name="P:Newtonsoft.Json.Serialization.JsonContract.Converter">
4616 <summary>
4617 Gets or sets the default <see cref="T:Newtonsoft.Json.JsonConverter"/> for this contract.
4618 </summary>
4619 <value>The converter.</value>
4620 </member>
4621 <member name="P:Newtonsoft.Json.Serialization.JsonContract.OnDeserialized">
4622 <summary>
4623 Gets or sets the method called immediately after deserialization of the object.
4624 </summary>
4625 <value>The method called immediately after deserialization of the object.</value>
4626 </member>
4627 <member name="P:Newtonsoft.Json.Serialization.JsonContract.OnDeserializing">
4628 <summary>
4629 Gets or sets the method called during deserialization of the object.
4630 </summary>
4631 <value>The method called during deserialization of the object.</value>
4632 </member>
4633 <member name="P:Newtonsoft.Json.Serialization.JsonContract.OnSerialized">
4634 <summary>
4635 Gets or sets the method called after serialization of the object graph.
4636 </summary>
4637 <value>The method called after serialization of the object graph.</value>
4638 </member>
4639 <member name="P:Newtonsoft.Json.Serialization.JsonContract.OnSerializing">
4640 <summary>
4641 Gets or sets the method called before serialization of the object.
4642 </summary>
4643 <value>The method called before serialization of the object.</value>
4644 </member>
4645 <member name="P:Newtonsoft.Json.Serialization.JsonContract.DefaultCreator">
4646 <summary>
4647 Gets or sets the default creator.
4648 </summary>
4649 <value>The default creator.</value>
4650 </member>
4651 <member name="P:Newtonsoft.Json.Serialization.JsonContract.DefaultCreatorNonPublic">
4652 <summary>
4653 Gets or sets a value indicating whether [default creator non public].
4654 </summary>
4655 <value><c>true</c> if the default object creator is non-public; otherwise, <c>false</c>.</value>
4656 </member>
4657 <member name="P:Newtonsoft.Json.Serialization.JsonContract.OnError">
4658 <summary>
4659 Gets or sets the method called when an error is thrown during the serialization of the object.
4660 </summary>
4661 <value>The method called when an error is thrown during the serialization of the object.</value>
4662 </member>
4663 <member name="M:Newtonsoft.Json.Serialization.JsonArrayContract.#ctor(System.Type)">
4664 <summary>
4665 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.JsonArrayContract"/> class.
4666 </summary>
4667 <param name="underlyingType">The underlying type for the contract.</param>
4668 </member>
4669 <member name="T:Newtonsoft.Json.Serialization.JsonDictionaryContract">
4670 <summary>
4671 Contract details for a <see cref="T:System.Type"/> used by the <see cref="T:Newtonsoft.Json.JsonSerializer"/>.
4672 </summary>
4673 </member>
4674 <member name="M:Newtonsoft.Json.Serialization.JsonDictionaryContract.#ctor(System.Type)">
4675 <summary>
4676 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.JsonDictionaryContract"/> class.
4677 </summary>
4678 <param name="underlyingType">The underlying type for the contract.</param>
4679 </member>
4680 <member name="T:Newtonsoft.Json.Serialization.JsonLinqContract">
4681 <summary>
4682 Contract details for a <see cref="T:System.Type"/> used by the <see cref="T:Newtonsoft.Json.JsonSerializer"/>.
4683 </summary>
4684 </member>
4685 <member name="M:Newtonsoft.Json.Serialization.JsonLinqContract.#ctor(System.Type)">
4686 <summary>
4687 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.JsonLinqContract"/> class.
4688 </summary>
4689 <param name="underlyingType">The underlying type for the contract.</param>
4690 </member>
4691 <member name="T:Newtonsoft.Json.Serialization.JsonPrimitiveContract">
4692 <summary>
4693 Contract details for a <see cref="T:System.Type"/> used by the <see cref="T:Newtonsoft.Json.JsonSerializer"/>.
4694 </summary>
4695 </member>
4696 <member name="M:Newtonsoft.Json.Serialization.JsonPrimitiveContract.#ctor(System.Type)">
4697 <summary>
4698 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.JsonPrimitiveContract"/> class.
4699 </summary>
4700 <param name="underlyingType">The underlying type for the contract.</param>
4701 </member>
4702 <member name="T:Newtonsoft.Json.Serialization.JsonProperty">
4703 <summary>
4704 Maps a JSON property to a .NET member.
4705 </summary>
4706 </member>
4707 <member name="P:Newtonsoft.Json.Serialization.JsonProperty.PropertyName">
4708 <summary>
4709 Gets the name of the property.
4710 </summary>
4711 <value>The name of the property.</value>
4712 </member>
4713 <member name="P:Newtonsoft.Json.Serialization.JsonProperty.ValueProvider">
4714 <summary>
4715 Gets the <see cref="T:Newtonsoft.Json.Serialization.IValueProvider"/> that will get and set the <see cref="T:Newtonsoft.Json.Serialization.JsonProperty"/> during serialization.
4716 </summary>
4717 <value>The <see cref="T:Newtonsoft.Json.Serialization.IValueProvider"/> that will get and set the <see cref="T:Newtonsoft.Json.Serialization.JsonProperty"/> during serialization.</value>
4718 </member>
4719 <member name="P:Newtonsoft.Json.Serialization.JsonProperty.PropertyType">
4720 <summary>
4721 Gets or sets the type of the property.
4722 </summary>
4723 <value>The type of the property.</value>
4724 </member>
4725 <member name="P:Newtonsoft.Json.Serialization.JsonProperty.Converter">
4726 <summary>
4727 Gets or sets the <see cref="T:Newtonsoft.Json.JsonConverter"/> for the property.
4728 If set this converter takes presidence over the contract converter for the property type.
4729 </summary>
4730 <value>The converter.</value>
4731 </member>
4732 <member name="P:Newtonsoft.Json.Serialization.JsonProperty.Ignored">
4733 <summary>
4734 Gets a value indicating whether this <see cref="T:Newtonsoft.Json.Serialization.JsonProperty"/> is ignored.
4735 </summary>
4736 <value><c>true</c> if ignored; otherwise, <c>false</c>.</value>
4737 </member>
4738 <member name="P:Newtonsoft.Json.Serialization.JsonProperty.Readable">
4739 <summary>
4740 Gets a value indicating whether this <see cref="T:Newtonsoft.Json.Serialization.JsonProperty"/> is readable.
4741 </summary>
4742 <value><c>true</c> if readable; otherwise, <c>false</c>.</value>
4743 </member>
4744 <member name="P:Newtonsoft.Json.Serialization.JsonProperty.Writable">
4745 <summary>
4746 Gets a value indicating whether this <see cref="T:Newtonsoft.Json.Serialization.JsonProperty"/> is writable.
4747 </summary>
4748 <value><c>true</c> if writable; otherwise, <c>false</c>.</value>
4749 </member>
4750 <member name="P:Newtonsoft.Json.Serialization.JsonProperty.MemberConverter">
4751 <summary>
4752 Gets the member converter.
4753 </summary>
4754 <value>The member converter.</value>
4755 </member>
4756 <member name="P:Newtonsoft.Json.Serialization.JsonProperty.DefaultValue">
4757 <summary>
4758 Gets the default value.
4759 </summary>
4760 <value>The default value.</value>
4761 </member>
4762 <member name="P:Newtonsoft.Json.Serialization.JsonProperty.Required">
4763 <summary>
4764 Gets a value indicating whether this <see cref="T:Newtonsoft.Json.Serialization.JsonProperty"/> is required.
4765 </summary>
4766 <value>A value indicating whether this <see cref="T:Newtonsoft.Json.Serialization.JsonProperty"/> is required.</value>
4767 </member>
4768 <member name="P:Newtonsoft.Json.Serialization.JsonProperty.IsReference">
4769 <summary>
4770 Gets a value indicating whether this property preserves object references.
4771 </summary>
4772 <value>
4773 <c>true</c> if this instance is reference; otherwise, <c>false</c>.
4774 </value>
4775 </member>
4776 <member name="P:Newtonsoft.Json.Serialization.JsonProperty.NullValueHandling">
4777 <summary>
4778 Gets the property null value handling.
4779 </summary>
4780 <value>The null value handling.</value>
4781 </member>
4782 <member name="P:Newtonsoft.Json.Serialization.JsonProperty.DefaultValueHandling">
4783 <summary>
4784 Gets the property default value handling.
4785 </summary>
4786 <value>The default value handling.</value>
4787 </member>
4788 <member name="P:Newtonsoft.Json.Serialization.JsonProperty.ReferenceLoopHandling">
4789 <summary>
4790 Gets the property reference loop handling.
4791 </summary>
4792 <value>The reference loop handling.</value>
4793 </member>
4794 <member name="P:Newtonsoft.Json.Serialization.JsonProperty.ObjectCreationHandling">
4795 <summary>
4796 Gets the property object creation handling.
4797 </summary>
4798 <value>The object creation handling.</value>
4799 </member>
4800 <member name="T:Newtonsoft.Json.Serialization.JsonPropertyCollection">
4801 <summary>
4802 A collection of <see cref="T:Newtonsoft.Json.Serialization.JsonProperty"/> objects.
4803 </summary>
4804 </member>
4805 <member name="M:Newtonsoft.Json.Serialization.JsonPropertyCollection.#ctor(Newtonsoft.Json.Serialization.JsonObjectContract)">
4806 <summary>
4807 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.JsonPropertyCollection"/> class.
4808 </summary>
4809 <param name="contract">The contract.</param>
4810 </member>
4811 <member name="M:Newtonsoft.Json.Serialization.JsonPropertyCollection.GetKeyForItem(Newtonsoft.Json.Serialization.JsonProperty)">
4812 <summary>
4813 When implemented in a derived class, extracts the key from the specified element.
4814 </summary>
4815 <param name="item">The element from which to extract the key.</param>
4816 <returns>The key for the specified element.</returns>
4817 </member>
4818 <member name="M:Newtonsoft.Json.Serialization.JsonPropertyCollection.AddProperty(Newtonsoft.Json.Serialization.JsonProperty)">
4819 <summary>
4820 Adds a <see cref="T:Newtonsoft.Json.Serialization.JsonProperty"/> object.
4821 </summary>
4822 <param name="property">The property to add to the collection.</param>
4823 </member>
4824 <member name="M:Newtonsoft.Json.Serialization.JsonPropertyCollection.GetClosestMatchProperty(System.String)">
4825 <summary>
4826 Gets the closest matching <see cref="T:Newtonsoft.Json.Serialization.JsonProperty"/> object.
4827 First attempts to get an exact case match of propertyName and then
4828 a case insensitive match.
4829 </summary>
4830 <param name="propertyName">Name of the property.</param>
4831 <returns>A matching property if found.</returns>
4832 </member>
4833 <member name="M:Newtonsoft.Json.Serialization.JsonPropertyCollection.GetProperty(System.String,System.StringComparison)">
4834 <summary>
4835 Gets a property by property name.
4836 </summary>
4837 <param name="propertyName">The name of the property to get.</param>
4838 <param name="comparisonType">Type property name string comparison.</param>
4839 <returns>A matching property if found.</returns>
4840 </member>
4841 <member name="T:Newtonsoft.Json.MissingMemberHandling">
4842 <summary>
4843 Specifies missing member handling options for the <see cref="T:Newtonsoft.Json.JsonSerializer"/>.
4844 </summary>
4845 </member>
4846 <member name="F:Newtonsoft.Json.MissingMemberHandling.Ignore">
4847 <summary>
4848 Ignore a missing member and do not attempt to deserialize it.
4849 </summary>
4850 </member>
4851 <member name="F:Newtonsoft.Json.MissingMemberHandling.Error">
4852 <summary>
4853 Throw a <see cref="T:Newtonsoft.Json.JsonSerializationException"/> when a missing member is encountered during deserialization.
4854 </summary>
4855 </member>
4856 <member name="T:Newtonsoft.Json.NullValueHandling">
4857 <summary>
4858 Specifies null value handling options for the <see cref="T:Newtonsoft.Json.JsonSerializer"/>.
4859 </summary>
4860 </member>
4861 <member name="F:Newtonsoft.Json.NullValueHandling.Include">
4862 <summary>
4863 Include null values when serializing and deserializing objects.
4864 </summary>
4865 </member>
4866 <member name="F:Newtonsoft.Json.NullValueHandling.Ignore">
4867 <summary>
4868 Ignore null values when serializing and deserializing objects.
4869 </summary>
4870 </member>
4871 <member name="T:Newtonsoft.Json.ReferenceLoopHandling">
4872 <summary>
4873 Specifies reference loop handling options for the <see cref="T:Newtonsoft.Json.JsonSerializer"/>.
4874 </summary>
4875 </member>
4876 <member name="F:Newtonsoft.Json.ReferenceLoopHandling.Error">
4877 <summary>
4878 Throw a <see cref="T:Newtonsoft.Json.JsonSerializationException"/> when a loop is encountered.
4879 </summary>
4880 </member>
4881 <member name="F:Newtonsoft.Json.ReferenceLoopHandling.Ignore">
4882 <summary>
4883 Ignore loop references and do not serialize.
4884 </summary>
4885 </member>
4886 <member name="F:Newtonsoft.Json.ReferenceLoopHandling.Serialize">
4887 <summary>
4888 Serialize loop references.
4889 </summary>
4890 </member>
4891 <member name="T:Newtonsoft.Json.Schema.JsonSchema">
4892 <summary>
4893 An in-memory representation of a JSON Schema.
4894 </summary>
4895 </member>
4896 <member name="M:Newtonsoft.Json.Schema.JsonSchema.#ctor">
4897 <summary>
4898 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Schema.JsonSchema"/> class.
4899 </summary>
4900 </member>
4901 <member name="M:Newtonsoft.Json.Schema.JsonSchema.Read(Newtonsoft.Json.JsonReader)">
4902 <summary>
4903 Reads a <see cref="T:Newtonsoft.Json.Schema.JsonSchema"/> from the specified <see cref="T:Newtonsoft.Json.JsonReader"/>.
4904 </summary>
4905 <param name="reader">The <see cref="T:Newtonsoft.Json.JsonReader"/> containing the JSON Schema to read.</param>
4906 <returns>The <see cref="T:Newtonsoft.Json.Schema.JsonSchema"/> object representing the JSON Schema.</returns>
4907 </member>
4908 <member name="M:Newtonsoft.Json.Schema.JsonSchema.Read(Newtonsoft.Json.JsonReader,Newtonsoft.Json.Schema.JsonSchemaResolver)">
4909 <summary>
4910 Reads a <see cref="T:Newtonsoft.Json.Schema.JsonSchema"/> from the specified <see cref="T:Newtonsoft.Json.JsonReader"/>.
4911 </summary>
4912 <param name="reader">The <see cref="T:Newtonsoft.Json.JsonReader"/> containing the JSON Schema to read.</param>
4913 <param name="resolver">The <see cref="T:Newtonsoft.Json.Schema.JsonSchemaResolver"/> to use when resolving schema references.</param>
4914 <returns>The <see cref="T:Newtonsoft.Json.Schema.JsonSchema"/> object representing the JSON Schema.</returns>
4915 </member>
4916 <member name="M:Newtonsoft.Json.Schema.JsonSchema.Parse(System.String)">
4917 <summary>
4918 Load a <see cref="T:Newtonsoft.Json.Schema.JsonSchema"/> from a string that contains schema JSON.
4919 </summary>
4920 <param name="json">A <see cref="T:System.String"/> that contains JSON.</param>
4921 <returns>A <see cref="T:Newtonsoft.Json.Schema.JsonSchema"/> populated from the string that contains JSON.</returns>
4922 </member>
4923 <member name="M:Newtonsoft.Json.Schema.JsonSchema.Parse(System.String,Newtonsoft.Json.Schema.JsonSchemaResolver)">
4924 <summary>
4925 Parses the specified json.
4926 </summary>
4927 <param name="json">The json.</param>
4928 <param name="resolver">The resolver.</param>
4929 <returns>A <see cref="T:Newtonsoft.Json.Schema.JsonSchema"/> populated from the string that contains JSON.</returns>
4930 </member>
4931 <member name="M:Newtonsoft.Json.Schema.JsonSchema.WriteTo(Newtonsoft.Json.JsonWriter)">
4932 <summary>
4933 Writes this schema to a <see cref="T:Newtonsoft.Json.JsonWriter"/>.
4934 </summary>
4935 <param name="writer">A <see cref="T:Newtonsoft.Json.JsonWriter"/> into which this method will write.</param>
4936 </member>
4937 <member name="M:Newtonsoft.Json.Schema.JsonSchema.WriteTo(Newtonsoft.Json.JsonWriter,Newtonsoft.Json.Schema.JsonSchemaResolver)">
4938 <summary>
4939 Writes this schema to a <see cref="T:Newtonsoft.Json.JsonWriter"/> using the specified <see cref="T:Newtonsoft.Json.Schema.JsonSchemaResolver"/>.
4940 </summary>
4941 <param name="writer">A <see cref="T:Newtonsoft.Json.JsonWriter"/> into which this method will write.</param>
4942 <param name="resolver">The resolver used.</param>
4943 </member>
4944 <member name="M:Newtonsoft.Json.Schema.JsonSchema.ToString">
4945 <summary>
4946 Returns a <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
4947 </summary>
4948 <returns>
4949 A <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
4950 </returns>
4951 </member>
4952 <member name="P:Newtonsoft.Json.Schema.JsonSchema.Id">
4953 <summary>
4954 Gets or sets the id.
4955 </summary>
4956 </member>
4957 <member name="P:Newtonsoft.Json.Schema.JsonSchema.Title">
4958 <summary>
4959 Gets or sets the title.
4960 </summary>
4961 </member>
4962 <member name="P:Newtonsoft.Json.Schema.JsonSchema.Optional">
4963 <summary>
4964 Gets or sets whether the object is optional.
4965 </summary>
4966 </member>
4967 <member name="P:Newtonsoft.Json.Schema.JsonSchema.ReadOnly">
4968 <summary>
4969 Gets or sets whether the object is read only.
4970 </summary>
4971 </member>
4972 <member name="P:Newtonsoft.Json.Schema.JsonSchema.Hidden">
4973 <summary>
4974 Gets or sets whether the object is visible to users.
4975 </summary>
4976 </member>
4977 <member name="P:Newtonsoft.Json.Schema.JsonSchema.Transient">
4978 <summary>
4979 Gets or sets whether the object is transient.
4980 </summary>
4981 </member>
4982 <member name="P:Newtonsoft.Json.Schema.JsonSchema.Description">
4983 <summary>
4984 Gets or sets the description of the object.
4985 </summary>
4986 </member>
4987 <member name="P:Newtonsoft.Json.Schema.JsonSchema.Type">
4988 <summary>
4989 Gets or sets the types of values allowed by the object.
4990 </summary>
4991 <value>The type.</value>
4992 </member>
4993 <member name="P:Newtonsoft.Json.Schema.JsonSchema.Pattern">
4994 <summary>
4995 Gets or sets the pattern.
4996 </summary>
4997 <value>The pattern.</value>
4998 </member>
4999 <member name="P:Newtonsoft.Json.Schema.JsonSchema.MinimumLength">
5000 <summary>
5001 Gets or sets the minimum length.
5002 </summary>
5003 <value>The minimum length.</value>
5004 </member>
5005 <member name="P:Newtonsoft.Json.Schema.JsonSchema.MaximumLength">
5006 <summary>
5007 Gets or sets the maximum length.
5008 </summary>
5009 <value>The maximum length.</value>
5010 </member>
5011 <member name="P:Newtonsoft.Json.Schema.JsonSchema.MaximumDecimals">
5012 <summary>
5013 Gets or sets the maximum decimals.
5014 </summary>
5015 <value>The maximum decimals.</value>
5016 </member>
5017 <member name="P:Newtonsoft.Json.Schema.JsonSchema.Minimum">
5018 <summary>
5019 Gets or sets the minimum.
5020 </summary>
5021 <value>The minimum.</value>
5022 </member>
5023 <member name="P:Newtonsoft.Json.Schema.JsonSchema.Maximum">
5024 <summary>
5025 Gets or sets the maximum.
5026 </summary>
5027 <value>The maximum.</value>
5028 </member>
5029 <member name="P:Newtonsoft.Json.Schema.JsonSchema.MinimumItems">
5030 <summary>
5031 Gets or sets the minimum number of items.
5032 </summary>
5033 <value>The minimum number of items.</value>
5034 </member>
5035 <member name="P:Newtonsoft.Json.Schema.JsonSchema.MaximumItems">
5036 <summary>
5037 Gets or sets the maximum number of items.
5038 </summary>
5039 <value>The maximum number of items.</value>
5040 </member>
5041 <member name="P:Newtonsoft.Json.Schema.JsonSchema.Items">
5042 <summary>
5043 Gets or sets the <see cref="T:Newtonsoft.Json.Schema.JsonSchema"/> of items.
5044 </summary>
5045 <value>The <see cref="T:Newtonsoft.Json.Schema.JsonSchema"/> of items.</value>
5046 </member>
5047 <member name="P:Newtonsoft.Json.Schema.JsonSchema.Properties">
5048 <summary>
5049 Gets or sets the <see cref="T:Newtonsoft.Json.Schema.JsonSchema"/> of properties.
5050 </summary>
5051 <value>The <see cref="T:Newtonsoft.Json.Schema.JsonSchema"/> of properties.</value>
5052 </member>
5053 <member name="P:Newtonsoft.Json.Schema.JsonSchema.AdditionalProperties">
5054 <summary>
5055 Gets or sets the <see cref="T:Newtonsoft.Json.Schema.JsonSchema"/> of additional properties.
5056 </summary>
5057 <value>The <see cref="T:Newtonsoft.Json.Schema.JsonSchema"/> of additional properties.</value>
5058 </member>
5059 <member name="P:Newtonsoft.Json.Schema.JsonSchema.AllowAdditionalProperties">
5060 <summary>
5061 Gets or sets a value indicating whether additional properties are allowed.
5062 </summary>
5063 <value>
5064 <c>true</c> if additional properties are allowed; otherwise, <c>false</c>.
5065 </value>
5066 </member>
5067 <member name="P:Newtonsoft.Json.Schema.JsonSchema.Requires">
5068 <summary>
5069 Gets or sets the required property if this property is present.
5070 </summary>
5071 <value>The required property if this property is present.</value>
5072 </member>
5073 <member name="P:Newtonsoft.Json.Schema.JsonSchema.Identity">
5074 <summary>
5075 Gets or sets the identity.
5076 </summary>
5077 <value>The identity.</value>
5078 </member>
5079 <member name="P:Newtonsoft.Json.Schema.JsonSchema.Enum">
5080 <summary>
5081 Gets or sets the a collection of valid enum values allowed.
5082 </summary>
5083 <value>A collection of valid enum values allowed.</value>
5084 </member>
5085 <member name="P:Newtonsoft.Json.Schema.JsonSchema.Options">
5086 <summary>
5087 Gets or sets a collection of options.
5088 </summary>
5089 <value>A collection of options.</value>
5090 </member>
5091 <member name="P:Newtonsoft.Json.Schema.JsonSchema.Disallow">
5092 <summary>
5093 Gets or sets disallowed types.
5094 </summary>
5095 <value>The disallow types.</value>
5096 </member>
5097 <member name="P:Newtonsoft.Json.Schema.JsonSchema.Default">
5098 <summary>
5099 Gets or sets the default value.
5100 </summary>
5101 <value>The default value.</value>
5102 </member>
5103 <member name="P:Newtonsoft.Json.Schema.JsonSchema.Extends">
5104 <summary>
5105 Gets or sets the extend <see cref="T:Newtonsoft.Json.Schema.JsonSchema"/>.
5106 </summary>
5107 <value>The extended <see cref="T:Newtonsoft.Json.Schema.JsonSchema"/>.</value>
5108 </member>
5109 <member name="P:Newtonsoft.Json.Schema.JsonSchema.Format">
5110 <summary>
5111 Gets or sets the format.
5112 </summary>
5113 <value>The format.</value>
5114 </member>
5115 <member name="T:Newtonsoft.Json.Schema.JsonSchemaGenerator">
5116 <summary>
5117 Generates a <see cref="T:Newtonsoft.Json.Schema.JsonSchema"/> from a specified <see cref="T:System.Type"/>.
5118 </summary>
5119 </member>
5120 <member name="M:Newtonsoft.Json.Schema.JsonSchemaGenerator.Generate(System.Type)">
5121 <summary>
5122 Generate a <see cref="T:Newtonsoft.Json.Schema.JsonSchema"/> from the specified type.
5123 </summary>
5124 <param name="type">The type to generate a <see cref="T:Newtonsoft.Json.Schema.JsonSchema"/> from.</param>
5125 <returns>A <see cref="T:Newtonsoft.Json.Schema.JsonSchema"/> generated from the specified type.</returns>
5126 </member>
5127 <member name="M:Newtonsoft.Json.Schema.JsonSchemaGenerator.Generate(System.Type,Newtonsoft.Json.Schema.JsonSchemaResolver)">
5128 <summary>
5129 Generate a <see cref="T:Newtonsoft.Json.Schema.JsonSchema"/> from the specified type.
5130 </summary>
5131 <param name="type">The type to generate a <see cref="T:Newtonsoft.Json.Schema.JsonSchema"/> from.</param>
5132 <param name="resolver">The <see cref="T:Newtonsoft.Json.Schema.JsonSchemaResolver"/> used to resolve schema references.</param>
5133 <returns>A <see cref="T:Newtonsoft.Json.Schema.JsonSchema"/> generated from the specified type.</returns>
5134 </member>
5135 <member name="M:Newtonsoft.Json.Schema.JsonSchemaGenerator.Generate(System.Type,System.Boolean)">
5136 <summary>
5137 Generate a <see cref="T:Newtonsoft.Json.Schema.JsonSchema"/> from the specified type.
5138 </summary>
5139 <param name="type">The type to generate a <see cref="T:Newtonsoft.Json.Schema.JsonSchema"/> from.</param>
5140 <param name="rootSchemaNullable">Specify whether the generated root <see cref="T:Newtonsoft.Json.Schema.JsonSchema"/> will be nullable.</param>
5141 <returns>A <see cref="T:Newtonsoft.Json.Schema.JsonSchema"/> generated from the specified type.</returns>
5142 </member>
5143 <member name="M:Newtonsoft.Json.Schema.JsonSchemaGenerator.Generate(System.Type,Newtonsoft.Json.Schema.JsonSchemaResolver,System.Boolean)">
5144 <summary>
5145 Generate a <see cref="T:Newtonsoft.Json.Schema.JsonSchema"/> from the specified type.
5146 </summary>
5147 <param name="type">The type to generate a <see cref="T:Newtonsoft.Json.Schema.JsonSchema"/> from.</param>
5148 <param name="resolver">The <see cref="T:Newtonsoft.Json.Schema.JsonSchemaResolver"/> used to resolve schema references.</param>
5149 <param name="rootSchemaNullable">Specify whether the generated root <see cref="T:Newtonsoft.Json.Schema.JsonSchema"/> will be nullable.</param>
5150 <returns>A <see cref="T:Newtonsoft.Json.Schema.JsonSchema"/> generated from the specified type.</returns>
5151 </member>
5152 <member name="P:Newtonsoft.Json.Schema.JsonSchemaGenerator.UndefinedSchemaIdHandling">
5153 <summary>
5154 Gets or sets how undefined schemas are handled by the serializer.
5155 </summary>
5156 </member>
5157 <member name="P:Newtonsoft.Json.Schema.JsonSchemaGenerator.ContractResolver">
5158 <summary>
5159 Gets or sets the contract resolver.
5160 </summary>
5161 <value>The contract resolver.</value>
5162 </member>
5163 <member name="T:Newtonsoft.Json.Schema.JsonSchemaType">
5164 <summary>
5165 The value types allowed by the <see cref="T:Newtonsoft.Json.Schema.JsonSchema"/>.
5166 </summary>
5167 </member>
5168 <member name="F:Newtonsoft.Json.Schema.JsonSchemaType.None">
5169 <summary>
5170 No type specified.
5171 </summary>
5172 </member>
5173 <member name="F:Newtonsoft.Json.Schema.JsonSchemaType.String">
5174 <summary>
5175 String type.
5176 </summary>
5177 </member>
5178 <member name="F:Newtonsoft.Json.Schema.JsonSchemaType.Float">
5179 <summary>
5180 Float type.
5181 </summary>
5182 </member>
5183 <member name="F:Newtonsoft.Json.Schema.JsonSchemaType.Integer">
5184 <summary>
5185 Integer type.
5186 </summary>
5187 </member>
5188 <member name="F:Newtonsoft.Json.Schema.JsonSchemaType.Boolean">
5189 <summary>
5190 Boolean type.
5191 </summary>
5192 </member>
5193 <member name="F:Newtonsoft.Json.Schema.JsonSchemaType.Object">
5194 <summary>
5195 Object type.
5196 </summary>
5197 </member>
5198 <member name="F:Newtonsoft.Json.Schema.JsonSchemaType.Array">
5199 <summary>
5200 Array type.
5201 </summary>
5202 </member>
5203 <member name="F:Newtonsoft.Json.Schema.JsonSchemaType.Null">
5204 <summary>
5205 Null type.
5206 </summary>
5207 </member>
5208 <member name="F:Newtonsoft.Json.Schema.JsonSchemaType.Any">
5209 <summary>
5210 Any type.
5211 </summary>
5212 </member>
5213 <member name="T:Newtonsoft.Json.Serialization.JsonObjectContract">
5214 <summary>
5215 Contract details for a <see cref="T:System.Type"/> used by the <see cref="T:Newtonsoft.Json.JsonSerializer"/>.
5216 </summary>
5217 </member>
5218 <member name="M:Newtonsoft.Json.Serialization.JsonObjectContract.#ctor(System.Type)">
5219 <summary>
5220 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.JsonObjectContract"/> class.
5221 </summary>
5222 <param name="underlyingType">The underlying type for the contract.</param>
5223 </member>
5224 <member name="P:Newtonsoft.Json.Serialization.JsonObjectContract.MemberSerialization">
5225 <summary>
5226 Gets or sets the object member serialization.
5227 </summary>
5228 <value>The member object serialization.</value>
5229 </member>
5230 <member name="P:Newtonsoft.Json.Serialization.JsonObjectContract.Properties">
5231 <summary>
5232 Gets the object's properties.
5233 </summary>
5234 <value>The object's properties.</value>
5235 </member>
5236 <member name="P:Newtonsoft.Json.Serialization.JsonObjectContract.ParametrizedConstructor">
5237 <summary>
5238 Gets or sets the parametrized constructor used to create the object.
5239 </summary>
5240 <value>The parametrized constructor.</value>
5241 </member>
5242 <member name="T:Newtonsoft.Json.Serialization.OnErrorAttribute">
5243 <summary>
5244 When applied to a method, specifies that the method is called when an error occurs serializing an object.
5245 </summary>
5246 </member>
5247 <member name="T:Newtonsoft.Json.Serialization.ReflectionValueProvider">
5248 <summary>
5249 Get and set values for a <see cref="T:System.Reflection.MemberInfo"/> using reflection.
5250 </summary>
5251 </member>
5252 <member name="M:Newtonsoft.Json.Serialization.ReflectionValueProvider.#ctor(System.Reflection.MemberInfo)">
5253 <summary>
5254 Initializes a new instance of the <see cref="T:Newtonsoft.Json.Serialization.ReflectionValueProvider"/> class.
5255 </summary>
5256 <param name="memberInfo">The member info.</param>
5257 </member>
5258 <member name="M:Newtonsoft.Json.Serialization.ReflectionValueProvider.SetValue(System.Object,System.Object)">
5259 <summary>
5260 Sets the value.
5261 </summary>
5262 <param name="target">The target to set the value on.</param>
5263 <param name="value">The value to set on the target.</param>
5264 </member>
5265 <member name="M:Newtonsoft.Json.Serialization.ReflectionValueProvider.GetValue(System.Object)">
5266 <summary>
5267 Gets the value.
5268 </summary>
5269 <param name="target">The target to get the value from.</param>
5270 <returns>The value.</returns>
5271 </member>
5272 <member name="T:Newtonsoft.Json.TypeNameHandling">
5273 <summary>
5274 Specifies type name handling options for the <see cref="T:Newtonsoft.Json.JsonSerializer"/>.
5275 </summary>
5276 </member>
5277 <member name="F:Newtonsoft.Json.TypeNameHandling.None">
5278 <summary>
5279 Do not include the .NET type name when serializing types.
5280 </summary>
5281 </member>
5282 <member name="F:Newtonsoft.Json.TypeNameHandling.Objects">
5283 <summary>
5284 Include the .NET type name when serializing into a JSON object structure.
5285 </summary>
5286 </member>
5287 <member name="F:Newtonsoft.Json.TypeNameHandling.Arrays">
5288 <summary>
5289 Include the .NET type name when serializing into a JSON array structure.
5290 </summary>
5291 </member>
5292 <member name="F:Newtonsoft.Json.TypeNameHandling.All">
5293 <summary>
5294 Always include the .NET type name when serializing.
5295 </summary>
5296 </member>
5297 <member name="M:Newtonsoft.Json.Utilities.ConvertUtils.Convert``1(System.Object)">
5298 <summary>
5299 Converts the value to the specified type.
5300 </summary>
5301 <typeparam name="T">The type to convert the value to.</typeparam>
5302 <param name="initialValue">The value to convert.</param>
5303 <returns>The converted type.</returns>
5304 </member>
5305 <member name="M:Newtonsoft.Json.Utilities.ConvertUtils.Convert``1(System.Object,System.Globalization.CultureInfo)">
5306 <summary>
5307 Converts the value to the specified type.
5308 </summary>
5309 <typeparam name="T">The type to convert the value to.</typeparam>
5310 <param name="initialValue">The value to convert.</param>
5311 <param name="culture">The culture to use when converting.</param>
5312 <returns>The converted type.</returns>
5313 </member>
5314 <member name="M:Newtonsoft.Json.Utilities.ConvertUtils.Convert(System.Object,System.Globalization.CultureInfo,System.Type)">
5315 <summary>
5316 Converts the value to the specified type.
5317 </summary>
5318 <param name="initialValue">The value to convert.</param>
5319 <param name="culture">The culture to use when converting.</param>
5320 <param name="targetType">The type to convert the value to.</param>
5321 <returns>The converted type.</returns>
5322 </member>
5323 <member name="M:Newtonsoft.Json.Utilities.ConvertUtils.TryConvert``1(System.Object,``0@)">
5324 <summary>
5325 Converts the value to the specified type.
5326 </summary>
5327 <typeparam name="T">The type to convert the value to.</typeparam>
5328 <param name="initialValue">The value to convert.</param>
5329 <param name="convertedValue">The converted value if the conversion was successful or the default value of <c>T</c> if it failed.</param>
5330 <returns>
5331 <c>true</c> if <c>initialValue</c> was converted successfully; otherwise, <c>false</c>.
5332 </returns>
5333 </member>
5334 <member name="M:Newtonsoft.Json.Utilities.ConvertUtils.TryConvert``1(System.Object,System.Globalization.CultureInfo,``0@)">
5335 <summary>
5336 Converts the value to the specified type.
5337 </summary>
5338 <typeparam name="T">The type to convert the value to.</typeparam>
5339 <param name="initialValue">The value to convert.</param>
5340 <param name="culture">The culture to use when converting.</param>
5341 <param name="convertedValue">The converted value if the conversion was successful or the default value of <c>T</c> if it failed.</param>
5342 <returns>
5343 <c>true</c> if <c>initialValue</c> was converted successfully; otherwise, <c>false</c>.
5344 </returns>
5345 </member>
5346 <member name="M:Newtonsoft.Json.Utilities.ConvertUtils.TryConvert(System.Object,System.Globalization.CultureInfo,System.Type,System.Object@)">
5347 <summary>
5348 Converts the value to the specified type.
5349 </summary>
5350 <param name="initialValue">The value to convert.</param>
5351 <param name="culture">The culture to use when converting.</param>
5352 <param name="targetType">The type to convert the value to.</param>
5353 <param name="convertedValue">The converted value if the conversion was successful or the default value of <c>T</c> if it failed.</param>
5354 <returns>
5355 <c>true</c> if <c>initialValue</c> was converted successfully; otherwise, <c>false</c>.
5356 </returns>
5357 </member>
5358 <member name="M:Newtonsoft.Json.Utilities.ConvertUtils.ConvertOrCast``1(System.Object)">
5359 <summary>
5360 Converts the value to the specified type. If the value is unable to be converted, the
5361 value is checked whether it assignable to the specified type.
5362 </summary>
5363 <typeparam name="T">The type to convert or cast the value to.</typeparam>
5364 <param name="initialValue">The value to convert.</param>
5365 <returns>The converted type. If conversion was unsuccessful, the initial value is returned if assignable to the target type</returns>
5366 </member>
5367 <member name="M:Newtonsoft.Json.Utilities.ConvertUtils.ConvertOrCast``1(System.Object,System.Globalization.CultureInfo)">
5368 <summary>
5369 Converts the value to the specified type. If the value is unable to be converted, the
5370 value is checked whether it assignable to the specified type.
5371 </summary>
5372 <typeparam name="T">The type to convert or cast the value to.</typeparam>
5373 <param name="initialValue">The value to convert.</param>
5374 <param name="culture">The culture to use when converting.</param>
5375 <returns>The converted type. If conversion was unsuccessful, the initial value is returned if assignable to the target type</returns>
5376 </member>
5377 <member name="M:Newtonsoft.Json.Utilities.ConvertUtils.ConvertOrCast(System.Object,System.Globalization.CultureInfo,System.Type)">
5378 <summary>
5379 Converts the value to the specified type. If the value is unable to be converted, the
5380 value is checked whether it assignable to the specified type.
5381 </summary>
5382 <param name="initialValue">The value to convert.</param>
5383 <param name="culture">The culture to use when converting.</param>
5384 <param name="targetType">The type to convert or cast the value to.</param>
5385 <returns>
5386 The converted type. If conversion was unsuccessful, the initial value
5387 is returned if assignable to the target type.
5388 </returns>
5389 </member>
5390 <member name="M:Newtonsoft.Json.Utilities.ConvertUtils.TryConvertOrCast``1(System.Object,``0@)">
5391 <summary>
5392 Converts the value to the specified type. If the value is unable to be converted, the
5393 value is checked whether it assignable to the specified type.
5394 </summary>
5395 <typeparam name="T">The type to convert the value to.</typeparam>
5396 <param name="initialValue">The value to convert.</param>
5397 <param name="convertedValue">The converted value if the conversion was successful or the default value of <c>T</c> if it failed.</param>
5398 <returns>
5399 <c>true</c> if <c>initialValue</c> was converted successfully or is assignable; otherwise, <c>false</c>.
5400 </returns>
5401 </member>
5402 <member name="M:Newtonsoft.Json.Utilities.ConvertUtils.TryConvertOrCast``1(System.Object,System.Globalization.CultureInfo,``0@)">
5403 <summary>
5404 Converts the value to the specified type. If the value is unable to be converted, the
5405 value is checked whether it assignable to the specified type.
5406 </summary>
5407 <typeparam name="T">The type to convert the value to.</typeparam>
5408 <param name="initialValue">The value to convert.</param>
5409 <param name="culture">The culture to use when converting.</param>
5410 <param name="convertedValue">The converted value if the conversion was successful or the default value of <c>T</c> if it failed.</param>
5411 <returns>
5412 <c>true</c> if <c>initialValue</c> was converted successfully or is assignable; otherwise, <c>false</c>.
5413 </returns>
5414 </member>
5415 <member name="M:Newtonsoft.Json.Utilities.ConvertUtils.TryConvertOrCast(System.Object,System.Globalization.CultureInfo,System.Type,System.Object@)">
5416 <summary>
5417 Converts the value to the specified type. If the value is unable to be converted, the
5418 value is checked whether it assignable to the specified type.
5419 </summary>
5420 <param name="initialValue">The value to convert.</param>
5421 <param name="culture">The culture to use when converting.</param>
5422 <param name="targetType">The type to convert the value to.</param>
5423 <param name="convertedValue">The converted value if the conversion was successful or the default value of <c>T</c> if it failed.</param>
5424 <returns>
5425 <c>true</c> if <c>initialValue</c> was converted successfully or is assignable; otherwise, <c>false</c>.
5426 </returns>
5427 </member>
5428 <member name="M:Newtonsoft.Json.Utilities.EnumUtils.Parse``1(System.String)">
5429 <summary>
5430 Parses the specified enum member name, returning it's value.
5431 </summary>
5432 <param name="enumMemberName">Name of the enum member.</param>
5433 <returns></returns>
5434 </member>
5435 <member name="M:Newtonsoft.Json.Utilities.EnumUtils.Parse``1(System.String,System.Boolean)">
5436 <summary>
5437 Parses the specified enum member name, returning it's value.
5438 </summary>
5439 <param name="enumMemberName">Name of the enum member.</param>
5440 <param name="ignoreCase">If set to <c>true</c> ignore case.</param>
5441 <returns></returns>
5442 </member>
5443 <member name="M:Newtonsoft.Json.Utilities.EnumUtils.GetNamesAndValues``1">
5444 <summary>
5445 Gets a dictionary of the names and values of an Enum type.
5446 </summary>
5447 <returns></returns>
5448 </member>
5449 <member name="M:Newtonsoft.Json.Utilities.EnumUtils.GetNamesAndValues``2">
5450 <summary>
5451 Gets a dictionary of the names and values of an Enum type.
5452 </summary>
5453 <returns></returns>
5454 </member>
5455 <member name="M:Newtonsoft.Json.Utilities.EnumUtils.GetNamesAndValues``1(System.Type)">
5456 <summary>
5457 Gets a dictionary of the names and values of an Enum type.
5458 </summary>
5459 <param name="enumType">The enum type to get names and values for.</param>
5460 <returns></returns>
5461 </member>
5462 <member name="M:Newtonsoft.Json.Utilities.EnumUtils.GetMaximumValue``1(System.Type)">
5463 <summary>
5464 Gets the maximum valid value of an Enum type. Flags enums are ORed.
5465 </summary>
5466 <typeparam name="TEnumType">The type of the returned value. Must be assignable from the enum's underlying value type.</typeparam>
5467 <param name="enumType">The enum type to get the maximum value for.</param>
5468 <returns></returns>
5469 </member>
5470 <member name="T:Newtonsoft.Json.JsonToken">
5471 <summary>
5472 Specifies the type of Json token.
5473 </summary>
5474 </member>
5475 <member name="F:Newtonsoft.Json.JsonToken.None">
5476 <summary>
5477 This is returned by the <see cref="T:Newtonsoft.Json.JsonReader"/> if a <see cref="M:Newtonsoft.Json.JsonReader.Read"/> method has not been called.
5478 </summary>
5479 </member>
5480 <member name="F:Newtonsoft.Json.JsonToken.StartObject">
5481 <summary>
5482 An object start token.
5483 </summary>
5484 </member>
5485 <member name="F:Newtonsoft.Json.JsonToken.StartArray">
5486 <summary>
5487 An array start token.
5488 </summary>
5489 </member>
5490 <member name="F:Newtonsoft.Json.JsonToken.StartConstructor">
5491 <summary>
5492 A constructor start token.
5493 </summary>
5494 </member>
5495 <member name="F:Newtonsoft.Json.JsonToken.PropertyName">
5496 <summary>
5497 An object property name.
5498 </summary>
5499 </member>
5500 <member name="F:Newtonsoft.Json.JsonToken.Comment">
5501 <summary>
5502 A comment.
5503 </summary>
5504 </member>
5505 <member name="F:Newtonsoft.Json.JsonToken.Raw">
5506 <summary>
5507 Raw JSON.
5508 </summary>
5509 </member>
5510 <member name="F:Newtonsoft.Json.JsonToken.Integer">
5511 <summary>
5512 An interger.
5513 </summary>
5514 </member>
5515 <member name="F:Newtonsoft.Json.JsonToken.Float">
5516 <summary>
5517 A float.
5518 </summary>
5519 </member>
5520 <member name="F:Newtonsoft.Json.JsonToken.String">
5521 <summary>
5522 A string.
5523 </summary>
5524 </member>
5525 <member name="F:Newtonsoft.Json.JsonToken.Boolean">
5526 <summary>
5527 A boolean.
5528 </summary>
5529 </member>
5530 <member name="F:Newtonsoft.Json.JsonToken.Null">
5531 <summary>
5532 A null token.
5533 </summary>
5534 </member>
5535 <member name="F:Newtonsoft.Json.JsonToken.Undefined">
5536 <summary>
5537 An undefined token.
5538 </summary>
5539 </member>
5540 <member name="F:Newtonsoft.Json.JsonToken.EndObject">
5541 <summary>
5542 An object end token.
5543 </summary>
5544 </member>
5545 <member name="F:Newtonsoft.Json.JsonToken.EndArray">
5546 <summary>
5547 An array end token.
5548 </summary>
5549 </member>
5550 <member name="F:Newtonsoft.Json.JsonToken.EndConstructor">
5551 <summary>
5552 A constructor end token.
5553 </summary>
5554 </member>
5555 <member name="F:Newtonsoft.Json.JsonToken.Date">
5556 <summary>
5557 A Date.
5558 </summary>
5559 </member>
5560 <member name="F:Newtonsoft.Json.JsonToken.Bytes">
5561 <summary>
5562 Byte data.
5563 </summary>
5564 </member>
5565 <member name="T:Newtonsoft.Json.WriteState">
5566 <summary>
5567 Specifies the state of the <see cref="T:Newtonsoft.Json.JsonWriter"/>.
5568 </summary>
5569 </member>
5570 <member name="F:Newtonsoft.Json.WriteState.Error">
5571 <summary>
5572 An exception has been thrown, which has left the <see cref="T:Newtonsoft.Json.JsonWriter"/> in an invalid state.
5573 You may call the <see cref="M:Newtonsoft.Json.JsonWriter.Close"/> method to put the <see cref="T:Newtonsoft.Json.JsonWriter"/> in the <c>Closed</c> state.
5574 Any other <see cref="T:Newtonsoft.Json.JsonWriter"/> method calls results in an <see cref="T:System.InvalidOperationException"/> being thrown.
5575 </summary>
5576 </member>
5577 <member name="F:Newtonsoft.Json.WriteState.Closed">
5578 <summary>
5579 The <see cref="M:Newtonsoft.Json.JsonWriter.Close"/> method has been called.
5580 </summary>
5581 </member>
5582 <member name="F:Newtonsoft.Json.WriteState.Object">
5583 <summary>
5584 An object is being written.
5585 </summary>
5586 </member>
5587 <member name="F:Newtonsoft.Json.WriteState.Array">
5588 <summary>
5589 A array is being written.
5590 </summary>
5591 </member>
5592 <member name="F:Newtonsoft.Json.WriteState.Constructor">
5593 <summary>
5594 A constructor is being written.
5595 </summary>
5596 </member>
5597 <member name="F:Newtonsoft.Json.WriteState.Property">
5598 <summary>
5599 A property is being written.
5600 </summary>
5601 </member>
5602 <member name="F:Newtonsoft.Json.WriteState.Start">
5603 <summary>
5604 A write method has not been called.
5605 </summary>
5606 </member>
5607 <member name="T:Newtonsoft.Json.Formatting">
5608 <summary>
5609 Specifies formatting options for the <see cref="T:Newtonsoft.Json.JsonTextWriter"/>.
5610 </summary>
5611 </member>
5612 <member name="F:Newtonsoft.Json.Formatting.None">
5613 <summary>
5614 No special formatting is applied. This is the default.
5615 </summary>
5616 </member>
5617 <member name="F:Newtonsoft.Json.Formatting.Indented">
5618 <summary>
5619 Causes child objects to be indented according to the <see cref="P:Newtonsoft.Json.JsonTextWriter.Indentation"/> and <see cref="P:Newtonsoft.Json.JsonTextWriter.IndentChar"/> settings.
5620 </summary>
5621 </member>
5622 <member name="T:Newtonsoft.Json.Utilities.StringBuffer">
5623 <summary>
5624 Builds a string. Unlike StringBuilder this class lets you reuse it's internal buffer.
5625 </summary>
5626 </member>
5627 <member name="M:Newtonsoft.Json.Utilities.CollectionUtils.IsNullOrEmpty(System.Collections.ICollection)">
5628 <summary>
5629 Determines whether the collection is null or empty.
5630 </summary>
5631 <param name="collection">The collection.</param>
5632 <returns>
5633 <c>true</c> if the collection is null or empty; otherwise, <c>false</c>.
5634 </returns>
5635 </member>
5636 <member name="M:Newtonsoft.Json.Utilities.CollectionUtils.IsNullOrEmpty``1(System.Collections.Generic.ICollection{``0})">
5637 <summary>
5638 Determines whether the collection is null or empty.
5639 </summary>
5640 <param name="collection">The collection.</param>
5641 <returns>
5642 <c>true</c> if the collection is null or empty; otherwise, <c>false</c>.
5643 </returns>
5644 </member>
5645 <member name="M:Newtonsoft.Json.Utilities.CollectionUtils.IsNullOrEmptyOrDefault``1(System.Collections.Generic.IList{``0})">
5646 <summary>
5647 Determines whether the collection is null, empty or its contents are uninitialized values.
5648 </summary>
5649 <param name="list">The list.</param>
5650 <returns>
5651 <c>true</c> if the collection is null or empty or its contents are uninitialized values; otherwise, <c>false</c>.
5652 </returns>
5653 </member>
5654 <member name="M:Newtonsoft.Json.Utilities.CollectionUtils.Slice``1(System.Collections.Generic.IList{``0},System.Nullable{System.Int32},System.Nullable{System.Int32})">
5655 <summary>
5656 Makes a slice of the specified list in between the start and end indexes.
5657 </summary>
5658 <param name="list">The list.</param>
5659 <param name="start">The start index.</param>
5660 <param name="end">The end index.</param>
5661 <returns>A slice of the list.</returns>
5662 </member>
5663 <member name="M:Newtonsoft.Json.Utilities.CollectionUtils.Slice``1(System.Collections.Generic.IList{``0},System.Nullable{System.Int32},System.Nullable{System.Int32},System.Nullable{System.Int32})">
5664 <summary>
5665 Makes a slice of the specified list in between the start and end indexes,
5666 getting every so many items based upon the step.
5667 </summary>
5668 <param name="list">The list.</param>
5669 <param name="start">The start index.</param>
5670 <param name="end">The end index.</param>
5671 <param name="step">The step.</param>
5672 <returns>A slice of the list.</returns>
5673 </member>
5674 <member name="M:Newtonsoft.Json.Utilities.CollectionUtils.GroupBy``2(System.Collections.Generic.ICollection{``1},System.Func{``1,``0})">
5675 <summary>
5676 Group the collection using a function which returns the key.
5677 </summary>
5678 <param name="source">The source collection to group.</param>
5679 <param name="keySelector">The key selector.</param>
5680 <returns>A Dictionary with each key relating to a list of objects in a list grouped under it.</returns>
5681 </member>
5682 <member name="M:Newtonsoft.Json.Utilities.CollectionUtils.AddRange``1(System.Collections.Generic.IList{``0},System.Collections.Generic.IEnumerable{``0})">
5683 <summary>
5684 Adds the elements of the specified collection to the specified generic IList.
5685 </summary>
5686 <param name="initial">The list to add to.</param>
5687 <param name="collection">The collection of elements to add.</param>
5688 </member>
5689 <member name="M:Newtonsoft.Json.Utilities.ReflectionUtils.GetCollectionItemType(System.Type)">
5690 <summary>
5691 Gets the type of the typed collection's items.
5692 </summary>
5693 <param name="type">The type.</param>
5694 <returns>The type of the typed collection's items.</returns>
5695 </member>
5696 <member name="M:Newtonsoft.Json.Utilities.ReflectionUtils.ItemsUnitializedValue``1(System.Collections.Generic.IList{``0})">
5697 <summary>
5698 Tests whether the list's items are their unitialized value.
5699 </summary>
5700 <param name="list">The list.</param>
5701 <returns>Whether the list's items are their unitialized value</returns>
5702 </member>
5703 <member name="M:Newtonsoft.Json.Utilities.ReflectionUtils.GetMemberUnderlyingType(System.Reflection.MemberInfo)">
5704 <summary>
5705 Gets the member's underlying type.
5706 </summary>
5707 <param name="member">The member.</param>
5708 <returns>The underlying type of the member.</returns>
5709 </member>
5710 <member name="M:Newtonsoft.Json.Utilities.ReflectionUtils.IsIndexedProperty(System.Reflection.MemberInfo)">
5711 <summary>
5712 Determines whether the member is an indexed property.
5713 </summary>
5714 <param name="member">The member.</param>
5715 <returns>
5716 <c>true</c> if the member is an indexed property; otherwise, <c>false</c>.
5717 </returns>
5718 </member>
5719 <member name="M:Newtonsoft.Json.Utilities.ReflectionUtils.IsIndexedProperty(System.Reflection.PropertyInfo)">
5720 <summary>
5721 Determines whether the property is an indexed property.
5722 </summary>
5723 <param name="property">The property.</param>
5724 <returns>
5725 <c>true</c> if the property is an indexed property; otherwise, <c>false</c>.
5726 </returns>
5727 </member>
5728 <member name="M:Newtonsoft.Json.Utilities.ReflectionUtils.GetMemberValue(System.Reflection.MemberInfo,System.Object)">
5729 <summary>
5730 Gets the member's value on the object.
5731 </summary>
5732 <param name="member">The member.</param>
5733 <param name="target">The target object.</param>
5734 <returns>The member's value on the object.</returns>
5735 </member>
5736 <member name="M:Newtonsoft.Json.Utilities.ReflectionUtils.SetMemberValue(System.Reflection.MemberInfo,System.Object,System.Object)">
5737 <summary>
5738 Sets the member's value on the target object.
5739 </summary>
5740 <param name="member">The member.</param>
5741 <param name="target">The target.</param>
5742 <param name="value">The value.</param>
5743 </member>
5744 <member name="M:Newtonsoft.Json.Utilities.ReflectionUtils.CanReadMemberValue(System.Reflection.MemberInfo)">
5745 <summary>
5746 Determines whether the specified MemberInfo can be read.
5747 </summary>
5748 <param name="member">The MemberInfo to determine whether can be read.</param>
5749 <returns>
5750 <c>true</c> if the specified MemberInfo can be read; otherwise, <c>false</c>.
5751 </returns>
5752 </member>
5753 <member name="M:Newtonsoft.Json.Utilities.ReflectionUtils.CanSetMemberValue(System.Reflection.MemberInfo)">
5754 <summary>
5755 Determines whether the specified MemberInfo can be set.
5756 </summary>
5757 <param name="member">The MemberInfo to determine whether can be set.</param>
5758 <returns>
5759 <c>true</c> if the specified MemberInfo can be set; otherwise, <c>false</c>.
5760 </returns>
5761 </member>
5762 <member name="M:Newtonsoft.Json.Utilities.StringUtils.ContainsWhiteSpace(System.String)">
5763 <summary>
5764 Determines whether the string contains white space.
5765 </summary>
5766 <param name="s">The string to test for white space.</param>
5767 <returns>
5768 <c>true</c> if the string contains white space; otherwise, <c>false</c>.
5769 </returns>
5770 </member>
5771 <member name="M:Newtonsoft.Json.Utilities.StringUtils.IsWhiteSpace(System.String)">
5772 <summary>
5773 Determines whether the string is all white space. Empty string will return false.
5774 </summary>
5775 <param name="s">The string to test whether it is all white space.</param>
5776 <returns>
5777 <c>true</c> if the string is all white space; otherwise, <c>false</c>.
5778 </returns>
5779 </member>
5780 <member name="M:Newtonsoft.Json.Utilities.StringUtils.EnsureEndsWith(System.String,System.String)">
5781 <summary>
5782 Ensures the target string ends with the specified string.
5783 </summary>
5784 <param name="target">The target.</param>
5785 <param name="value">The value.</param>
5786 <returns>The target string with the value string at the end.</returns>
5787 </member>
5788 <member name="M:Newtonsoft.Json.Utilities.StringUtils.IfNotNullOrEmpty(System.String,System.Action{System.String})">
5789 <summary>
5790 Perform an action if the string is not null or empty.
5791 </summary>
5792 <param name="value">The value.</param>
5793 <param name="action">The action to perform.</param>
5794 </member>
5795 <member name="M:Newtonsoft.Json.Utilities.StringUtils.Indent(System.String,System.Int32)">
5796 <summary>
5797 Indents the specified string.
5798 </summary>
5799 <param name="s">The string to indent.</param>
5800 <param name="indentation">The number of characters to indent by.</param>
5801 <returns></returns>
5802 </member>
5803 <member name="M:Newtonsoft.Json.Utilities.StringUtils.Indent(System.String,System.Int32,System.Char)">
5804 <summary>
5805 Indents the specified string.
5806 </summary>
5807 <param name="s">The string to indent.</param>
5808 <param name="indentation">The number of characters to indent by.</param>
5809 <param name="indentChar">The indent character.</param>
5810 <returns></returns>
5811 </member>
5812 <member name="M:Newtonsoft.Json.Utilities.StringUtils.NumberLines(System.String)">
5813 <summary>
5814 Numbers the lines.
5815 </summary>
5816 <param name="s">The string to number.</param>
5817 <returns></returns>
5818 </member>
5819 <member name="M:Newtonsoft.Json.Utilities.StringUtils.NullEmptyString(System.String)">
5820 <summary>
5821 Nulls an empty string.
5822 </summary>
5823 <param name="s">The string.</param>
5824 <returns>Null if the string was null, otherwise the string unchanged.</returns>
5825 </member>
5826 </members>
5827</doc>
diff --git a/bin/Newtonsoft.Json.pdb b/bin/Newtonsoft.Json.pdb
deleted file mode 100644
index 892546a..0000000
--- a/bin/Newtonsoft.Json.pdb
+++ /dev/null
Binary files differ
diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example
index 9c68b65..0de4002 100644
--- a/bin/OpenSim.ini.example
+++ b/bin/OpenSim.ini.example
@@ -87,10 +87,18 @@
87 ;; from the selected region_info_source. 87 ;; from the selected region_info_source.
88 ; allow_regionless = false 88 ; allow_regionless = false
89 89
90 ;# {NonPhysicalPrimMin} {} {Minimum size of nonphysical prims?} {} 0.01
91 ;; Minimum size for non-physical prims. Affects resizing of existing prims. This can be overriden in the region config file (as NonphysicalPrimMin!).
92 ; NonphysicalPrimMin = 0.01
93
90 ;# {NonPhysicalPrimMax} {} {Maximum size of nonphysical prims?} {} 256 94 ;# {NonPhysicalPrimMax} {} {Maximum size of nonphysical prims?} {} 256
91 ;; Maximum size for non-physical prims. Affects resizing of existing prims. This can be overriden in the region config file (as NonphysicalPrimMax!). 95 ;; Maximum size for non-physical prims. Affects resizing of existing prims. This can be overriden in the region config file (as NonphysicalPrimMax!).
92 ; NonphysicalPrimMax = 256 96 ; NonphysicalPrimMax = 256
93 97
98 ;# {PhysicalPrimMin} {} {Minimum size of physical prims?} {} 10
99 ;; Maximum size where a prim can be physical. Affects resizing of existing prims. This can be overriden in the region config file.
100 ; PhysicalPrimMin = 0.01
101
94 ;# {PhysicalPrimMax} {} {Maximum size of physical prims?} {} 10 102 ;# {PhysicalPrimMax} {} {Maximum size of physical prims?} {} 10
95 ;; Maximum size where a prim can be physical. Affects resizing of existing prims. This can be overriden in the region config file. 103 ;; Maximum size where a prim can be physical. Affects resizing of existing prims. This can be overriden in the region config file.
96 ; PhysicalPrimMax = 10 104 ; PhysicalPrimMax = 10
@@ -99,6 +107,11 @@
99 ;; If a viewer attempts to rez a prim larger than the non-physical or physical prim max, clamp the dimensions to the appropriate maximum 107 ;; If a viewer attempts to rez a prim larger than the non-physical or physical prim max, clamp the dimensions to the appropriate maximum
100 ;; This can be overriden in the region config file. 108 ;; This can be overriden in the region config file.
101 ; ClampPrimSize = false 109 ; ClampPrimSize = false
110
111 ;# {LinksetPrims} {} {Max prims an object will hold?} {} 0
112 ;; Maximum number of prims allowable in a linkset. Affects creating new linksets. Ignored if less than or equal to zero.
113 ;; This can be overriden in the region config file.
114 ; LinksetPrims = 0
102 115
103 ;# {AllowScriptCrossing} {} {Allow scripts to cross into this region} {true false} true 116 ;# {AllowScriptCrossing} {} {Allow scripts to cross into this region} {true false} true
104 ;; Allow scripts to keep running when they cross region boundaries, rather than being restarted. State is reloaded on the destination region. 117 ;; Allow scripts to keep running when they cross region boundaries, rather than being restarted. State is reloaded on the destination region.
@@ -675,7 +688,9 @@
675 ;; Maximum number of events to queue for a script (excluding timers) 688 ;; Maximum number of events to queue for a script (excluding timers)
676 ; MaxScriptEventQueue = 300 689 ; MaxScriptEventQueue = 300
677 690
678 ;; Stack size per thread created 691 ;; Stack size per script engine thread in bytes.
692 ;; If you are experiencing StackOverflowExceptions you may want to increase this (e.g. double it).
693 ;; The trade-off may be increased memory usage by the script engine.
679 ; ThreadStackSize = 262144 694 ; ThreadStackSize = 262144
680 695
681 ;# {DeleteScriptsOnStartup} {} {Delete previously compiled script DLLs on startup?} (true false) true 696 ;# {DeleteScriptsOnStartup} {} {Delete previously compiled script DLLs on startup?} (true false) true
diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini
index 554aafa..1dc3f15 100644
--- a/bin/OpenSimDefaults.ini
+++ b/bin/OpenSimDefaults.ini
@@ -94,6 +94,10 @@
94 ; If a viewer attempts to rez a prim larger than the non-physical or physical prim max, clamp the dimensions to the appropriate maximum 94 ; If a viewer attempts to rez a prim larger than the non-physical or physical prim max, clamp the dimensions to the appropriate maximum
95 ; This can be overriden in the region config file. 95 ; This can be overriden in the region config file.
96 ClampPrimSize = false 96 ClampPrimSize = false
97
98 ; Maximum number of prims allowable in a linkset. Affects creating new linksets. Ignored if less than or equal to zero.
99 ; This can be overriden in the region config file.
100 LinksetPrims = 0
97 101
98 ; Allow scripts to keep running when they cross region boundaries, rather than being restarted. State is reloaded on the destination region. 102 ; Allow scripts to keep running when they cross region boundaries, rather than being restarted. State is reloaded on the destination region.
99 ; This only applies when crossing to a region running in a different simulator. 103 ; This only applies when crossing to a region running in a different simulator.
@@ -693,6 +697,24 @@
693 ;LevelUpload = 0 697 ;LevelUpload = 0
694 698
695 699
700[Textures]
701 ; If true, textures generated dynamically (i.e. through osSetDynamicTextureData() and similar OSSL functions) are reused where possible
702 ; Chiefly, reuse occurs if a texture has already been generated with identical data and settings, and that texture contains no dynamic components
703 ; (e.g. images pulled from an external HTTP address).
704 ; Reusing previously generated textures results in a much faster update on the viewer but may cause issues if the viewer didn't receive all resolutions of the texture.
705 ; Currently, it will also increase asset cache use since temporary dynamic textures are no longer deleted.
706 ; Hence, currently considered experimental.
707 ; Default is false.
708 ReuseDynamicTextures = false
709
710 ; If true, then textures generated dynamically that have a low data size relative to their pixel size are not reused
711 ; This is to workaround an apparent LL 3.3.4 and earlier viewer bug where such textures are not redisplayed properly when pulled from the viewer cache.
712 ; Only set this to true if you are sure that all the viewers using your simulator will not suffer from this problem.
713 ; This setting only has an affect is ReuseDynamicTextures = true
714 ; Default is false
715 ReuseDynamicLowDataTextures = false
716
717
696[ODEPhysicsSettings] 718[ODEPhysicsSettings]
697 ; ## 719 ; ##
698 ; ## Physics stats settings 720 ; ## Physics stats settings
@@ -931,6 +953,9 @@
931 953
932 ; level of detail for physical meshes. 32,16,8 or 4 with 32 being full detail 954 ; level of detail for physical meshes. 32,16,8 or 4 with 32 being full detail
933 MeshLevelOfDetail = 8 955 MeshLevelOfDetail = 8
956 ; if mesh size is > threshold meters, we need to add more detail because people will notice
957 MeshLevelOfDetailMegaPrimThreshold = 10
958 MeshLevelOfDetailMegaPrim = 16
934 ; number^2 non-physical level of detail of the sculpt texture. 32x32 - 1024 verticies 959 ; number^2 non-physical level of detail of the sculpt texture. 32x32 - 1024 verticies
935 SculptLevelOfDetail = 32 960 SculptLevelOfDetail = 32
936 961
diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example
index 3eecdd9..fad399d 100644
--- a/bin/Robust.HG.ini.example
+++ b/bin/Robust.HG.ini.example
@@ -104,6 +104,12 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003
104 ; Region_Welcome_Area = "DefaultRegion, FallbackRegion" 104 ; Region_Welcome_Area = "DefaultRegion, FallbackRegion"
105 ; (replace spaces with underscore) 105 ; (replace spaces with underscore)
106 106
107 ;; Allow Hyperlinks to be created at the console
108 HypergridLinker = true
109
110 Gatekeeper = "http://127.0.0.1:8002"
111
112
107; * This is the configuration for the freeswitch server in grid mode 113; * This is the configuration for the freeswitch server in grid mode
108[FreeswitchService] 114[FreeswitchService]
109 LocalServiceModule = "OpenSim.Services.FreeswitchService.dll:FreeswitchService" 115 LocalServiceModule = "OpenSim.Services.FreeswitchService.dll:FreeswitchService"
diff --git a/bin/config-include/FlotsamCache.ini.example b/bin/config-include/FlotsamCache.ini.example
index b9c6d84..ad74fc1 100644
--- a/bin/config-include/FlotsamCache.ini.example
+++ b/bin/config-include/FlotsamCache.ini.example
@@ -54,10 +54,3 @@
54 54
55 ; Warning level for cache directory size 55 ; Warning level for cache directory size
56 ;CacheWarnAt = 30000 56 ;CacheWarnAt = 30000
57
58 ; Perform a deep scan of all assets within all regions, looking for all assets
59 ; present or referenced. Mark all assets found that are already present in the
60 ; cache, and request all assets that are found that are not already cached (this
61 ; will cause those assets to be cached)
62 ;
63 DeepScanBeforePurge = true
diff --git a/bin/config-include/StandaloneHypergrid.ini b/bin/config-include/StandaloneHypergrid.ini
index 75c4788..b0ae351 100644
--- a/bin/config-include/StandaloneHypergrid.ini
+++ b/bin/config-include/StandaloneHypergrid.ini
@@ -36,8 +36,6 @@
36 SimulationServiceInConnector = true 36 SimulationServiceInConnector = true
37 MapImageServiceInConnector = true 37 MapImageServiceInConnector = true
38 38
39[Profile]
40 Module = "BasicProfileModule"
41 39
42[Messaging] 40[Messaging]
43 MessageTransferModule = HGMessageTransferModule 41 MessageTransferModule = HGMessageTransferModule
@@ -97,6 +95,10 @@
97 GridUserService = "OpenSim.Services.UserAccountService.dll:GridUserService" 95 GridUserService = "OpenSim.Services.UserAccountService.dll:GridUserService"
98 GridService = "OpenSim.Services.GridService.dll:GridService" 96 GridService = "OpenSim.Services.GridService.dll:GridService"
99 InventoryService = "OpenSim.Services.InventoryService.dll:XInventoryService" 97 InventoryService = "OpenSim.Services.InventoryService.dll:XInventoryService"
98 AvatarService = "OpenSim.Services.AvatarService.dll:AvatarService"
99
100 ;; This switch creates the minimum set of body parts and avatar entries for a viewer 2 to show a default "Ruth" avatar rather than a cloud.
101 CreateDefaultAvatarEntries = true
100 102
101[GridUserService] 103[GridUserService]
102 LocalServiceModule = "OpenSim.Services.UserAccountService.dll:GridUserService" 104 LocalServiceModule = "OpenSim.Services.UserAccountService.dll:GridUserService"
@@ -151,6 +153,7 @@
151 ; For the InventoryServiceInConnector 153 ; For the InventoryServiceInConnector
152 LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGInventoryService" 154 LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGInventoryService"
153 UserAccountsService = "OpenSim.Services.UserAccountService.dll:UserAccountService" 155 UserAccountsService = "OpenSim.Services.UserAccountService.dll:UserAccountService"
156 AvatarService = "OpenSim.Services.AvatarService.dll:AvatarService"
154 157
155;; The interface that local users get when they are in other grids 158;; The interface that local users get when they are in other grids
156;; This restricts/filters the asset operations from the outside 159;; This restricts/filters the asset operations from the outside
diff --git a/bin/config-include/storage/SQLiteStandalone.ini b/bin/config-include/storage/SQLiteStandalone.ini
index c1de71a..67d98ff 100644
--- a/bin/config-include/storage/SQLiteStandalone.ini
+++ b/bin/config-include/storage/SQLiteStandalone.ini
@@ -7,6 +7,16 @@
7[AssetService] 7[AssetService]
8 ConnectionString = "URI=file:Asset.db,version=3" 8 ConnectionString = "URI=file:Asset.db,version=3"
9 9
10; The HGAssetService section controls the connection given to the AssetService in a Hypergrid configuration.
11; This has to be separate from [AssetService] because the Hypergrid facing connector uses [HGAssetService] for its config data instead.
12; However, the internal asset service will still use the [AssetService] section.
13; Therefore, you will almost certainly want the ConnectionString in [HGAssetService] to be the same as in [AssetService]
14; so that they both access the same database.
15; This issue does not apply to normal MySQL/MSSQL configurations, since by default they use the settings in [DatabaseService] and
16; do not have separate connection strings for different services.
17[HGAssetService]
18 ConnectionString = "URI=file:Asset.db,version=3"
19
10[InventoryService] 20[InventoryService]
11 ;ConnectionString = "URI=file:inventory.db,version=3" 21 ;ConnectionString = "URI=file:inventory.db,version=3"
12 ; if you have a legacy inventory store use the connection string below 22 ; if you have a legacy inventory store use the connection string below
diff --git a/bin/lib32/BulletSim.dll b/bin/lib32/BulletSim.dll
index 0f2d522..3b35a98 100755
--- a/bin/lib32/BulletSim.dll
+++ b/bin/lib32/BulletSim.dll
Binary files differ
diff --git a/bin/lib32/libBulletSim.so b/bin/lib32/libBulletSim.so
index 783c9a2..65eba37 100755
--- a/bin/lib32/libBulletSim.so
+++ b/bin/lib32/libBulletSim.so
Binary files differ
diff --git a/bin/lib64/BulletSim.dll b/bin/lib64/BulletSim.dll
index c2a2bda..f01655b 100755
--- a/bin/lib64/BulletSim.dll
+++ b/bin/lib64/BulletSim.dll
Binary files differ
diff --git a/bin/lib64/libBulletSim.so b/bin/lib64/libBulletSim.so
index 74d4f98..5302e29 100755
--- a/bin/lib64/libBulletSim.so
+++ b/bin/lib64/libBulletSim.so
Binary files differ
diff --git a/prebuild.xml b/prebuild.xml
index 36eb27b..4e12fe9 100644
--- a/prebuild.xml
+++ b/prebuild.xml
@@ -1881,6 +1881,7 @@
1881 <Reference name="System.Core"/> 1881 <Reference name="System.Core"/>
1882 <Reference name="System.Xml"/> 1882 <Reference name="System.Xml"/>
1883 <Reference name="Mono.Addins" path="../../../bin/"/> 1883 <Reference name="Mono.Addins" path="../../../bin/"/>
1884 <Reference name="NDesk.Options" path="../../../bin/"/>
1884 <Reference name="OpenMetaverseTypes" path="../../../bin/"/> 1885 <Reference name="OpenMetaverseTypes" path="../../../bin/"/>
1885 <Reference name="OpenMetaverse.StructuredData" path="../../../bin/"/> 1886 <Reference name="OpenMetaverse.StructuredData" path="../../../bin/"/>
1886 <Reference name="OpenMetaverse" path="../../../bin/"/> 1887 <Reference name="OpenMetaverse" path="../../../bin/"/>
@@ -3091,6 +3092,7 @@
3091 <Match path="World/Media/Moap/Tests" pattern="*.cs" recurse="true"/> 3092 <Match path="World/Media/Moap/Tests" pattern="*.cs" recurse="true"/>
3092 <Match path="World/Serialiser/Tests" pattern="*.cs" recurse="true"/> 3093 <Match path="World/Serialiser/Tests" pattern="*.cs" recurse="true"/>
3093 <Match path="World/Terrain/Tests" pattern="*.cs" recurse="true"/> 3094 <Match path="World/Terrain/Tests" pattern="*.cs" recurse="true"/>
3095 <Match path="ServiceConnectorsOut/Asset/Tests" pattern="*.cs" recurse="true"/>
3094 <Match path="ServiceConnectorsOut/Grid/Tests" pattern="*.cs" recurse="true"/> 3096 <Match path="ServiceConnectorsOut/Grid/Tests" pattern="*.cs" recurse="true"/>
3095 <Match path="ServiceConnectorsOut/Presence/Tests" pattern="*.cs" recurse="true"/> 3097 <Match path="ServiceConnectorsOut/Presence/Tests" pattern="*.cs" recurse="true"/>
3096 </Files> 3098 </Files>
@@ -3371,7 +3373,48 @@
3371 </Files> 3373 </Files>
3372 </Project> 3374 </Project>
3373 3375
3374 <Project frameworkVersion="v3_5" name="OpenSim.Tests.Torture" path="OpenSim/Tests/Torture" type="Library"> 3376 <Project frameworkVersion="v3_5" name="OpenSim.Tests.Stress" path="OpenSim/Tests/Stress" type="Library">
3377 <Configuration name="Debug">
3378 <Options>
3379 <OutputPath>../../../bin/</OutputPath>
3380 </Options>
3381 </Configuration>
3382 <Configuration name="Release">
3383 <Options>
3384 <OutputPath>../../../bin/</OutputPath>
3385 </Options>
3386 </Configuration>
3387
3388 <ReferencePath>../../../bin/</ReferencePath>
3389 <Reference name="System"/>
3390 <Reference name="System.Core"/>
3391 <Reference name="System.Xml"/>
3392 <Reference name="System.Data"/>
3393 <Reference name="log4net" path="../../../bin/"/>
3394 <Reference name="Nini" path="../../../bin/"/>
3395 <Reference name="nunit.framework" path="../../../bin/"/>
3396 <Reference name="OpenMetaverse" path="../../../bin/"/>
3397 <Reference name="OpenMetaverseTypes" path="../../../bin/"/>
3398 <Reference name="OpenMetaverse.StructuredData" path="../../../bin/"/>
3399 <Reference name="XMLRPC" path="../../../bin/"/>
3400 <Reference name="OpenSim.Framework"/>
3401 <Reference name="OpenSim.Framework.Communications"/>
3402 <Reference name="OpenSim.Framework.Console"/>
3403 <Reference name="OpenSim.Framework.Servers.HttpServer"/>
3404 <Reference name="OpenSim.Region.CoreModules"/>
3405 <Reference name="OpenSim.Region.Framework"/>
3406 <Reference name="OpenSim.Region.OptionalModules"/>
3407 <Reference name="OpenSim.Region.ScriptEngine.Shared"/>
3408 <Reference name="OpenSim.Region.ScriptEngine.XEngine"/>
3409 <Reference name="OpenSim.Services.Interfaces"/>
3410 <Reference name="OpenSim.Services.AvatarService"/>
3411 <Reference name="OpenSim.Tests.Common"/>
3412 <Files>
3413 <Match pattern="*.cs" recurse="false"/>
3414 </Files>
3415 </Project>
3416
3417 <Project frameworkVersion="v3_5" name="OpenSim.Tests.Performance" path="OpenSim/Tests/Performance" type="Library">
3375 <Configuration name="Debug"> 3418 <Configuration name="Debug">
3376 <Options> 3419 <Options>
3377 <OutputPath>../../../bin/</OutputPath> 3420 <OutputPath>../../../bin/</OutputPath>